superdoc 2.20.1-next.9 → 2.21.0-next.2
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/dist/chunks/{create-super-doc-ui-Cfwszc3b.es.js → create-super-doc-ui-0CZTlOvl.es.js} +571 -4
- package/dist/chunks/{create-super-doc-ui-j8Qm5SYa.cjs → create-super-doc-ui-yKesgn9b.cjs} +582 -3
- package/dist/collaboration-upgrade-engine.cjs +1 -1
- package/dist/collaboration-upgrade-engine.es.js +1 -1
- package/dist/document-api/src/contract/command-catalog.d.ts +1 -1
- package/dist/document-api/src/contract/operation-definitions.d.ts +3 -3
- package/dist/document-api/src/ranges/ranges.types.d.ts +7 -3
- package/dist/document-api/src/types/create.types.d.ts +91 -2
- package/dist/layout-engine/contracts/src/index.d.ts +37 -0
- package/dist/layout-engine/contracts/src/segment-geometry.d.ts +22 -6
- package/dist/layout-engine/layout-bridge/src/line-justify-adjustment.d.ts +106 -0
- package/dist/public/ui-react.cjs +1 -1
- package/dist/public/ui-react.es.js +1 -1
- package/dist/public/ui-vue.cjs +1 -1
- package/dist/public/ui-vue.es.js +1 -1
- package/dist/public/ui.cjs +1 -1
- package/dist/public/ui.es.js +1 -1
- package/dist/style.css +27 -27
- package/dist/style.layered.css +27 -27
- package/dist/superdoc/src/internal/diagnostics/interaction-history.d.ts +7 -1
- package/dist/superdoc/src/internal/diagnostics/workflow-recording.d.ts +73 -0
- package/dist/superdoc.cjs +11 -7
- package/dist/superdoc.es.js +11 -7
- package/dist-cdn/style.layered.css +1 -1
- package/dist-cdn/superdoc.min.css +1 -1
- package/dist-cdn/superdoc.min.js +39 -39
- package/package.json +2 -2
|
@@ -1,5 +1,563 @@
|
|
|
1
1
|
const require__plugin_vue_export_helper = require("./_plugin-vue_export-helper-CYxINHh_.cjs");
|
|
2
|
+
//#region src/internal/diagnostics/workflow-recording.ts
|
|
3
|
+
var fields$1 = /* @__PURE__ */ new Set([
|
|
4
|
+
"documentId",
|
|
5
|
+
"actionId",
|
|
6
|
+
"commandId",
|
|
7
|
+
"operation",
|
|
8
|
+
"source",
|
|
9
|
+
"origin",
|
|
10
|
+
"phase",
|
|
11
|
+
"kind",
|
|
12
|
+
"status",
|
|
13
|
+
"success",
|
|
14
|
+
"changed",
|
|
15
|
+
"reason",
|
|
16
|
+
"code",
|
|
17
|
+
"direction",
|
|
18
|
+
"outcome",
|
|
19
|
+
"receipt",
|
|
20
|
+
"result",
|
|
21
|
+
"failure",
|
|
22
|
+
"rejection",
|
|
23
|
+
"txId",
|
|
24
|
+
"documentEpoch",
|
|
25
|
+
"commitSequence",
|
|
26
|
+
"targetCommitSequence",
|
|
27
|
+
"paintedCommitSequence",
|
|
28
|
+
"renderInputEpoch",
|
|
29
|
+
"paintedRenderInputEpoch",
|
|
30
|
+
"health",
|
|
31
|
+
"selection",
|
|
32
|
+
"selectionBefore",
|
|
33
|
+
"selectionAfter",
|
|
34
|
+
"snapshot",
|
|
35
|
+
"target",
|
|
36
|
+
"start",
|
|
37
|
+
"end",
|
|
38
|
+
"anchor",
|
|
39
|
+
"focus",
|
|
40
|
+
"story",
|
|
41
|
+
"storyType",
|
|
42
|
+
"storyId",
|
|
43
|
+
"refId",
|
|
44
|
+
"noteId",
|
|
45
|
+
"textboxId",
|
|
46
|
+
"position",
|
|
47
|
+
"offset",
|
|
48
|
+
"unit",
|
|
49
|
+
"value",
|
|
50
|
+
"blockId",
|
|
51
|
+
"blockOffset",
|
|
52
|
+
"fragmentId",
|
|
53
|
+
"pageIndex",
|
|
54
|
+
"layoutEpoch",
|
|
55
|
+
"revision",
|
|
56
|
+
"sourceCommit",
|
|
57
|
+
"selectionLineageId",
|
|
58
|
+
"selectionIntentSequence",
|
|
59
|
+
"intentSequence",
|
|
60
|
+
"intentId",
|
|
61
|
+
"authoringMode",
|
|
62
|
+
"editableCommandKind",
|
|
63
|
+
"inputKind",
|
|
64
|
+
"visualIntent",
|
|
65
|
+
"preEdit",
|
|
66
|
+
"postEdit",
|
|
67
|
+
"fallback",
|
|
68
|
+
"selectionRevision",
|
|
69
|
+
"timing",
|
|
70
|
+
"selectionTargetMs",
|
|
71
|
+
"textReplaceMs",
|
|
72
|
+
"postEditSelectionMs",
|
|
73
|
+
"totalMs",
|
|
74
|
+
"inputAtMs",
|
|
75
|
+
"dispatchAtMs",
|
|
76
|
+
"committedAtMs",
|
|
77
|
+
"durationMs",
|
|
78
|
+
"elapsedMs",
|
|
79
|
+
"affectedStories",
|
|
80
|
+
"tableId",
|
|
81
|
+
"cellId",
|
|
82
|
+
"contentControlId",
|
|
83
|
+
"outsideContentControl",
|
|
84
|
+
"trackedBlockOffset",
|
|
85
|
+
"projectionBlockId",
|
|
86
|
+
"geometryBlockId",
|
|
87
|
+
"geometryBlockOffset",
|
|
88
|
+
"geometryTrackedBlockOffset",
|
|
89
|
+
"lineAffinity",
|
|
90
|
+
"inlineAffinity",
|
|
91
|
+
"stability",
|
|
92
|
+
"nativeId",
|
|
93
|
+
"paraId",
|
|
94
|
+
"partId",
|
|
95
|
+
"partRevision",
|
|
96
|
+
"storyRevision",
|
|
97
|
+
"pathFingerprint",
|
|
98
|
+
"path",
|
|
99
|
+
"index",
|
|
100
|
+
"name",
|
|
101
|
+
"id",
|
|
102
|
+
"range",
|
|
103
|
+
"hasRangeSelection",
|
|
104
|
+
"inputType",
|
|
105
|
+
"dataLength",
|
|
106
|
+
"isComposing",
|
|
107
|
+
"repeat",
|
|
108
|
+
"altKey",
|
|
109
|
+
"ctrlKey",
|
|
110
|
+
"metaKey",
|
|
111
|
+
"shiftKey",
|
|
112
|
+
"key",
|
|
113
|
+
"button",
|
|
114
|
+
"buttons",
|
|
115
|
+
"pointerType",
|
|
116
|
+
"clickCount",
|
|
117
|
+
"x",
|
|
118
|
+
"y",
|
|
119
|
+
"selector",
|
|
120
|
+
"domPath",
|
|
121
|
+
"scrollLeft",
|
|
122
|
+
"scrollTop",
|
|
123
|
+
"command",
|
|
124
|
+
"segments",
|
|
125
|
+
"nodeId",
|
|
126
|
+
"byteSpan",
|
|
127
|
+
"sdtId",
|
|
128
|
+
"controlId",
|
|
129
|
+
"scope",
|
|
130
|
+
"coordinateSpace",
|
|
131
|
+
"contentControlIds",
|
|
132
|
+
"scrollAncestors",
|
|
133
|
+
"layoutBlockRef",
|
|
134
|
+
"contextSource"
|
|
135
|
+
]);
|
|
136
|
+
var contentFields$1 = /* @__PURE__ */ new Set([
|
|
137
|
+
"text",
|
|
138
|
+
"data",
|
|
139
|
+
"message",
|
|
140
|
+
"errorMessage",
|
|
141
|
+
"quotedText"
|
|
142
|
+
]);
|
|
143
|
+
var inputTypes = [
|
|
144
|
+
"keydown",
|
|
145
|
+
"keyup",
|
|
146
|
+
"beforeinput",
|
|
147
|
+
"pointerdown",
|
|
148
|
+
"pointermove",
|
|
149
|
+
"pointerup",
|
|
150
|
+
"click",
|
|
151
|
+
"dblclick",
|
|
152
|
+
"mousedown",
|
|
153
|
+
"mouseup",
|
|
154
|
+
"scroll",
|
|
155
|
+
"compositionstart",
|
|
156
|
+
"compositionend",
|
|
157
|
+
"paste",
|
|
158
|
+
"cut",
|
|
159
|
+
"drop",
|
|
160
|
+
"dragstart"
|
|
161
|
+
];
|
|
162
|
+
var namedKeys = /* @__PURE__ */ new Set([
|
|
163
|
+
"Alt",
|
|
164
|
+
"AltGraph",
|
|
165
|
+
"CapsLock",
|
|
166
|
+
"Control",
|
|
167
|
+
"Meta",
|
|
168
|
+
"NumLock",
|
|
169
|
+
"ScrollLock",
|
|
170
|
+
"Shift",
|
|
171
|
+
"Enter",
|
|
172
|
+
"Tab",
|
|
173
|
+
"ArrowLeft",
|
|
174
|
+
"ArrowRight",
|
|
175
|
+
"ArrowUp",
|
|
176
|
+
"ArrowDown",
|
|
177
|
+
"End",
|
|
178
|
+
"Home",
|
|
179
|
+
"PageDown",
|
|
180
|
+
"PageUp",
|
|
181
|
+
"Backspace",
|
|
182
|
+
"Delete",
|
|
183
|
+
"Insert",
|
|
184
|
+
"Escape",
|
|
185
|
+
"ContextMenu",
|
|
186
|
+
"Pause",
|
|
187
|
+
"Dead",
|
|
188
|
+
"Process",
|
|
189
|
+
"Unidentified"
|
|
190
|
+
]);
|
|
191
|
+
var nextSession$1 = 0;
|
|
192
|
+
function own$1(value, key) {
|
|
193
|
+
return value && typeof value === "object" ? Object.getOwnPropertyDescriptor(value, key)?.value : void 0;
|
|
194
|
+
}
|
|
195
|
+
function budget(value, fallback, maximum) {
|
|
196
|
+
return typeof value === "number" && Number.isSafeInteger(value) && value > 0 && value <= maximum ? value : fallback;
|
|
197
|
+
}
|
|
198
|
+
var WorkflowRecorder = class {
|
|
199
|
+
constructor(root, version) {
|
|
200
|
+
this.root = root;
|
|
201
|
+
this.version = version;
|
|
202
|
+
this.session = null;
|
|
203
|
+
this.events = [];
|
|
204
|
+
this.startMs = 0;
|
|
205
|
+
this.maxEvents = 2e4;
|
|
206
|
+
this.maxBytes = 8388608;
|
|
207
|
+
this.closed = false;
|
|
208
|
+
this.pendingIntents = /* @__PURE__ */ new Set();
|
|
209
|
+
this.heldKeys = /* @__PURE__ */ new Set();
|
|
210
|
+
this.heldButtons = /* @__PURE__ */ new Set();
|
|
211
|
+
this.cleanups = [];
|
|
212
|
+
const recorder = this;
|
|
213
|
+
this.api = Object.freeze({
|
|
214
|
+
get active() {
|
|
215
|
+
return recorder.active;
|
|
216
|
+
},
|
|
217
|
+
start: (options) => this.start(options),
|
|
218
|
+
stop: () => this.stop(),
|
|
219
|
+
getSnapshot: () => this.snapshot()
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
attachInputs() {
|
|
223
|
+
const view = this.root.ownerDocument.defaultView;
|
|
224
|
+
if (!view) throw new Error("Workflow recording requires a browser window.");
|
|
225
|
+
try {
|
|
226
|
+
for (const type of inputTypes) {
|
|
227
|
+
const listener = (event) => {
|
|
228
|
+
if (!this.active || !event.isTrusted) return;
|
|
229
|
+
try {
|
|
230
|
+
if (event.target instanceof view.Node && this.root.contains(event.target)) this.input(event);
|
|
231
|
+
else if (event.type === "keyup" ? this.heldKeys.delete(event.key) : event.type === "pointerup" ? this.heldButtons.delete(event.button) : false) this.unsupported("input-released-outside-mount");
|
|
232
|
+
} catch {
|
|
233
|
+
this.fail("capture-failure");
|
|
234
|
+
}
|
|
235
|
+
};
|
|
236
|
+
view.addEventListener(type, listener, true);
|
|
237
|
+
this.cleanups.push(() => view.removeEventListener(type, listener, true));
|
|
238
|
+
}
|
|
239
|
+
} catch (error) {
|
|
240
|
+
this.detachInputs();
|
|
241
|
+
throw error;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
detachInputs() {
|
|
245
|
+
const cleanups = this.cleanups;
|
|
246
|
+
this.cleanups = [];
|
|
247
|
+
for (const cleanup of cleanups) try {
|
|
248
|
+
cleanup();
|
|
249
|
+
} catch {}
|
|
250
|
+
}
|
|
251
|
+
get active() {
|
|
252
|
+
return this.session?.status === "recording";
|
|
253
|
+
}
|
|
254
|
+
start(options = {}) {
|
|
255
|
+
if (this.closed) throw new Error("Cannot record a destroyed SuperDoc instance.");
|
|
256
|
+
if (this.active) throw new Error("Stop the active workflow recording first.");
|
|
257
|
+
this.maxEvents = budget(own$1(options, "maxEvents"), 2e4, 1e5);
|
|
258
|
+
this.maxBytes = budget(own$1(options, "maxBytes"), 8388608, 67108864);
|
|
259
|
+
const view = this.root.ownerDocument.defaultView;
|
|
260
|
+
this.events = [];
|
|
261
|
+
this.pendingIntents.clear();
|
|
262
|
+
this.startMs = view.performance.now();
|
|
263
|
+
this.session = {
|
|
264
|
+
schemaVersion: 1,
|
|
265
|
+
sessionId: `workflow-${Date.now()}-${++nextSession$1}`,
|
|
266
|
+
version: this.version(),
|
|
267
|
+
status: "recording",
|
|
268
|
+
startedAt: Date.now(),
|
|
269
|
+
durationMs: 0,
|
|
270
|
+
timeOrigin: view.performance.timeOrigin,
|
|
271
|
+
startTimeMs: this.startMs,
|
|
272
|
+
captureContent: own$1(options, "captureContent") === true,
|
|
273
|
+
viewport: {
|
|
274
|
+
width: view.innerWidth,
|
|
275
|
+
height: view.innerHeight,
|
|
276
|
+
devicePixelRatio: view.devicePixelRatio
|
|
277
|
+
},
|
|
278
|
+
retainedBytes: 0,
|
|
279
|
+
replayUnsupportedReasons: [],
|
|
280
|
+
pendingIntentIds: []
|
|
281
|
+
};
|
|
282
|
+
try {
|
|
283
|
+
this.attachInputs();
|
|
284
|
+
this.observe("workflow:started", () => ({
|
|
285
|
+
scrollTop: this.root.scrollTop,
|
|
286
|
+
scrollLeft: this.root.scrollLeft
|
|
287
|
+
}));
|
|
288
|
+
} catch {
|
|
289
|
+
this.fail("capture-failure");
|
|
290
|
+
}
|
|
291
|
+
return this.snapshot();
|
|
292
|
+
}
|
|
293
|
+
observe(type, read) {
|
|
294
|
+
if (!this.active) return;
|
|
295
|
+
try {
|
|
296
|
+
let remaining = 4096;
|
|
297
|
+
const copy = (value, depth = 0) => {
|
|
298
|
+
if (--remaining < 0 || depth > 14) throw new Error("payload-limit");
|
|
299
|
+
if (value === null || typeof value === "boolean") return value;
|
|
300
|
+
if (typeof value === "number") return Number.isFinite(value) ? value : void 0;
|
|
301
|
+
if (typeof value === "string") {
|
|
302
|
+
if (value.length > 32768) throw new Error("payload-limit");
|
|
303
|
+
return value;
|
|
304
|
+
}
|
|
305
|
+
if (!value || typeof value !== "object") return void 0;
|
|
306
|
+
if (Array.isArray(value)) {
|
|
307
|
+
if (value.length > 256) throw new Error("payload-limit");
|
|
308
|
+
return Array.from({ length: value.length }, (_, i) => copy(own$1(value, String(i)), depth + 1) ?? null);
|
|
309
|
+
}
|
|
310
|
+
const result = {};
|
|
311
|
+
for (const key of fields$1) {
|
|
312
|
+
const item = own$1(value, key);
|
|
313
|
+
if (key === "value" && typeof item === "string" && !this.session.captureContent) continue;
|
|
314
|
+
if (item !== void 0) result[key] = copy(item, depth + 1);
|
|
315
|
+
}
|
|
316
|
+
if (this.session.captureContent) for (const key of contentFields$1) {
|
|
317
|
+
const item = own$1(value, key);
|
|
318
|
+
if (item !== void 0) result[key] = copy(item, depth + 1);
|
|
319
|
+
}
|
|
320
|
+
return result;
|
|
321
|
+
};
|
|
322
|
+
const event = {
|
|
323
|
+
sequence: this.events.length + 1,
|
|
324
|
+
atMs: this.root.ownerDocument.defaultView.performance.now() - this.startMs,
|
|
325
|
+
type,
|
|
326
|
+
data: copy(read()) ?? {}
|
|
327
|
+
};
|
|
328
|
+
const serialized = JSON.stringify(event);
|
|
329
|
+
if (this.events.length >= this.maxEvents || this.session.retainedBytes + serialized.length * 2 > this.maxBytes) {
|
|
330
|
+
this.fail("capture-limit");
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
this.events.push(serialized);
|
|
334
|
+
this.session.retainedBytes += serialized.length * 2;
|
|
335
|
+
if (type === "interaction:intent") {
|
|
336
|
+
const id = `${event.data.documentId ?? ""}/${event.data.selectionLineageId}/${event.data.intentSequence}`;
|
|
337
|
+
if (event.data.phase === "enqueued" || event.data.phase === "executing") this.pendingIntents.add(id);
|
|
338
|
+
if (event.data.phase === "settled" || event.data.phase === "failed") this.pendingIntents.delete(id);
|
|
339
|
+
}
|
|
340
|
+
} catch {
|
|
341
|
+
this.fail("capture-failure");
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
unsupported(reason) {
|
|
345
|
+
if (!this.session.replayUnsupportedReasons.includes(reason)) this.session.replayUnsupportedReasons.push(reason);
|
|
346
|
+
}
|
|
347
|
+
fail(reason) {
|
|
348
|
+
if (!this.session) return;
|
|
349
|
+
this.unsupported(reason);
|
|
350
|
+
try {
|
|
351
|
+
this.session.durationMs = this.root.ownerDocument.defaultView.performance.now() - this.startMs;
|
|
352
|
+
} catch {}
|
|
353
|
+
this.session.status = "incomplete";
|
|
354
|
+
this.clearHeldInput();
|
|
355
|
+
this.detachInputs();
|
|
356
|
+
}
|
|
357
|
+
input(event) {
|
|
358
|
+
if (!this.active || !event.isTrusted) return;
|
|
359
|
+
try {
|
|
360
|
+
const target = event.target instanceof this.root.ownerDocument.defaultView.Element ? event.target : this.root;
|
|
361
|
+
const pointer = event;
|
|
362
|
+
if (event.type === "pointermove" && pointer.buttons === 0) return;
|
|
363
|
+
let element = target;
|
|
364
|
+
let selector = null;
|
|
365
|
+
while (element && element !== this.root) {
|
|
366
|
+
for (const attribute of [
|
|
367
|
+
"data-layout-fragment-id",
|
|
368
|
+
"data-layout-block-ref",
|
|
369
|
+
"data-page-index",
|
|
370
|
+
"data-item",
|
|
371
|
+
"data-testid",
|
|
372
|
+
"aria-label"
|
|
373
|
+
]) {
|
|
374
|
+
const value = element.getAttribute(attribute);
|
|
375
|
+
if (value) {
|
|
376
|
+
selector = `[${attribute}=${JSON.stringify(value)}]`;
|
|
377
|
+
break;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
if (selector) break;
|
|
381
|
+
element = element.parentElement;
|
|
382
|
+
}
|
|
383
|
+
if (!selector && target !== this.root) {
|
|
384
|
+
const path = [];
|
|
385
|
+
element = target;
|
|
386
|
+
while (element && element !== this.root) {
|
|
387
|
+
const parent = element.parentElement;
|
|
388
|
+
if (!parent) break;
|
|
389
|
+
path.unshift(`:nth-child(${Array.prototype.indexOf.call(parent.children, element) + 1})`);
|
|
390
|
+
element = parent;
|
|
391
|
+
}
|
|
392
|
+
if (element === this.root) selector = `:scope > ${path.join(" > ")}`;
|
|
393
|
+
element = target;
|
|
394
|
+
}
|
|
395
|
+
const modifiers = event;
|
|
396
|
+
const paintedTarget = { selector };
|
|
397
|
+
if (event.type.startsWith("pointer") || [
|
|
398
|
+
"mousedown",
|
|
399
|
+
"mouseup",
|
|
400
|
+
"click",
|
|
401
|
+
"dblclick"
|
|
402
|
+
].includes(event.type)) {
|
|
403
|
+
const path = [];
|
|
404
|
+
let part = element ?? this.root;
|
|
405
|
+
while (part && part !== this.root) {
|
|
406
|
+
const parent = part.parentElement;
|
|
407
|
+
if (!parent) break;
|
|
408
|
+
path.unshift(`:nth-child(${Array.prototype.indexOf.call(parent.children, part) + 1})`);
|
|
409
|
+
part = parent;
|
|
410
|
+
}
|
|
411
|
+
if (part === this.root && path.length) paintedTarget.domPath = `:scope > ${path.join(" > ")}`;
|
|
412
|
+
const controls = /* @__PURE__ */ new Set();
|
|
413
|
+
for (let ancestor = target; ancestor && ancestor !== this.root; ancestor = ancestor.parentElement) {
|
|
414
|
+
for (const [attribute, field] of [
|
|
415
|
+
["data-source-node-id", "blockId"],
|
|
416
|
+
["data-layout-fragment-id", "fragmentId"],
|
|
417
|
+
["data-layout-block-ref", "layoutBlockRef"],
|
|
418
|
+
["data-layout-story", "storyId"],
|
|
419
|
+
["data-page-index", "pageIndex"]
|
|
420
|
+
]) {
|
|
421
|
+
const value = ancestor.getAttribute(attribute);
|
|
422
|
+
if (value && paintedTarget[field] == null) paintedTarget[field] = field === "pageIndex" ? Number(value) : value;
|
|
423
|
+
}
|
|
424
|
+
const control = ancestor.getAttribute("data-sdt-id") ?? ancestor.getAttribute("data-sdt-container-id");
|
|
425
|
+
if (control) controls.add(control);
|
|
426
|
+
if (ancestor.classList.contains("superdoc-table-fragment") && paintedTarget.tableId == null) paintedTarget.tableId = ancestor.getAttribute("data-layout-block-ref");
|
|
427
|
+
}
|
|
428
|
+
paintedTarget.contentControlIds = [...controls];
|
|
429
|
+
paintedTarget.contextSource = "painted-pointer";
|
|
430
|
+
if (paintedTarget.fragmentId && paintedTarget.pageIndex != null) paintedTarget.selector = `[data-page-index="${paintedTarget.pageIndex}"] ${selector}`;
|
|
431
|
+
const scrollAncestors = [];
|
|
432
|
+
for (let ancestor = target; ancestor; ancestor = ancestor.parentElement) {
|
|
433
|
+
const style = this.root.ownerDocument.defaultView.getComputedStyle(ancestor);
|
|
434
|
+
const scrollable = ancestor === this.root || /auto|scroll/.test(`${style.overflowX} ${style.overflowY}`);
|
|
435
|
+
if (ancestor.scrollLeft || ancestor.scrollTop || scrollable && (ancestor.scrollWidth > ancestor.clientWidth || ancestor.scrollHeight > ancestor.clientHeight)) {
|
|
436
|
+
const path = [];
|
|
437
|
+
let part = ancestor;
|
|
438
|
+
while (part && part !== this.root) {
|
|
439
|
+
const parent = part.parentElement;
|
|
440
|
+
if (!parent) break;
|
|
441
|
+
path.unshift(`:nth-child(${Array.prototype.indexOf.call(parent.children, part) + 1})`);
|
|
442
|
+
part = parent;
|
|
443
|
+
}
|
|
444
|
+
if (part === this.root) scrollAncestors.push({
|
|
445
|
+
selector: ancestor === this.root ? null : `:scope > ${path.join(" > ")}`,
|
|
446
|
+
scrollLeft: ancestor.scrollLeft,
|
|
447
|
+
scrollTop: ancestor.scrollTop
|
|
448
|
+
});
|
|
449
|
+
}
|
|
450
|
+
if (ancestor === this.root) break;
|
|
451
|
+
if (scrollAncestors.length >= 32) throw new Error("scroll-ancestor-limit");
|
|
452
|
+
}
|
|
453
|
+
paintedTarget.scrollAncestors = scrollAncestors;
|
|
454
|
+
}
|
|
455
|
+
const data = {
|
|
456
|
+
target: paintedTarget,
|
|
457
|
+
inputAtMs: event.timeStamp > this.root.ownerDocument.defaultView.performance.timeOrigin ? event.timeStamp - this.root.ownerDocument.defaultView.performance.timeOrigin : event.timeStamp,
|
|
458
|
+
altKey: modifiers.altKey,
|
|
459
|
+
ctrlKey: modifiers.ctrlKey,
|
|
460
|
+
metaKey: modifiers.metaKey,
|
|
461
|
+
shiftKey: modifiers.shiftKey
|
|
462
|
+
};
|
|
463
|
+
if (event.type === "keydown" || event.type === "keyup") {
|
|
464
|
+
const key = modifiers.key;
|
|
465
|
+
if (event.type === "keydown") this.heldKeys.add(key);
|
|
466
|
+
else this.heldKeys.delete(key);
|
|
467
|
+
const named = namedKeys.has(key) || /^F(?:[1-9]|1\d|2[0-4])$/.test(key);
|
|
468
|
+
data.key = !named && !this.session.captureContent ? void 0 : key;
|
|
469
|
+
data.repeat = modifiers.repeat;
|
|
470
|
+
data.isComposing = modifiers.isComposing;
|
|
471
|
+
if (!named && !this.session.captureContent) this.unsupported("content-redacted");
|
|
472
|
+
if (modifiers.isComposing || key === "Dead" || key === "Process") this.unsupported("ime");
|
|
473
|
+
} else if (event.type.startsWith("pointer") || [
|
|
474
|
+
"mousedown",
|
|
475
|
+
"mouseup",
|
|
476
|
+
"click",
|
|
477
|
+
"dblclick"
|
|
478
|
+
].includes(event.type)) {
|
|
479
|
+
const rect = (element ?? this.root).getBoundingClientRect();
|
|
480
|
+
if (event.type === "pointerdown") this.heldButtons.add(pointer.button);
|
|
481
|
+
if (event.type === "pointerup") this.heldButtons.delete(pointer.button);
|
|
482
|
+
Object.assign(data, {
|
|
483
|
+
button: pointer.button,
|
|
484
|
+
buttons: pointer.buttons,
|
|
485
|
+
pointerType: pointer.pointerType ?? "mouse",
|
|
486
|
+
clickCount: pointer.detail,
|
|
487
|
+
x: pointer.clientX - rect.left,
|
|
488
|
+
y: pointer.clientY - rect.top
|
|
489
|
+
});
|
|
490
|
+
if (pointer.pointerType && pointer.pointerType !== "mouse") this.unsupported("non-mouse-pointer");
|
|
491
|
+
if (!selector) this.unsupported("unresolved-pointer-target");
|
|
492
|
+
} else if (event.type === "scroll") {
|
|
493
|
+
Object.assign(data, {
|
|
494
|
+
scrollTop: target.scrollTop,
|
|
495
|
+
scrollLeft: target.scrollLeft
|
|
496
|
+
});
|
|
497
|
+
if (target !== this.root && !selector) this.unsupported("unresolved-scroll-target");
|
|
498
|
+
} else {
|
|
499
|
+
const input = event;
|
|
500
|
+
Object.assign(data, {
|
|
501
|
+
inputType: input.inputType,
|
|
502
|
+
dataLength: input.data?.length,
|
|
503
|
+
...this.session.captureContent ? { data: input.data } : {}
|
|
504
|
+
});
|
|
505
|
+
if (input.data && !this.session.captureContent) this.unsupported("content-redacted");
|
|
506
|
+
if ([
|
|
507
|
+
"paste",
|
|
508
|
+
"cut",
|
|
509
|
+
"drop",
|
|
510
|
+
"dragstart",
|
|
511
|
+
"compositionstart",
|
|
512
|
+
"compositionend"
|
|
513
|
+
].includes(event.type)) this.unsupported(event.type);
|
|
514
|
+
if (event.type === "beforeinput" && input.inputType !== "insertText" && !input.inputType?.startsWith("delete")) this.unsupported(`beforeinput:${input.inputType}`);
|
|
515
|
+
}
|
|
516
|
+
this.observe(`browser:${event.type}`, () => data);
|
|
517
|
+
} catch {
|
|
518
|
+
this.fail("capture-failure");
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
clearHeldInput() {
|
|
522
|
+
this.heldKeys.clear();
|
|
523
|
+
this.heldButtons.clear();
|
|
524
|
+
}
|
|
525
|
+
stop() {
|
|
526
|
+
if (this.active) {
|
|
527
|
+
if (this.heldKeys.size || this.heldButtons.size) this.unsupported("held-input-at-stop");
|
|
528
|
+
this.session.durationMs = this.root.ownerDocument.defaultView.performance.now() - this.startMs;
|
|
529
|
+
this.session.status = "stopped";
|
|
530
|
+
this.clearHeldInput();
|
|
531
|
+
}
|
|
532
|
+
this.detachInputs();
|
|
533
|
+
return this.snapshot();
|
|
534
|
+
}
|
|
535
|
+
snapshot() {
|
|
536
|
+
if (!this.session) return null;
|
|
537
|
+
return {
|
|
538
|
+
...this.session,
|
|
539
|
+
viewport: { ...this.session.viewport },
|
|
540
|
+
durationMs: this.active ? this.root.ownerDocument.defaultView.performance.now() - this.startMs : this.session.durationMs,
|
|
541
|
+
replayUnsupportedReasons: [...this.session.replayUnsupportedReasons],
|
|
542
|
+
events: this.events.map((event) => JSON.parse(event)),
|
|
543
|
+
pendingIntentIds: [...this.pendingIntents]
|
|
544
|
+
};
|
|
545
|
+
}
|
|
546
|
+
close() {
|
|
547
|
+
if (this.active) this.fail("instance-destroyed");
|
|
548
|
+
this.closed = true;
|
|
549
|
+
this.detachInputs();
|
|
550
|
+
}
|
|
551
|
+
};
|
|
552
|
+
//#endregion
|
|
2
553
|
//#region src/internal/diagnostics/interaction-history.ts
|
|
554
|
+
function isWorkflowRecordingEnabled(config) {
|
|
555
|
+
try {
|
|
556
|
+
return own(own(own(config, "diagnostics"), "recording"), "enabled") === true;
|
|
557
|
+
} catch {
|
|
558
|
+
return false;
|
|
559
|
+
}
|
|
560
|
+
}
|
|
3
561
|
var recorders = /* @__PURE__ */ new WeakMap();
|
|
4
562
|
var nextSession = 0;
|
|
5
563
|
var fields = [
|
|
@@ -105,7 +663,7 @@ function limit(value, fallback, ceiling) {
|
|
|
105
663
|
return typeof value === "number" && Number.isSafeInteger(value) && value > 0 && value <= ceiling ? value : fallback;
|
|
106
664
|
}
|
|
107
665
|
var InteractionRecorder = class {
|
|
108
|
-
constructor(config, version) {
|
|
666
|
+
constructor(config, version, root) {
|
|
109
667
|
this.version = version;
|
|
110
668
|
this.sessionId = `interaction-${++nextSession}`;
|
|
111
669
|
this.slots = [];
|
|
@@ -119,6 +677,9 @@ var InteractionRecorder = class {
|
|
|
119
677
|
this.failures = 0;
|
|
120
678
|
this.closed = false;
|
|
121
679
|
this.cleanups = [];
|
|
680
|
+
if (isWorkflowRecordingEnabled(config)) try {
|
|
681
|
+
this.workflow = new WorkflowRecorder(root, version);
|
|
682
|
+
} catch {}
|
|
122
683
|
const history = own(own(config, "diagnostics"), "history");
|
|
123
684
|
this.enabled = own(history, "enabled") !== false;
|
|
124
685
|
this.captureContent = own(history, "captureContent") === true;
|
|
@@ -126,6 +687,7 @@ var InteractionRecorder = class {
|
|
|
126
687
|
this.maxBytes = limit(own(history, "maxBytes"), 1048576, 16777216);
|
|
127
688
|
}
|
|
128
689
|
record(type, read) {
|
|
690
|
+
this.workflow?.observe(type, read);
|
|
129
691
|
if (!this.enabled || this.closed) return;
|
|
130
692
|
try {
|
|
131
693
|
let truncated = false;
|
|
@@ -202,7 +764,7 @@ var InteractionRecorder = class {
|
|
|
202
764
|
}
|
|
203
765
|
}
|
|
204
766
|
action() {
|
|
205
|
-
return this.enabled && !this.closed ? `${this.sessionId}:${++this.actions}` : void 0;
|
|
767
|
+
return (this.enabled || this.workflow?.active) && !this.closed ? `${this.sessionId}:${++this.actions}` : void 0;
|
|
206
768
|
}
|
|
207
769
|
snapshot() {
|
|
208
770
|
const events = [];
|
|
@@ -286,6 +848,7 @@ var InteractionRecorder = class {
|
|
|
286
848
|
}
|
|
287
849
|
}
|
|
288
850
|
close() {
|
|
851
|
+
this.workflow?.close();
|
|
289
852
|
this.closed = true;
|
|
290
853
|
for (const cleanup of this.cleanups) try {
|
|
291
854
|
cleanup();
|
|
@@ -312,10 +875,11 @@ var unavailable = Object.freeze({
|
|
|
312
875
|
});
|
|
313
876
|
function createInteractionHistory(owner, config, version, root) {
|
|
314
877
|
try {
|
|
315
|
-
const recorder = new InteractionRecorder(config, version);
|
|
878
|
+
const recorder = new InteractionRecorder(config, version, root);
|
|
316
879
|
recorders.set(owner, recorder);
|
|
317
880
|
recorder.attach(root);
|
|
318
881
|
const handle = Object.freeze({
|
|
882
|
+
...recorder.workflow ? { recording: recorder.workflow.api } : {},
|
|
319
883
|
getSnapshot: () => {
|
|
320
884
|
try {
|
|
321
885
|
return recorder.snapshot();
|
|
@@ -360,6 +924,9 @@ function closeInteractionHistory(owner) {
|
|
|
360
924
|
recorders.delete(owner);
|
|
361
925
|
} catch {}
|
|
362
926
|
}
|
|
927
|
+
function getWorkflowRecording(owner) {
|
|
928
|
+
return recorders.get(owner)?.workflow?.api;
|
|
929
|
+
}
|
|
363
930
|
//#endregion
|
|
364
931
|
//#region ../layout-engine/dom-contract/src/class-names.ts
|
|
365
932
|
/**
|
|
@@ -13715,6 +14282,18 @@ Object.defineProperty(exports, "getV2TrackedChangeMutationImpact", {
|
|
|
13715
14282
|
return getV2TrackedChangeMutationImpact;
|
|
13716
14283
|
}
|
|
13717
14284
|
});
|
|
14285
|
+
Object.defineProperty(exports, "getWorkflowRecording", {
|
|
14286
|
+
enumerable: true,
|
|
14287
|
+
get: function() {
|
|
14288
|
+
return getWorkflowRecording;
|
|
14289
|
+
}
|
|
14290
|
+
});
|
|
14291
|
+
Object.defineProperty(exports, "isWorkflowRecordingEnabled", {
|
|
14292
|
+
enumerable: true,
|
|
14293
|
+
get: function() {
|
|
14294
|
+
return isWorkflowRecordingEnabled;
|
|
14295
|
+
}
|
|
14296
|
+
});
|
|
13718
14297
|
Object.defineProperty(exports, "readFirstPartyPageNumbers", {
|
|
13719
14298
|
enumerable: true,
|
|
13720
14299
|
get: function() {
|
|
@@ -19,7 +19,7 @@ var COLLABORATION_UPGRADE_ENGINE_MINIMUM_NODE_MAJOR = 20;
|
|
|
19
19
|
var PRIVATE_ENGINE_INFO = (0, _superdoc_docx_engine_collaboration_upgrade_engine.getCollaborationUpgradeEngineInfo)();
|
|
20
20
|
var ENGINE_INFO = Object.freeze({
|
|
21
21
|
...PRIVATE_ENGINE_INFO,
|
|
22
|
-
superdocVersion: "2.
|
|
22
|
+
superdocVersion: "2.21.0-next.2",
|
|
23
23
|
roomSchemaVersion: Object.freeze({ ...PRIVATE_ENGINE_INFO.roomSchemaVersion }),
|
|
24
24
|
supportedBundleVersions: SUPPORTED_COLLABORATION_UPGRADE_BUNDLE_VERSIONS,
|
|
25
25
|
supportedV1ReaderContractVersions: SUPPORTED_V1_READER_CONTRACT_VERSIONS
|
|
@@ -18,7 +18,7 @@ var COLLABORATION_UPGRADE_ENGINE_MINIMUM_NODE_MAJOR = 20;
|
|
|
18
18
|
var PRIVATE_ENGINE_INFO = getCollaborationUpgradeEngineInfo$1();
|
|
19
19
|
var ENGINE_INFO = Object.freeze({
|
|
20
20
|
...PRIVATE_ENGINE_INFO,
|
|
21
|
-
superdocVersion: "2.
|
|
21
|
+
superdocVersion: "2.21.0-next.2",
|
|
22
22
|
roomSchemaVersion: Object.freeze({ ...PRIVATE_ENGINE_INFO.roomSchemaVersion }),
|
|
23
23
|
supportedBundleVersions: SUPPORTED_COLLABORATION_UPGRADE_BUNDLE_VERSIONS,
|
|
24
24
|
supportedV1ReaderContractVersions: SUPPORTED_V1_READER_CONTRACT_VERSIONS
|