@ai-matrx/office 0.8.44 → 0.8.46
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/CHANGELOG.md +23 -2
- package/dist/collab-sheets-transform.cjs +12 -0
- package/dist/collab-sheets-transform.cjs.map +1 -1
- package/dist/collab-sheets-transform.js +12 -0
- package/dist/collab-sheets-transform.js.map +1 -1
- package/dist/docs.cjs +85 -24
- package/dist/docs.cjs.map +1 -1
- package/dist/docs.d.cts +15 -1
- package/dist/docs.d.ts +15 -1
- package/dist/docs.js +65 -4
- package/dist/docs.js.map +1 -1
- package/dist/pdf-model.cjs +232 -0
- package/dist/pdf-model.cjs.map +1 -0
- package/dist/pdf-model.d.cts +248 -0
- package/dist/pdf-model.d.ts +248 -0
- package/dist/pdf-model.js +209 -0
- package/dist/pdf-model.js.map +1 -0
- package/dist/pdf.cjs +1127 -0
- package/dist/pdf.cjs.map +1 -0
- package/dist/pdf.d.cts +255 -0
- package/dist/pdf.d.ts +255 -0
- package/dist/pdf.js +1133 -0
- package/dist/pdf.js.map +1 -0
- package/dist/univer-collab.cjs +250 -22
- package/dist/univer-collab.cjs.map +1 -1
- package/dist/univer-collab.d.cts +91 -10
- package/dist/univer-collab.d.ts +91 -10
- package/dist/univer-collab.js +250 -22
- package/dist/univer-collab.js.map +1 -1
- package/package.json +27 -6
package/dist/univer-collab.js
CHANGED
|
@@ -1165,26 +1165,77 @@ function rebaseUndoStack(items, remote, stack) {
|
|
|
1165
1165
|
const first = stack === "undo" ? "undoMutations" : "redoMutations";
|
|
1166
1166
|
const second = stack === "undo" ? "redoMutations" : "undoMutations";
|
|
1167
1167
|
let dropped = 0;
|
|
1168
|
-
|
|
1168
|
+
let R = remote;
|
|
1169
|
+
for (let i = items.length - 1; i >= 0 && !isNoopDocsOp(R); i--) {
|
|
1169
1170
|
const item = items[i];
|
|
1170
1171
|
try {
|
|
1171
|
-
const a = threadThrough(item[first],
|
|
1172
|
+
const a = threadThrough(item[first], R);
|
|
1172
1173
|
const b = threadThrough(item[second], a.after);
|
|
1173
1174
|
if (a.next) item[first] = a.next;
|
|
1174
1175
|
if (b.next) item[second] = b.next;
|
|
1176
|
+
R = a.after;
|
|
1175
1177
|
} catch {
|
|
1176
1178
|
items.splice(i, 1);
|
|
1177
1179
|
dropped++;
|
|
1180
|
+
R = carryPast(item[first], R);
|
|
1178
1181
|
}
|
|
1179
1182
|
}
|
|
1180
1183
|
return dropped;
|
|
1181
1184
|
}
|
|
1185
|
+
function carryPast(list, remote) {
|
|
1186
|
+
let R = remote;
|
|
1187
|
+
for (const m of list ?? []) {
|
|
1188
|
+
if (m.id !== RICH_TEXT_EDITING || isNoopDocsOp(R)) continue;
|
|
1189
|
+
const own = m.params.actions;
|
|
1190
|
+
if (touchesPageSetup(own) && touchesPageSetup(R)) continue;
|
|
1191
|
+
R = transformDocsOp(R, own, "right").op;
|
|
1192
|
+
}
|
|
1193
|
+
return R;
|
|
1194
|
+
}
|
|
1195
|
+
var UNDO_COMMAND = "univer.command.undo";
|
|
1196
|
+
var REDO_COMMAND = "univer.command.redo";
|
|
1182
1197
|
function openDocsOtRoom(o) {
|
|
1183
1198
|
const { port } = o;
|
|
1184
1199
|
let session = null;
|
|
1185
1200
|
let composing = false;
|
|
1186
1201
|
let queue = [];
|
|
1187
1202
|
const drainWaiters = [];
|
|
1203
|
+
let replay = null;
|
|
1204
|
+
const noteHistoryStep = (m, inverse) => {
|
|
1205
|
+
const side = m.cmd === UNDO_COMMAND ? "undo" : m.cmd === REDO_COMMAND ? "redo" : null;
|
|
1206
|
+
if (!side) {
|
|
1207
|
+
replay = null;
|
|
1208
|
+
return;
|
|
1209
|
+
}
|
|
1210
|
+
for (const t of port.undoTargets()) {
|
|
1211
|
+
const stacks = undoStacksOf(t.service);
|
|
1212
|
+
const stack = stacks ? (side === "undo" ? stacks.undo : stacks.redo).get(t.unitId) : void 0;
|
|
1213
|
+
const item = stack?.[stack.length - 1];
|
|
1214
|
+
const list = item ? side === "undo" ? item.undoMutations : item.redoMutations : void 0;
|
|
1215
|
+
const k = list ? list.findIndex((x) => x.params === m.params) : -1;
|
|
1216
|
+
if (!item || !list || k < 0) continue;
|
|
1217
|
+
if (k === 0 || !replay || replay.item !== item || replay.side !== side) {
|
|
1218
|
+
const other = (side === "undo" ? item.redoMutations : item.undoMutations)?.[0]?.params ?? {};
|
|
1219
|
+
const { textRanges: _t, layoutState: _l, actions: _a, ...template } = other;
|
|
1220
|
+
replay = { item, side, inverses: [], template };
|
|
1221
|
+
}
|
|
1222
|
+
if (inverse === void 0 || list.some((x) => x.id !== RICH_TEXT_EDITING)) {
|
|
1223
|
+
replay = null;
|
|
1224
|
+
return;
|
|
1225
|
+
}
|
|
1226
|
+
replay.inverses.unshift(inverse);
|
|
1227
|
+
if (k === list.length - 1) {
|
|
1228
|
+
const rewritten = replay.inverses.filter((op) => !isNoopDocsOp(op)).map((op) => ({ id: RICH_TEXT_EDITING, params: { ...replay.template, segmentId: m.params?.segmentId ?? "", actions: op } }));
|
|
1229
|
+
if (rewritten.length) {
|
|
1230
|
+
if (side === "undo") item.redoMutations = rewritten;
|
|
1231
|
+
else item.undoMutations = rewritten;
|
|
1232
|
+
}
|
|
1233
|
+
replay = null;
|
|
1234
|
+
}
|
|
1235
|
+
return;
|
|
1236
|
+
}
|
|
1237
|
+
replay = null;
|
|
1238
|
+
};
|
|
1188
1239
|
const notice = (n) => {
|
|
1189
1240
|
try {
|
|
1190
1241
|
o.onNotice?.(n);
|
|
@@ -1282,7 +1333,10 @@ function openDocsOtRoom(o) {
|
|
|
1282
1333
|
}
|
|
1283
1334
|
const p = m.params ?? {};
|
|
1284
1335
|
const applied = p.actions ?? null;
|
|
1285
|
-
if (isNoopDocsOp(applied))
|
|
1336
|
+
if (isNoopDocsOp(applied)) {
|
|
1337
|
+
noteHistoryStep(m, null);
|
|
1338
|
+
return;
|
|
1339
|
+
}
|
|
1286
1340
|
let op = normalizeDocsOp(structuredClone(applied));
|
|
1287
1341
|
let inverse;
|
|
1288
1342
|
try {
|
|
@@ -1290,6 +1344,7 @@ function openDocsOtRoom(o) {
|
|
|
1290
1344
|
} catch {
|
|
1291
1345
|
inverse = void 0;
|
|
1292
1346
|
}
|
|
1347
|
+
noteHistoryStep(m, inverse === void 0 ? void 0 : normalizeDocsOp(inverse));
|
|
1293
1348
|
if (queue.length) {
|
|
1294
1349
|
inverse = void 0;
|
|
1295
1350
|
const next = [];
|
|
@@ -2781,6 +2836,18 @@ function transformCell(X, Y4, side) {
|
|
|
2781
2836
|
if (styleKeys(xs).length !== styleKeys(kept ?? {}).length) xLost = true;
|
|
2782
2837
|
}
|
|
2783
2838
|
}
|
|
2839
|
+
if (hasContent(X) && hasContent(Y4)) {
|
|
2840
|
+
const has = (s) => !!s && typeof s === "object" && "n" in s;
|
|
2841
|
+
const outS = out.s;
|
|
2842
|
+
if (side === "left" && !has(X.s) && has(Y4.s) && X.s !== null) {
|
|
2843
|
+
out.s = { ...outS && typeof outS === "object" ? outS : {}, n: null };
|
|
2844
|
+
} else if (side === "right" && outS && typeof outS === "object" && "n" in outS) {
|
|
2845
|
+
const rest = withoutStyleKeys(outS, /* @__PURE__ */ new Set(["n"]));
|
|
2846
|
+
if (rest) out.s = rest;
|
|
2847
|
+
else delete out.s;
|
|
2848
|
+
xLost = true;
|
|
2849
|
+
}
|
|
2850
|
+
}
|
|
2784
2851
|
return { entries: Object.keys(out).length ? [out, ...tail] : tail, xLost, yLost };
|
|
2785
2852
|
}
|
|
2786
2853
|
function transformCellsOverCells(x, y, side) {
|
|
@@ -3869,6 +3936,12 @@ function rebaseSheetUndoStack(items, remote, unitId) {
|
|
|
3869
3936
|
function createSheetsOtAdapter(port, hooks = {}) {
|
|
3870
3937
|
let queue = [];
|
|
3871
3938
|
let draining = false;
|
|
3939
|
+
const sameOp = (a, b) => JSON.stringify(canonicalKeys(a ?? [])) === JSON.stringify(canonicalKeys(b ?? []));
|
|
3940
|
+
const commutesWithHeld = (op) => queue.every((q) => {
|
|
3941
|
+
const a = transformSheetOp(op, q.op, "left");
|
|
3942
|
+
const b = transformSheetOp(q.op, op, "right");
|
|
3943
|
+
return !("barrier" in a) && !("barrier" in b) && sameOp(a.op, op) && sameOp(b.op, q.op);
|
|
3944
|
+
});
|
|
3872
3945
|
const lazy = typeof port.beforeUndo === "function";
|
|
3873
3946
|
let pending = [];
|
|
3874
3947
|
let pendingBase = 0;
|
|
@@ -3941,15 +4014,16 @@ function createSheetsOtAdapter(port, hooks = {}) {
|
|
|
3941
4014
|
decode: decodeSheetOp,
|
|
3942
4015
|
apply(op) {
|
|
3943
4016
|
if (isNoopSheetOp(op)) return true;
|
|
3944
|
-
|
|
3945
|
-
|
|
4017
|
+
const hold = port.busy() || !!port.defers?.(op) || queue.length > 0 && !commutesWithHeld(op);
|
|
4018
|
+
if (hold) {
|
|
4019
|
+
queue.push({ op, rev: hooks.rev?.() ?? 0 });
|
|
3946
4020
|
if (!draining) {
|
|
3947
4021
|
draining = true;
|
|
3948
4022
|
port.whenIdle(() => {
|
|
3949
4023
|
draining = false;
|
|
3950
4024
|
const held = queue;
|
|
3951
4025
|
queue = [];
|
|
3952
|
-
for (const q of held) applyNow(q);
|
|
4026
|
+
for (const q of held) applyNow(q.op);
|
|
3953
4027
|
});
|
|
3954
4028
|
}
|
|
3955
4029
|
return true;
|
|
@@ -3974,9 +4048,9 @@ function createSheetsOtAdapter(port, hooks = {}) {
|
|
|
3974
4048
|
async hash() {
|
|
3975
4049
|
if (port.busy() || queue.length) {
|
|
3976
4050
|
await new Promise((resolve) => {
|
|
3977
|
-
const done = setTimeout(resolve, 5e3);
|
|
4051
|
+
const done = queue.length ? null : setTimeout(resolve, 5e3);
|
|
3978
4052
|
port.whenIdle(() => {
|
|
3979
|
-
clearTimeout(done);
|
|
4053
|
+
if (done) clearTimeout(done);
|
|
3980
4054
|
setTimeout(resolve, 0);
|
|
3981
4055
|
});
|
|
3982
4056
|
});
|
|
@@ -3987,15 +4061,17 @@ function createSheetsOtAdapter(port, hooks = {}) {
|
|
|
3987
4061
|
rebaseLocalOverHeld(local) {
|
|
3988
4062
|
let op = local;
|
|
3989
4063
|
const next = [];
|
|
4064
|
+
const overrode = [];
|
|
3990
4065
|
for (const q of queue) {
|
|
3991
|
-
const l2 = transformSheetOp(op, q, "left");
|
|
3992
|
-
const q2 = transformSheetOp(q, op, "right");
|
|
4066
|
+
const l2 = transformSheetOp(op, q.op, "left");
|
|
4067
|
+
const q2 = transformSheetOp(q.op, op, "right");
|
|
3993
4068
|
if ("barrier" in l2 || "barrier" in q2) return "barrier";
|
|
4069
|
+
if (l2.lost.length && q.rev > 0) overrode.push({ rev: q.rev, lost: l2.lost });
|
|
3994
4070
|
op = l2.op ?? [];
|
|
3995
|
-
if (q2.op?.length) next.push(q2.op);
|
|
4071
|
+
if (q2.op?.length) next.push({ op: q2.op, rev: q.rev });
|
|
3996
4072
|
}
|
|
3997
4073
|
queue = next;
|
|
3998
|
-
return op;
|
|
4074
|
+
return { op, overrode };
|
|
3999
4075
|
},
|
|
4000
4076
|
clearHeld() {
|
|
4001
4077
|
queue = [];
|
|
@@ -4006,7 +4082,6 @@ function createSheetsOtAdapter(port, hooks = {}) {
|
|
|
4006
4082
|
function openSheetsOtRoom(o) {
|
|
4007
4083
|
const { port } = o;
|
|
4008
4084
|
let session = null;
|
|
4009
|
-
const adapter = createSheetsOtAdapter(port);
|
|
4010
4085
|
const notice = (n) => {
|
|
4011
4086
|
try {
|
|
4012
4087
|
o.onNotice?.(n);
|
|
@@ -4014,6 +4089,29 @@ function openSheetsOtRoom(o) {
|
|
|
4014
4089
|
console.warn("[sheets-ot] notice handler failed", err);
|
|
4015
4090
|
}
|
|
4016
4091
|
};
|
|
4092
|
+
const adapter = createSheetsOtAdapter(port, { rev: () => session?.rev() ?? 0 });
|
|
4093
|
+
let healing = null;
|
|
4094
|
+
const HEALS = /* @__PURE__ */ new Set(["hash_mismatch", "save_hash_mismatch", "ack_mismatch"]);
|
|
4095
|
+
const screen = () => {
|
|
4096
|
+
try {
|
|
4097
|
+
const s = port.snapshot();
|
|
4098
|
+
return s ? canonicalSheetString(s) : null;
|
|
4099
|
+
} catch {
|
|
4100
|
+
return null;
|
|
4101
|
+
}
|
|
4102
|
+
};
|
|
4103
|
+
const onIncident = (i) => {
|
|
4104
|
+
if (HEALS.has(i.kind) && !healing) healing = { reason: i.kind, before: screen() };
|
|
4105
|
+
o.onIncident?.(i);
|
|
4106
|
+
};
|
|
4107
|
+
const onStatus = (st) => {
|
|
4108
|
+
if (st === "live" && healing) {
|
|
4109
|
+
const h = healing;
|
|
4110
|
+
healing = null;
|
|
4111
|
+
if (h.before !== null && screen() !== h.before) notice({ kind: "resynced", reason: h.reason });
|
|
4112
|
+
} else if (st === "read_only" || st === "closed") healing = null;
|
|
4113
|
+
o.onStatus?.(st);
|
|
4114
|
+
};
|
|
4017
4115
|
const onLocal = (e) => {
|
|
4018
4116
|
if (!session) return;
|
|
4019
4117
|
if (e.kind === "not_shared") {
|
|
@@ -4033,6 +4131,7 @@ function openSheetsOtRoom(o) {
|
|
|
4033
4131
|
}
|
|
4034
4132
|
let op = e.mutations;
|
|
4035
4133
|
let inverse = e.inverse;
|
|
4134
|
+
let overrode = [];
|
|
4036
4135
|
if (adapter.held()) {
|
|
4037
4136
|
inverse = void 0;
|
|
4038
4137
|
const r = adapter.rebaseLocalOverHeld(op);
|
|
@@ -4041,10 +4140,11 @@ function openSheetsOtRoom(o) {
|
|
|
4041
4140
|
session.rebuild("held_barrier");
|
|
4042
4141
|
return;
|
|
4043
4142
|
}
|
|
4044
|
-
op = r;
|
|
4143
|
+
op = r.op;
|
|
4144
|
+
overrode = r.overrode;
|
|
4045
4145
|
if (!op.length) return;
|
|
4046
4146
|
}
|
|
4047
|
-
if (!session.local(op, { ...inverse !== void 0 ? { inverse } : {}, label: e.label ?? SHEETS_EDIT_GROUP })) notice({ kind: "not_live" });
|
|
4147
|
+
if (!session.local(op, { ...inverse !== void 0 ? { inverse } : {}, label: e.label ?? SHEETS_EDIT_GROUP, ...overrode.length ? { overrode } : {} })) notice({ kind: "not_live" });
|
|
4048
4148
|
};
|
|
4049
4149
|
const unsubLocal = port.onLocal(onLocal);
|
|
4050
4150
|
session = openOpSession2({
|
|
@@ -4054,8 +4154,8 @@ function openSheetsOtRoom(o) {
|
|
|
4054
4154
|
clientId: o.clientId,
|
|
4055
4155
|
...o.presence ? { presence: o.presence } : {},
|
|
4056
4156
|
onNotice: (n) => notice(n),
|
|
4057
|
-
|
|
4058
|
-
|
|
4157
|
+
onIncident,
|
|
4158
|
+
onStatus,
|
|
4059
4159
|
...o.offline ? { offline: o.offline } : {},
|
|
4060
4160
|
...o.onOffline ? { onOffline: o.onOffline } : {}
|
|
4061
4161
|
});
|
|
@@ -4148,6 +4248,23 @@ function releaseUnitPluginState(cs, unitId, saved) {
|
|
|
4148
4248
|
}
|
|
4149
4249
|
|
|
4150
4250
|
// src/univer/collab/sheets-ot/univer-port.ts
|
|
4251
|
+
function filterServiceRange(service) {
|
|
4252
|
+
return (unitId, subUnitId) => {
|
|
4253
|
+
try {
|
|
4254
|
+
const r = service()?.getFilterModel(unitId, subUnitId)?.getRange();
|
|
4255
|
+
return r ? { startRow: r.startRow, endRow: r.endRow, startColumn: r.startColumn, endColumn: r.endColumn, ...r.rangeType !== void 0 ? { rangeType: r.rangeType } : {} } : null;
|
|
4256
|
+
} catch {
|
|
4257
|
+
return null;
|
|
4258
|
+
}
|
|
4259
|
+
};
|
|
4260
|
+
}
|
|
4261
|
+
function editorBridgeCell(bridge) {
|
|
4262
|
+
return () => {
|
|
4263
|
+
if (!bridge.isVisible()?.visible) return null;
|
|
4264
|
+
const at = bridge.getEditLocation();
|
|
4265
|
+
return at ? { sheetId: at.sheetId, row: at.row, col: at.column } : null;
|
|
4266
|
+
};
|
|
4267
|
+
}
|
|
4151
4268
|
var COMMAND = 0;
|
|
4152
4269
|
var MUTATION = 2;
|
|
4153
4270
|
var VALUES = "sheet.mutation.set-range-values";
|
|
@@ -4155,6 +4272,7 @@ var ADD_MERGE = "sheet.mutation.add-worksheet-merge";
|
|
|
4155
4272
|
var REMOVE_MERGE = "sheet.mutation.remove-worksheet-merge";
|
|
4156
4273
|
var SHEET_NAME = "sheet.mutation.set-worksheet-name";
|
|
4157
4274
|
var INSERT_SHEET = "sheet.mutation.insert-sheet";
|
|
4275
|
+
var REMOVE_SHEET2 = "sheet.mutation.remove-sheet";
|
|
4158
4276
|
var FILTER_RANGE = "sheet.mutation.set-filter-range";
|
|
4159
4277
|
var RESHAPE = /* @__PURE__ */ new Set(["sheet.mutation.set-worksheet-row-count", "sheet.mutation.set-worksheet-column-count", "sheet.mutation.remove-sheet", INSERT_SHEET]);
|
|
4160
4278
|
var UNDO = "univer.command.undo";
|
|
@@ -4174,6 +4292,18 @@ function univerSheetsOtPort(o) {
|
|
|
4174
4292
|
const tracker = { stack: [], settle: () => settle() };
|
|
4175
4293
|
let group = null;
|
|
4176
4294
|
let applying = false;
|
|
4295
|
+
let editorHold = false;
|
|
4296
|
+
const edited = () => {
|
|
4297
|
+
try {
|
|
4298
|
+
return o.cellEditor?.() ?? null;
|
|
4299
|
+
} catch {
|
|
4300
|
+
return null;
|
|
4301
|
+
}
|
|
4302
|
+
};
|
|
4303
|
+
const holding = () => {
|
|
4304
|
+
if (editorHold && !edited()) editorHold = false;
|
|
4305
|
+
return editorHold;
|
|
4306
|
+
};
|
|
4177
4307
|
const unitId = () => o.workbook()?.getUnitId() ?? null;
|
|
4178
4308
|
const mine = (params) => {
|
|
4179
4309
|
const u = unitId();
|
|
@@ -4202,7 +4332,7 @@ function univerSheetsOtPort(o) {
|
|
|
4202
4332
|
if (!u || !o.filterRange) return null;
|
|
4203
4333
|
try {
|
|
4204
4334
|
const r = o.filterRange(u, sheet);
|
|
4205
|
-
return r ? { startRow: r.startRow, endRow: r.endRow, startColumn: r.startColumn, endColumn: r.endColumn } : null;
|
|
4335
|
+
return r ? { startRow: r.startRow, endRow: r.endRow, startColumn: r.startColumn, endColumn: r.endColumn, ...r.rangeType !== void 0 ? { rangeType: r.rangeType } : {} } : null;
|
|
4206
4336
|
} catch {
|
|
4207
4337
|
return null;
|
|
4208
4338
|
}
|
|
@@ -4218,10 +4348,45 @@ function univerSheetsOtPort(o) {
|
|
|
4218
4348
|
}
|
|
4219
4349
|
}
|
|
4220
4350
|
};
|
|
4351
|
+
const sweepRemovedSheetRefs = (g) => {
|
|
4352
|
+
const removed = g.mutations.filter((m) => m.id === REMOVE_SHEET2).map((m) => String(m.params.subUnitId ?? ""));
|
|
4353
|
+
const wb = o.workbook();
|
|
4354
|
+
const u = unitId();
|
|
4355
|
+
if (!removed.length || !wb || !u) return;
|
|
4356
|
+
const refSheets = {};
|
|
4357
|
+
for (const [id, name] of Object.entries(g.sheets)) refSheets[name] = id;
|
|
4358
|
+
for (const gone of removed) {
|
|
4359
|
+
const name = g.sheets[gone];
|
|
4360
|
+
if (!name) continue;
|
|
4361
|
+
for (const ws of wb.getSheets()) {
|
|
4362
|
+
const sheet = ws.getSheetId();
|
|
4363
|
+
const cells = {};
|
|
4364
|
+
ws.getCellMatrix?.().forValue((r, c, cell) => {
|
|
4365
|
+
const f = cell?.f;
|
|
4366
|
+
if (typeof f !== "string" || !f.includes(name)) return;
|
|
4367
|
+
const out = rewriteFormula(f, { ownSheet: sheet, refSheets }, { kind: "remove-sheet", sheet: gone });
|
|
4368
|
+
if (typeof out !== "string" && out.changed) (cells[r] ??= {})[c] = { f: out.text, si: null };
|
|
4369
|
+
});
|
|
4370
|
+
if (!Object.keys(cells).length) continue;
|
|
4371
|
+
applying = true;
|
|
4372
|
+
try {
|
|
4373
|
+
cs.syncExecuteCommand(VALUES, { unitId: u, subUnitId: sheet, cellValue: json(cells) });
|
|
4374
|
+
} finally {
|
|
4375
|
+
applying = false;
|
|
4376
|
+
}
|
|
4377
|
+
const done = {};
|
|
4378
|
+
for (const r of Object.keys(cells))
|
|
4379
|
+
for (const c of Object.keys(cells[r])) (done[r] ??= {})[c] = completeCellContent(cells[r][c], json(ws.getCellRaw(Number(r), Number(c)) ?? null));
|
|
4380
|
+
g.mutations.push({ id: VALUES, params: { subUnitId: sheet, cellValue: done } });
|
|
4381
|
+
g.inverses.push(void 0);
|
|
4382
|
+
}
|
|
4383
|
+
}
|
|
4384
|
+
};
|
|
4221
4385
|
const flush = () => {
|
|
4222
4386
|
const g = group;
|
|
4223
4387
|
group = null;
|
|
4224
4388
|
if (!g) return;
|
|
4389
|
+
if (!g.notShared) sweepRemovedSheetRefs(g);
|
|
4225
4390
|
if (g.notShared) emit({ kind: "not_shared", mutationId: g.notShared, label: g.label });
|
|
4226
4391
|
else if (g.mutations.length) {
|
|
4227
4392
|
const mutations = annotateSheetOps(annotateFormulas(g.mutations, g.sheets, g.names), g.order);
|
|
@@ -4233,7 +4398,7 @@ function univerSheetsOtPort(o) {
|
|
|
4233
4398
|
};
|
|
4234
4399
|
function settle() {
|
|
4235
4400
|
if (tracker.stack.length === 0) flush();
|
|
4236
|
-
if (tracker.stack.length === 0 && !group) for (const fn of idle.splice(0)) fn();
|
|
4401
|
+
if (tracker.stack.length === 0 && !group && !holding()) for (const fn of idle.splice(0)) fn();
|
|
4237
4402
|
}
|
|
4238
4403
|
const before = cs.beforeCommandExecuted((info, options) => {
|
|
4239
4404
|
if (info.id === UNDO || info.id === REDO) for (const fn of [...undoWatchers]) fn();
|
|
@@ -4247,6 +4412,7 @@ function univerSheetsOtPort(o) {
|
|
|
4247
4412
|
const ws = o.workbook()?.getSheetBySheetId(String(p.subUnitId ?? ""));
|
|
4248
4413
|
if (!ws) return;
|
|
4249
4414
|
const record = { merges: json(ws.getMergeData() ?? []) };
|
|
4415
|
+
if (!group) record.lone = openGroup(null);
|
|
4250
4416
|
if (info.id === VALUES) {
|
|
4251
4417
|
record.cells = /* @__PURE__ */ new Map();
|
|
4252
4418
|
const cells = p.cellValue ?? {};
|
|
@@ -4283,6 +4449,7 @@ function univerSheetsOtPort(o) {
|
|
|
4283
4449
|
}
|
|
4284
4450
|
};
|
|
4285
4451
|
const after = cs.onCommandExecuted((info) => {
|
|
4452
|
+
if (editorHold && tracker.stack.length === 0 && !group && !edited()) settle();
|
|
4286
4453
|
if (info.type !== COMMAND) return;
|
|
4287
4454
|
const at = tracker.stack.lastIndexOf(info.id);
|
|
4288
4455
|
if (at >= 0) tracker.stack.splice(at, 1);
|
|
@@ -4364,7 +4531,7 @@ function univerSheetsOtPort(o) {
|
|
|
4364
4531
|
else {
|
|
4365
4532
|
inv = {};
|
|
4366
4533
|
if (CONTENT_KEYS.some((k) => k !== "t" && k in done)) Object.assign(inv, fullContent(p));
|
|
4367
|
-
if ("s" in done) inv.s = p?.s
|
|
4534
|
+
if ("s" in done) inv.s = inverseStyle(p?.s, done.s);
|
|
4368
4535
|
}
|
|
4369
4536
|
(invCells[r] ??= {})[c] = inv;
|
|
4370
4537
|
}
|
|
@@ -4402,7 +4569,7 @@ function univerSheetsOtPort(o) {
|
|
|
4402
4569
|
};
|
|
4403
4570
|
const collab = cs.onMutationExecutedForCollab((info, options) => {
|
|
4404
4571
|
if (applying || flagged(options) || !mine(info.params)) return;
|
|
4405
|
-
if (!group) group = openGroup(null);
|
|
4572
|
+
if (!group) group = pre.get(info.params)?.lone ?? openGroup(null);
|
|
4406
4573
|
const g = group;
|
|
4407
4574
|
if (!g.notShared) {
|
|
4408
4575
|
const r = capture(info);
|
|
@@ -4483,11 +4650,18 @@ function univerSheetsOtPort(o) {
|
|
|
4483
4650
|
listeners.add(listener);
|
|
4484
4651
|
return () => void listeners.delete(listener);
|
|
4485
4652
|
},
|
|
4653
|
+
// the editor hold is not "busy": only the ops that touch its cell wait (defers), the rest apply live
|
|
4486
4654
|
busy: () => tracker.stack.length > 0 || group !== null,
|
|
4655
|
+
defers(op) {
|
|
4656
|
+
const at = edited();
|
|
4657
|
+
if (!at || !op.some((m) => touchesEditedCell(m, at))) return false;
|
|
4658
|
+
editorHold = true;
|
|
4659
|
+
return true;
|
|
4660
|
+
},
|
|
4487
4661
|
/** The outermost commands still running here (why the port is busy), for logs. */
|
|
4488
4662
|
running: () => [...tracker.stack, ...group && tracker.stack.length === 0 ? ["(group)"] : []],
|
|
4489
4663
|
whenIdle(fn) {
|
|
4490
|
-
if (tracker.stack.length === 0 && !group) fn();
|
|
4664
|
+
if (tracker.stack.length === 0 && !group && !holding()) fn();
|
|
4491
4665
|
else idle.push(fn);
|
|
4492
4666
|
},
|
|
4493
4667
|
applyRemote(m) {
|
|
@@ -4547,6 +4721,55 @@ function univerSheetsOtPort(o) {
|
|
|
4547
4721
|
}
|
|
4548
4722
|
};
|
|
4549
4723
|
}
|
|
4724
|
+
function inverseStyle(prev, wrote) {
|
|
4725
|
+
if (!prev || typeof prev !== "object") return null;
|
|
4726
|
+
if (!wrote || typeof wrote !== "object") return prev;
|
|
4727
|
+
const out = { ...prev };
|
|
4728
|
+
for (const k of Object.keys(wrote)) if (!(k in out)) out[k] = null;
|
|
4729
|
+
return out;
|
|
4730
|
+
}
|
|
4731
|
+
function touchesEditedCell(m, at) {
|
|
4732
|
+
const p = m.params;
|
|
4733
|
+
const sheet = String(p.subUnitId ?? p.sheetId ?? "");
|
|
4734
|
+
if (sheet !== at.sheetId) return false;
|
|
4735
|
+
if (m.id === VALUES) {
|
|
4736
|
+
const row = p.cellValue?.[at.row];
|
|
4737
|
+
return !!row && Object.prototype.hasOwnProperty.call(row, at.col);
|
|
4738
|
+
}
|
|
4739
|
+
if (m.id === REMOVE_SHEET2) return true;
|
|
4740
|
+
if (m.id === "sheet.mutation.set-worksheet-row-count") return !(Number(p.rowCount) > at.row);
|
|
4741
|
+
if (m.id === "sheet.mutation.set-worksheet-column-count") return !(Number(p.columnCount) > at.col);
|
|
4742
|
+
const axis = axisOpOf(m);
|
|
4743
|
+
if (axis) {
|
|
4744
|
+
const i = axis.axis === "row" ? at.row : at.col;
|
|
4745
|
+
return mapIndex(axis.op, i) !== i;
|
|
4746
|
+
}
|
|
4747
|
+
const ranges = [];
|
|
4748
|
+
let unreadable = false;
|
|
4749
|
+
const walk = (v, depth) => {
|
|
4750
|
+
if (!v || typeof v !== "object" || depth > 6) return;
|
|
4751
|
+
if (Array.isArray(v)) {
|
|
4752
|
+
for (const x of v) walk(x, depth + 1);
|
|
4753
|
+
return;
|
|
4754
|
+
}
|
|
4755
|
+
const o = v;
|
|
4756
|
+
if (["startRow", "endRow", "startColumn", "endColumn"].some((k) => k in o)) {
|
|
4757
|
+
const r = o;
|
|
4758
|
+
if (![r.startRow, r.endRow, r.startColumn, r.endColumn].every((n) => typeof n === "number" && Number.isFinite(n)) && !(r.rangeType && r.rangeType > 0)) unreadable = true;
|
|
4759
|
+
else ranges.push(r);
|
|
4760
|
+
return;
|
|
4761
|
+
}
|
|
4762
|
+
if (typeof o.row === "number" && typeof o.col === "number") ranges.push({ startRow: o.row, endRow: o.row, startColumn: o.col, endColumn: o.col });
|
|
4763
|
+
for (const x of Object.values(o)) walk(x, depth + 1);
|
|
4764
|
+
};
|
|
4765
|
+
walk(p, 0);
|
|
4766
|
+
return unreadable || ranges.some((r) => covers(r, at));
|
|
4767
|
+
}
|
|
4768
|
+
function covers(r, at) {
|
|
4769
|
+
const rows = r.rangeType === 2 || r.rangeType === 3 || r.startRow <= at.row && at.row <= r.endRow;
|
|
4770
|
+
const cols = r.rangeType === 1 || r.rangeType === 3 || r.startColumn <= at.col && at.col <= r.endColumn;
|
|
4771
|
+
return rows && cols;
|
|
4772
|
+
}
|
|
4550
4773
|
function fullContent(cell) {
|
|
4551
4774
|
const out = {};
|
|
4552
4775
|
for (const k of CONTENT_KEYS) out[k] = cell && cell[k] !== void 0 ? cell[k] : null;
|
|
@@ -4857,6 +5080,7 @@ export {
|
|
|
4857
5080
|
DOCS_COLLAB_PROTO,
|
|
4858
5081
|
DOCS_TRANSFORM_VERSION,
|
|
4859
5082
|
DOC_LOCAL_KEYS,
|
|
5083
|
+
REDO_COMMAND,
|
|
4860
5084
|
RICH_TEXT_EDITING,
|
|
4861
5085
|
SENDER_VIEW_PARAMS,
|
|
4862
5086
|
SHEETS_COLLAB_PROTO,
|
|
@@ -4864,6 +5088,7 @@ export {
|
|
|
4864
5088
|
SHEETS_READABLE_PROTOS,
|
|
4865
5089
|
SHEET_ROOM_EDITOR_PRESETS,
|
|
4866
5090
|
SHEET_ROOM_PLUGIN_PACKAGES,
|
|
5091
|
+
UNDO_COMMAND,
|
|
4867
5092
|
WorkbookCollabSession,
|
|
4868
5093
|
applyDocsOp,
|
|
4869
5094
|
asLoadedDocsSnapshot,
|
|
@@ -4879,7 +5104,9 @@ export {
|
|
|
4879
5104
|
documentOtFactory,
|
|
4880
5105
|
documentUsesOrderedRoom,
|
|
4881
5106
|
dropEmptyStyleRetains,
|
|
5107
|
+
editorBridgeCell,
|
|
4882
5108
|
encodeSheetOp,
|
|
5109
|
+
filterServiceRange,
|
|
4883
5110
|
invertDocsOp,
|
|
4884
5111
|
isCellEditorScratch,
|
|
4885
5112
|
isNoopDocsOp,
|
|
@@ -4897,6 +5124,7 @@ export {
|
|
|
4897
5124
|
startWorkbookOtRoom,
|
|
4898
5125
|
stripSenderView,
|
|
4899
5126
|
takeCovered,
|
|
5127
|
+
touchesEditedCell,
|
|
4900
5128
|
transformDocsOp,
|
|
4901
5129
|
transformSheetOp,
|
|
4902
5130
|
transformTextX,
|