y-mxgraph 0.6.14 → 0.7.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 +195 -39
- package/README.zh-CN.md +195 -38
- package/iframe-bridge/provider.cjs +151 -63
- package/iframe-bridge/provider.cjs.map +1 -1
- package/iframe-bridge/provider.d.ts +1 -1
- package/iframe-bridge/provider.d.ts.map +1 -1
- package/iframe-bridge/provider.js +151 -63
- package/iframe-bridge/provider.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -116,53 +116,209 @@ pnpm --filter @y-mxgraph/ws-demo dev # Start client on port 5174
|
|
|
116
116
|
└─────────────┘
|
|
117
117
|
```
|
|
118
118
|
|
|
119
|
-
|
|
119
|
+
### Complete Example
|
|
120
|
+
|
|
121
|
+
#### 1. Parent Page (Server)
|
|
122
|
+
|
|
123
|
+
```html
|
|
124
|
+
<!DOCTYPE html>
|
|
125
|
+
<html>
|
|
126
|
+
<head>
|
|
127
|
+
<title>iframe Bridge Server</title>
|
|
128
|
+
</head>
|
|
129
|
+
<body>
|
|
130
|
+
<div>
|
|
131
|
+
<label>User: <input id="username" value="Alice" /></label>
|
|
132
|
+
<label>Color: <input id="usercolor" type="color" value="#2563eb" /></label>
|
|
133
|
+
<button id="undo-btn" disabled>Undo</button>
|
|
134
|
+
<button id="redo-btn" disabled>Redo</button>
|
|
135
|
+
<span id="status">Disconnected</span>
|
|
136
|
+
</div>
|
|
137
|
+
<iframe id="editor-iframe" src="./editor.html" style="width:100%;height:80vh;border:1px solid #ccc"></iframe>
|
|
138
|
+
|
|
139
|
+
<script type="module">
|
|
140
|
+
import * as Y from 'yjs';
|
|
141
|
+
import { WebrtcProvider } from 'y-webrtc';
|
|
142
|
+
import { LOCAL_ORIGIN } from 'y-mxgraph';
|
|
143
|
+
import { IFRAME_ORIGIN } from 'y-mxgraph/iframe-bridge';
|
|
144
|
+
import { createIframeBridgeServer } from 'y-mxgraph/iframe-bridge/server';
|
|
145
|
+
|
|
146
|
+
const iframe = document.getElementById('editor-iframe');
|
|
147
|
+
const statusEl = document.getElementById('status');
|
|
148
|
+
const undoBtn = document.getElementById('undo-btn');
|
|
149
|
+
const redoBtn = document.getElementById('redo-btn');
|
|
150
|
+
|
|
151
|
+
// 1. Create Y.Doc and network provider
|
|
152
|
+
const doc = new Y.Doc();
|
|
153
|
+
const provider = new WebrtcProvider('my-collab-room', doc);
|
|
154
|
+
const awareness = provider.awareness;
|
|
155
|
+
|
|
156
|
+
// 2. Set user info on parent awareness (synced to iframe automatically)
|
|
157
|
+
const updateUserInfo = () => {
|
|
158
|
+
awareness.setLocalState({
|
|
159
|
+
user: {
|
|
160
|
+
name: document.getElementById('username').value,
|
|
161
|
+
color: document.getElementById('usercolor').value,
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
};
|
|
165
|
+
updateUserInfo();
|
|
166
|
+
document.getElementById('username').onchange = updateUserInfo;
|
|
167
|
+
document.getElementById('usercolor').onchange = updateUserInfo;
|
|
168
|
+
|
|
169
|
+
// 3. Create UndoManager with cross-iframe support
|
|
170
|
+
const undoManager = new Y.UndoManager(doc, {
|
|
171
|
+
trackedOrigins: new Set([LOCAL_ORIGIN, IFRAME_ORIGIN]),
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
// 4. Create bridge server
|
|
175
|
+
const bridge = createIframeBridgeServer(iframe, doc, awareness, {
|
|
176
|
+
undoManager,
|
|
177
|
+
debug: true, // Enable console logging
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
// 5. Monitor connection status
|
|
181
|
+
bridge.onConnect(() => {
|
|
182
|
+
statusEl.textContent = 'Connected';
|
|
183
|
+
statusEl.style.color = 'green';
|
|
184
|
+
});
|
|
185
|
+
bridge.onDisconnect(() => {
|
|
186
|
+
statusEl.textContent = 'Disconnected';
|
|
187
|
+
statusEl.style.color = 'red';
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
// 6. Monitor peer count
|
|
191
|
+
awareness.on('update', () => {
|
|
192
|
+
const count = awareness.getStates().size;
|
|
193
|
+
statusEl.textContent = `Connected (${count} peers)`;
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
// 7. Undo/Redo from parent page
|
|
197
|
+
const updateUndoRedoButtons = () => {
|
|
198
|
+
undoBtn.disabled = !undoManager.canUndo();
|
|
199
|
+
redoBtn.disabled = !undoManager.canRedo();
|
|
200
|
+
};
|
|
201
|
+
undoManager.on('stack-item-added', updateUndoRedoButtons);
|
|
202
|
+
undoManager.on('stack-item-popped', updateUndoRedoButtons);
|
|
203
|
+
undoManager.on('stack-cleared', updateUndoRedoButtons);
|
|
204
|
+
|
|
205
|
+
undoBtn.onclick = () => undoManager.canUndo() && undoManager.undo();
|
|
206
|
+
redoBtn.onclick = () => undoManager.canRedo() && undoManager.redo();
|
|
207
|
+
|
|
208
|
+
// 8. Cleanup on page unload
|
|
209
|
+
window.addEventListener('beforeunload', () => {
|
|
210
|
+
bridge.destroy();
|
|
211
|
+
provider.disconnect();
|
|
212
|
+
provider.destroy();
|
|
213
|
+
undoManager.destroy();
|
|
214
|
+
});
|
|
215
|
+
</script>
|
|
216
|
+
</body>
|
|
217
|
+
</html>
|
|
218
|
+
```
|
|
120
219
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
220
|
+
#### 2. Iframe Child (Provider)
|
|
221
|
+
|
|
222
|
+
```html
|
|
223
|
+
<!DOCTYPE html>
|
|
224
|
+
<html>
|
|
225
|
+
<head>
|
|
226
|
+
<title>draw.io Editor</title>
|
|
227
|
+
</head>
|
|
228
|
+
<body>
|
|
229
|
+
<div id="drawio-container"></div>
|
|
230
|
+
|
|
231
|
+
<script type="module">
|
|
232
|
+
import * as Y from 'yjs';
|
|
233
|
+
import { Binding, LOCAL_ORIGIN } from 'y-mxgraph';
|
|
234
|
+
import { createIframeBridgeProvider } from 'y-mxgraph/iframe-bridge/provider';
|
|
235
|
+
|
|
236
|
+
// 1. Create local Y.Doc (no network provider needed)
|
|
237
|
+
const doc = new Y.Doc();
|
|
238
|
+
|
|
239
|
+
// 2. Create iframe bridge provider
|
|
240
|
+
// - No external awareness needed, provider creates its own AwarenessLike
|
|
241
|
+
// - Automatically syncs with parent via postMessage
|
|
242
|
+
const bridge = createIframeBridgeProvider(doc, {
|
|
243
|
+
debug: true, // Enable console logging
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
// 3. Monitor connection to parent
|
|
247
|
+
bridge.onConnect(() => {
|
|
248
|
+
console.log('[iframe] Connected to parent bridge');
|
|
249
|
+
});
|
|
250
|
+
bridge.onDisconnect(() => {
|
|
251
|
+
console.log('[iframe] Disconnected from parent bridge');
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
// 4. Initialize draw.io
|
|
255
|
+
App.main((app) => {
|
|
256
|
+
const file = app.currentFile;
|
|
257
|
+
|
|
258
|
+
// 5. Create binding with bridge awareness
|
|
259
|
+
const binding = new Binding(file, {
|
|
260
|
+
doc,
|
|
261
|
+
awareness: bridge.awareness,
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
// 6. Takeover draw.io's undo manager to route through parent
|
|
265
|
+
const cleanupUndo = bridge.takeoverUndoManager(file);
|
|
266
|
+
|
|
267
|
+
// 7. Cleanup on page unload
|
|
268
|
+
window.addEventListener('beforeunload', () => {
|
|
269
|
+
binding.destroy();
|
|
270
|
+
cleanupUndo();
|
|
271
|
+
bridge.destroy();
|
|
272
|
+
});
|
|
273
|
+
});
|
|
274
|
+
</script>
|
|
275
|
+
</body>
|
|
276
|
+
</html>
|
|
277
|
+
```
|
|
128
278
|
|
|
129
|
-
|
|
130
|
-
const provider = new WebrtcProvider(roomName, doc, { signaling });
|
|
131
|
-
const awareness = provider.awareness;
|
|
279
|
+
### Key Features
|
|
132
280
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
281
|
+
- **Automatic sync**: Y.Doc and Awareness state automatically sync between parent and iframe
|
|
282
|
+
- **User info propagation**: Set user info on parent awareness, iframe receives it automatically
|
|
283
|
+
- **Cross-iframe undo/redo**: UndoManager in parent page controls undo/redo for all iframes
|
|
284
|
+
- **Connection lifecycle**: `onConnect`/`onDisconnect` callbacks for status monitoring
|
|
285
|
+
- **Debug mode**: Set `debug: true` to log all postMessage traffic
|
|
137
286
|
|
|
138
|
-
|
|
139
|
-
// If the UndoManager implementation supports addTrackedOrigin/removeTrackedOrigin,
|
|
140
|
-
// the bridge will automatically add/remove IFRAME_ORIGIN for you.
|
|
141
|
-
// If not, keep IFRAME_ORIGIN in trackedOrigins manually.
|
|
142
|
-
const bridge = createIframeBridgeServer(iframeElement, doc, awareness, { undoManager });
|
|
287
|
+
### API Reference
|
|
143
288
|
|
|
144
|
-
|
|
145
|
-
document.getElementById('undo-btn')!.onclick = () => {
|
|
146
|
-
if (undoManager.canUndo()) undoManager.undo();
|
|
147
|
-
};
|
|
289
|
+
#### `createIframeBridgeServer(iframe, ydoc, awareness, options?)`
|
|
148
290
|
|
|
149
|
-
|
|
150
|
-
import * as Y from 'yjs';
|
|
151
|
-
import { Awareness } from 'y-protocols/awareness';
|
|
152
|
-
import { Binding } from 'y-mxgraph';
|
|
153
|
-
import { createIframeBridgeProvider } from 'y-mxgraph/iframe-bridge/provider';
|
|
291
|
+
Creates a bridge server on the parent page.
|
|
154
292
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
293
|
+
**Parameters:**
|
|
294
|
+
- `iframe: HTMLIFrameElement` - Target iframe element
|
|
295
|
+
- `ydoc: Y.Doc` - Shared Yjs document
|
|
296
|
+
- `awareness: Awareness` - Awareness instance (usually from provider.awareness)
|
|
297
|
+
- `options.undoManager?: Y.UndoManager` - Optional UndoManager for cross-iframe undo
|
|
298
|
+
- `options.debug?: boolean` - Enable debug logging (default: false)
|
|
158
299
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
300
|
+
**Returns:** `IframeBridgeServer` with:
|
|
301
|
+
- `connected: boolean` - Current connection status
|
|
302
|
+
- `onConnect(fn)` / `onDisconnect(fn)` - Connection lifecycle callbacks
|
|
303
|
+
- `destroy()` - Cleanup all listeners
|
|
304
|
+
|
|
305
|
+
#### `createIframeBridgeProvider(ydoc, options?)`
|
|
306
|
+
|
|
307
|
+
Creates a bridge provider inside the iframe.
|
|
308
|
+
|
|
309
|
+
**Parameters:**
|
|
310
|
+
- `ydoc: Y.Doc` - Local Yjs document
|
|
311
|
+
- `options.awareness?: Awareness` - Optional external Awareness (creates internal AwarenessLike if omitted)
|
|
312
|
+
- `options.debug?: boolean` - Enable debug logging (default: false)
|
|
313
|
+
|
|
314
|
+
**Returns:** `IframeBridgeProvider` with:
|
|
315
|
+
- `connected: boolean` - Connection status to parent
|
|
316
|
+
- `awareness: Awareness` - Awareness instance (use for Binding)
|
|
317
|
+
- `serverClientId: number | null` - Parent's client ID
|
|
318
|
+
- `setLocalFields(fields)` - Update local user fields
|
|
319
|
+
- `takeoverUndoManager(file)` - Route draw.io undo/redo through parent
|
|
320
|
+
- `onConnect(fn)` / `onDisconnect(fn)` - Connection lifecycle callbacks
|
|
321
|
+
- `destroy()` - Cleanup all listeners
|
|
166
322
|
|
|
167
323
|
See [iframe Bridge documentation](https://mizuka-wu.github.io/y-mxgraph/en/guide/iframe-bridge) for details.
|
|
168
324
|
|
package/README.zh-CN.md
CHANGED
|
@@ -78,52 +78,209 @@ App.main((app) => {
|
|
|
78
78
|
└─────────────┘
|
|
79
79
|
```
|
|
80
80
|
|
|
81
|
-
|
|
81
|
+
### 完整示例
|
|
82
|
+
|
|
83
|
+
#### 1. 父页面(Server)
|
|
84
|
+
|
|
85
|
+
```html
|
|
86
|
+
<!DOCTYPE html>
|
|
87
|
+
<html>
|
|
88
|
+
<head>
|
|
89
|
+
<title>iframe Bridge Server</title>
|
|
90
|
+
</head>
|
|
91
|
+
<body>
|
|
92
|
+
<div>
|
|
93
|
+
<label>用户名: <input id="username" value="Alice" /></label>
|
|
94
|
+
<label>颜色: <input id="usercolor" type="color" value="#2563eb" /></label>
|
|
95
|
+
<button id="undo-btn" disabled>撤销</button>
|
|
96
|
+
<button id="redo-btn" disabled>重做</button>
|
|
97
|
+
<span id="status">未连接</span>
|
|
98
|
+
</div>
|
|
99
|
+
<iframe id="editor-iframe" src="./editor.html" style="width:100%;height:80vh;border:1px solid #ccc"></iframe>
|
|
100
|
+
|
|
101
|
+
<script type="module">
|
|
102
|
+
import * as Y from 'yjs';
|
|
103
|
+
import { WebrtcProvider } from 'y-webrtc';
|
|
104
|
+
import { LOCAL_ORIGIN } from 'y-mxgraph';
|
|
105
|
+
import { IFRAME_ORIGIN } from 'y-mxgraph/iframe-bridge';
|
|
106
|
+
import { createIframeBridgeServer } from 'y-mxgraph/iframe-bridge/server';
|
|
107
|
+
|
|
108
|
+
const iframe = document.getElementById('editor-iframe');
|
|
109
|
+
const statusEl = document.getElementById('status');
|
|
110
|
+
const undoBtn = document.getElementById('undo-btn');
|
|
111
|
+
const redoBtn = document.getElementById('redo-btn');
|
|
112
|
+
|
|
113
|
+
// 1. 创建 Y.Doc 和网络 Provider
|
|
114
|
+
const doc = new Y.Doc();
|
|
115
|
+
const provider = new WebrtcProvider('my-collab-room', doc);
|
|
116
|
+
const awareness = provider.awareness;
|
|
117
|
+
|
|
118
|
+
// 2. 在父容器 awareness 上设置用户信息(自动同步到 iframe)
|
|
119
|
+
const updateUserInfo = () => {
|
|
120
|
+
awareness.setLocalState({
|
|
121
|
+
user: {
|
|
122
|
+
name: document.getElementById('username').value,
|
|
123
|
+
color: document.getElementById('usercolor').value,
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
};
|
|
127
|
+
updateUserInfo();
|
|
128
|
+
document.getElementById('username').onchange = updateUserInfo;
|
|
129
|
+
document.getElementById('usercolor').onchange = updateUserInfo;
|
|
130
|
+
|
|
131
|
+
// 3. 创建支持跨 iframe 的 UndoManager
|
|
132
|
+
const undoManager = new Y.UndoManager(doc, {
|
|
133
|
+
trackedOrigins: new Set([LOCAL_ORIGIN, IFRAME_ORIGIN]),
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
// 4. 创建 bridge server
|
|
137
|
+
const bridge = createIframeBridgeServer(iframe, doc, awareness, {
|
|
138
|
+
undoManager,
|
|
139
|
+
debug: true, // 启用控制台日志
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
// 5. 监听连接状态
|
|
143
|
+
bridge.onConnect(() => {
|
|
144
|
+
statusEl.textContent = '已连接';
|
|
145
|
+
statusEl.style.color = 'green';
|
|
146
|
+
});
|
|
147
|
+
bridge.onDisconnect(() => {
|
|
148
|
+
statusEl.textContent = '未连接';
|
|
149
|
+
statusEl.style.color = 'red';
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
// 6. 监听在线人数
|
|
153
|
+
awareness.on('update', () => {
|
|
154
|
+
const count = awareness.getStates().size;
|
|
155
|
+
statusEl.textContent = `已连接 (${count} 人在线)`;
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
// 7. 从父页面执行撤销/重做
|
|
159
|
+
const updateUndoRedoButtons = () => {
|
|
160
|
+
undoBtn.disabled = !undoManager.canUndo();
|
|
161
|
+
redoBtn.disabled = !undoManager.canRedo();
|
|
162
|
+
};
|
|
163
|
+
undoManager.on('stack-item-added', updateUndoRedoButtons);
|
|
164
|
+
undoManager.on('stack-item-popped', updateUndoRedoButtons);
|
|
165
|
+
undoManager.on('stack-cleared', updateUndoRedoButtons);
|
|
166
|
+
|
|
167
|
+
undoBtn.onclick = () => undoManager.canUndo() && undoManager.undo();
|
|
168
|
+
redoBtn.onclick = () => undoManager.canRedo() && undoManager.redo();
|
|
169
|
+
|
|
170
|
+
// 8. 页面卸载时清理
|
|
171
|
+
window.addEventListener('beforeunload', () => {
|
|
172
|
+
bridge.destroy();
|
|
173
|
+
provider.disconnect();
|
|
174
|
+
provider.destroy();
|
|
175
|
+
undoManager.destroy();
|
|
176
|
+
});
|
|
177
|
+
</script>
|
|
178
|
+
</body>
|
|
179
|
+
</html>
|
|
180
|
+
```
|
|
82
181
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
182
|
+
#### 2. iframe 子页面(Provider)
|
|
183
|
+
|
|
184
|
+
```html
|
|
185
|
+
<!DOCTYPE html>
|
|
186
|
+
<html>
|
|
187
|
+
<head>
|
|
188
|
+
<title>draw.io 编辑器</title>
|
|
189
|
+
</head>
|
|
190
|
+
<body>
|
|
191
|
+
<div id="drawio-container"></div>
|
|
192
|
+
|
|
193
|
+
<script type="module">
|
|
194
|
+
import * as Y from 'yjs';
|
|
195
|
+
import { Binding, LOCAL_ORIGIN } from 'y-mxgraph';
|
|
196
|
+
import { createIframeBridgeProvider } from 'y-mxgraph/iframe-bridge/provider';
|
|
197
|
+
|
|
198
|
+
// 1. 创建本地 Y.Doc(不需要网络 Provider)
|
|
199
|
+
const doc = new Y.Doc();
|
|
200
|
+
|
|
201
|
+
// 2. 创建 iframe bridge provider
|
|
202
|
+
// - 不需要外部 awareness,provider 会创建自己的 AwarenessLike
|
|
203
|
+
// - 自动通过 postMessage 与父页面同步
|
|
204
|
+
const bridge = createIframeBridgeProvider(doc, {
|
|
205
|
+
debug: true, // 启用控制台日志
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
// 3. 监听与父页面的连接状态
|
|
209
|
+
bridge.onConnect(() => {
|
|
210
|
+
console.log('[iframe] 已连接到父页面 bridge');
|
|
211
|
+
});
|
|
212
|
+
bridge.onDisconnect(() => {
|
|
213
|
+
console.log('[iframe] 已断开与父页面 bridge 的连接');
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
// 4. 初始化 draw.io
|
|
217
|
+
App.main((app) => {
|
|
218
|
+
const file = app.currentFile;
|
|
219
|
+
|
|
220
|
+
// 5. 使用 bridge awareness 创建 binding
|
|
221
|
+
const binding = new Binding(file, {
|
|
222
|
+
doc,
|
|
223
|
+
awareness: bridge.awareness,
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
// 6. 接管 draw.io 的 undo manager,使其通过父页面执行
|
|
227
|
+
const cleanupUndo = bridge.takeoverUndoManager(file);
|
|
228
|
+
|
|
229
|
+
// 7. 页面卸载时清理
|
|
230
|
+
window.addEventListener('beforeunload', () => {
|
|
231
|
+
binding.destroy();
|
|
232
|
+
cleanupUndo();
|
|
233
|
+
bridge.destroy();
|
|
234
|
+
});
|
|
235
|
+
});
|
|
236
|
+
</script>
|
|
237
|
+
</body>
|
|
238
|
+
</html>
|
|
239
|
+
```
|
|
90
240
|
|
|
91
|
-
|
|
92
|
-
const provider = new WebrtcProvider(roomName, doc, { signaling });
|
|
93
|
-
const awareness = provider.awareness;
|
|
241
|
+
### 核心特性
|
|
94
242
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
243
|
+
- **自动同步**: Y.Doc 和 Awareness 状态在父页面和 iframe 之间自动同步
|
|
244
|
+
- **用户信息传播**: 在父页面 awareness 上设置用户信息,iframe 自动接收
|
|
245
|
+
- **跨 iframe 撤销/重做**: 父页面的 UndoManager 控制所有 iframe 的撤销/重做
|
|
246
|
+
- **连接生命周期**: `onConnect`/`onDisconnect` 回调用于状态监控
|
|
247
|
+
- **调试模式**: 设置 `debug: true` 记录所有 postMessage 通信
|
|
99
248
|
|
|
100
|
-
|
|
101
|
-
// 如果 UndoManager 支持 addTrackedOrigin/removeTrackedOrigin,桥接会自动管理 IFRAME_ORIGIN。
|
|
102
|
-
// 如果不支持,请继续在 trackedOrigins 中保留 IFRAME_ORIGIN。
|
|
103
|
-
const bridge = createIframeBridgeServer(iframeElement, doc, awareness, { undoManager });
|
|
249
|
+
### API 参考
|
|
104
250
|
|
|
105
|
-
|
|
106
|
-
document.getElementById('undo-btn')!.onclick = () => {
|
|
107
|
-
if (undoManager.canUndo()) undoManager.undo();
|
|
108
|
-
};
|
|
251
|
+
#### `createIframeBridgeServer(iframe, ydoc, awareness, options?)`
|
|
109
252
|
|
|
110
|
-
|
|
111
|
-
import * as Y from 'yjs';
|
|
112
|
-
import { Awareness } from 'y-protocols/awareness';
|
|
113
|
-
import { Binding } from 'y-mxgraph';
|
|
114
|
-
import { createIframeBridgeProvider } from 'y-mxgraph/iframe-bridge/provider';
|
|
253
|
+
在父页面创建 bridge server。
|
|
115
254
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
255
|
+
**参数:**
|
|
256
|
+
- `iframe: HTMLIFrameElement` - 目标 iframe 元素
|
|
257
|
+
- `ydoc: Y.Doc` - 共享的 Yjs 文档
|
|
258
|
+
- `awareness: Awareness` - Awareness 实例(通常来自 provider.awareness)
|
|
259
|
+
- `options.undoManager?: Y.UndoManager` - 可选的 UndoManager,用于跨 iframe 撤销
|
|
260
|
+
- `options.debug?: boolean` - 启用调试日志(默认:false)
|
|
119
261
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
262
|
+
**返回:** `IframeBridgeServer`,包含:
|
|
263
|
+
- `connected: boolean` - 当前连接状态
|
|
264
|
+
- `onConnect(fn)` / `onDisconnect(fn)` - 连接生命周期回调
|
|
265
|
+
- `destroy()` - 清理所有监听器
|
|
266
|
+
|
|
267
|
+
#### `createIframeBridgeProvider(ydoc, options?)`
|
|
268
|
+
|
|
269
|
+
在 iframe 内创建 bridge provider。
|
|
270
|
+
|
|
271
|
+
**参数:**
|
|
272
|
+
- `ydoc: Y.Doc` - 本地 Yjs 文档
|
|
273
|
+
- `options.awareness?: Awareness` - 可选的外部 Awareness(省略则创建内部 AwarenessLike)
|
|
274
|
+
- `options.debug?: boolean` - 启用调试日志(默认:false)
|
|
275
|
+
|
|
276
|
+
**返回:** `IframeBridgeProvider`,包含:
|
|
277
|
+
- `connected: boolean` - 与父页面的连接状态
|
|
278
|
+
- `awareness: Awareness` - Awareness 实例(用于 Binding)
|
|
279
|
+
- `serverClientId: number | null` - 父页面的 client ID
|
|
280
|
+
- `setLocalFields(fields)` - 更新本地用户字段
|
|
281
|
+
- `takeoverUndoManager(file)` - 接管 draw.io 的 undo/redo 使其通过父页面执行
|
|
282
|
+
- `onConnect(fn)` / `onDisconnect(fn)` - 连接生命周期回调
|
|
283
|
+
- `destroy()` - 清理所有监听器
|
|
127
284
|
|
|
128
285
|
详见 [iframe Bridge 文档](https://mizuka-wu.github.io/y-mxgraph/guide/iframe-bridge)。
|
|
129
286
|
|