@ai-matrx/office 0.8.44 → 0.8.45
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 +17 -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/univer-collab.cjs +196 -15
- package/dist/univer-collab.cjs.map +1 -1
- package/dist/univer-collab.d.cts +68 -7
- package/dist/univer-collab.d.ts +68 -7
- package/dist/univer-collab.js +196 -15
- package/dist/univer-collab.js.map +1 -1
- package/package.json +6 -5
package/dist/univer-collab.cjs
CHANGED
|
@@ -35,6 +35,7 @@ __export(collab_exports, {
|
|
|
35
35
|
DOCS_COLLAB_PROTO: () => DOCS_COLLAB_PROTO,
|
|
36
36
|
DOCS_TRANSFORM_VERSION: () => DOCS_TRANSFORM_VERSION,
|
|
37
37
|
DOC_LOCAL_KEYS: () => DOC_LOCAL_KEYS,
|
|
38
|
+
REDO_COMMAND: () => REDO_COMMAND,
|
|
38
39
|
RICH_TEXT_EDITING: () => RICH_TEXT_EDITING,
|
|
39
40
|
SENDER_VIEW_PARAMS: () => SENDER_VIEW_PARAMS,
|
|
40
41
|
SHEETS_COLLAB_PROTO: () => SHEETS_COLLAB_PROTO,
|
|
@@ -42,6 +43,7 @@ __export(collab_exports, {
|
|
|
42
43
|
SHEETS_READABLE_PROTOS: () => SHEETS_READABLE_PROTOS,
|
|
43
44
|
SHEET_ROOM_EDITOR_PRESETS: () => SHEET_ROOM_EDITOR_PRESETS,
|
|
44
45
|
SHEET_ROOM_PLUGIN_PACKAGES: () => SHEET_ROOM_PLUGIN_PACKAGES,
|
|
46
|
+
UNDO_COMMAND: () => UNDO_COMMAND,
|
|
45
47
|
WorkbookCollabSession: () => WorkbookCollabSession,
|
|
46
48
|
applyDocsOp: () => applyDocsOp,
|
|
47
49
|
asLoadedDocsSnapshot: () => asLoadedDocsSnapshot,
|
|
@@ -57,7 +59,9 @@ __export(collab_exports, {
|
|
|
57
59
|
documentOtFactory: () => documentOtFactory,
|
|
58
60
|
documentUsesOrderedRoom: () => documentUsesOrderedRoom,
|
|
59
61
|
dropEmptyStyleRetains: () => dropEmptyStyleRetains,
|
|
62
|
+
editorBridgeCell: () => editorBridgeCell,
|
|
60
63
|
encodeSheetOp: () => encodeSheetOp,
|
|
64
|
+
filterServiceRange: () => filterServiceRange,
|
|
61
65
|
invertDocsOp: () => invertDocsOp,
|
|
62
66
|
isCellEditorScratch: () => isCellEditorScratch,
|
|
63
67
|
isNoopDocsOp: () => isNoopDocsOp,
|
|
@@ -1249,26 +1253,77 @@ function rebaseUndoStack(items, remote, stack) {
|
|
|
1249
1253
|
const first = stack === "undo" ? "undoMutations" : "redoMutations";
|
|
1250
1254
|
const second = stack === "undo" ? "redoMutations" : "undoMutations";
|
|
1251
1255
|
let dropped = 0;
|
|
1252
|
-
|
|
1256
|
+
let R = remote;
|
|
1257
|
+
for (let i = items.length - 1; i >= 0 && !isNoopDocsOp(R); i--) {
|
|
1253
1258
|
const item = items[i];
|
|
1254
1259
|
try {
|
|
1255
|
-
const a = threadThrough(item[first],
|
|
1260
|
+
const a = threadThrough(item[first], R);
|
|
1256
1261
|
const b = threadThrough(item[second], a.after);
|
|
1257
1262
|
if (a.next) item[first] = a.next;
|
|
1258
1263
|
if (b.next) item[second] = b.next;
|
|
1264
|
+
R = a.after;
|
|
1259
1265
|
} catch {
|
|
1260
1266
|
items.splice(i, 1);
|
|
1261
1267
|
dropped++;
|
|
1268
|
+
R = carryPast(item[first], R);
|
|
1262
1269
|
}
|
|
1263
1270
|
}
|
|
1264
1271
|
return dropped;
|
|
1265
1272
|
}
|
|
1273
|
+
function carryPast(list, remote) {
|
|
1274
|
+
let R = remote;
|
|
1275
|
+
for (const m of list ?? []) {
|
|
1276
|
+
if (m.id !== RICH_TEXT_EDITING || isNoopDocsOp(R)) continue;
|
|
1277
|
+
const own = m.params.actions;
|
|
1278
|
+
if (touchesPageSetup(own) && touchesPageSetup(R)) continue;
|
|
1279
|
+
R = transformDocsOp(R, own, "right").op;
|
|
1280
|
+
}
|
|
1281
|
+
return R;
|
|
1282
|
+
}
|
|
1283
|
+
var UNDO_COMMAND = "univer.command.undo";
|
|
1284
|
+
var REDO_COMMAND = "univer.command.redo";
|
|
1266
1285
|
function openDocsOtRoom(o) {
|
|
1267
1286
|
const { port } = o;
|
|
1268
1287
|
let session = null;
|
|
1269
1288
|
let composing = false;
|
|
1270
1289
|
let queue = [];
|
|
1271
1290
|
const drainWaiters = [];
|
|
1291
|
+
let replay = null;
|
|
1292
|
+
const noteHistoryStep = (m, inverse) => {
|
|
1293
|
+
const side = m.cmd === UNDO_COMMAND ? "undo" : m.cmd === REDO_COMMAND ? "redo" : null;
|
|
1294
|
+
if (!side) {
|
|
1295
|
+
replay = null;
|
|
1296
|
+
return;
|
|
1297
|
+
}
|
|
1298
|
+
for (const t of port.undoTargets()) {
|
|
1299
|
+
const stacks = undoStacksOf(t.service);
|
|
1300
|
+
const stack = stacks ? (side === "undo" ? stacks.undo : stacks.redo).get(t.unitId) : void 0;
|
|
1301
|
+
const item = stack?.[stack.length - 1];
|
|
1302
|
+
const list = item ? side === "undo" ? item.undoMutations : item.redoMutations : void 0;
|
|
1303
|
+
const k = list ? list.findIndex((x) => x.params === m.params) : -1;
|
|
1304
|
+
if (!item || !list || k < 0) continue;
|
|
1305
|
+
if (k === 0 || !replay || replay.item !== item || replay.side !== side) {
|
|
1306
|
+
const other = (side === "undo" ? item.redoMutations : item.undoMutations)?.[0]?.params ?? {};
|
|
1307
|
+
const { textRanges: _t, layoutState: _l, actions: _a, ...template } = other;
|
|
1308
|
+
replay = { item, side, inverses: [], template };
|
|
1309
|
+
}
|
|
1310
|
+
if (inverse === void 0 || list.some((x) => x.id !== RICH_TEXT_EDITING)) {
|
|
1311
|
+
replay = null;
|
|
1312
|
+
return;
|
|
1313
|
+
}
|
|
1314
|
+
replay.inverses.unshift(inverse);
|
|
1315
|
+
if (k === list.length - 1) {
|
|
1316
|
+
const rewritten = replay.inverses.filter((op) => !isNoopDocsOp(op)).map((op) => ({ id: RICH_TEXT_EDITING, params: { ...replay.template, segmentId: m.params?.segmentId ?? "", actions: op } }));
|
|
1317
|
+
if (rewritten.length) {
|
|
1318
|
+
if (side === "undo") item.redoMutations = rewritten;
|
|
1319
|
+
else item.undoMutations = rewritten;
|
|
1320
|
+
}
|
|
1321
|
+
replay = null;
|
|
1322
|
+
}
|
|
1323
|
+
return;
|
|
1324
|
+
}
|
|
1325
|
+
replay = null;
|
|
1326
|
+
};
|
|
1272
1327
|
const notice = (n) => {
|
|
1273
1328
|
try {
|
|
1274
1329
|
o.onNotice?.(n);
|
|
@@ -1366,7 +1421,10 @@ function openDocsOtRoom(o) {
|
|
|
1366
1421
|
}
|
|
1367
1422
|
const p = m.params ?? {};
|
|
1368
1423
|
const applied = p.actions ?? null;
|
|
1369
|
-
if (isNoopDocsOp(applied))
|
|
1424
|
+
if (isNoopDocsOp(applied)) {
|
|
1425
|
+
noteHistoryStep(m, null);
|
|
1426
|
+
return;
|
|
1427
|
+
}
|
|
1370
1428
|
let op = normalizeDocsOp(structuredClone(applied));
|
|
1371
1429
|
let inverse;
|
|
1372
1430
|
try {
|
|
@@ -1374,6 +1432,7 @@ function openDocsOtRoom(o) {
|
|
|
1374
1432
|
} catch {
|
|
1375
1433
|
inverse = void 0;
|
|
1376
1434
|
}
|
|
1435
|
+
noteHistoryStep(m, inverse === void 0 ? void 0 : normalizeDocsOp(inverse));
|
|
1377
1436
|
if (queue.length) {
|
|
1378
1437
|
inverse = void 0;
|
|
1379
1438
|
const next = [];
|
|
@@ -2846,6 +2905,18 @@ function transformCell(X, Y4, side) {
|
|
|
2846
2905
|
if (styleKeys(xs).length !== styleKeys(kept ?? {}).length) xLost = true;
|
|
2847
2906
|
}
|
|
2848
2907
|
}
|
|
2908
|
+
if (hasContent(X) && hasContent(Y4)) {
|
|
2909
|
+
const has = (s) => !!s && typeof s === "object" && "n" in s;
|
|
2910
|
+
const outS = out.s;
|
|
2911
|
+
if (side === "left" && !has(X.s) && has(Y4.s) && X.s !== null) {
|
|
2912
|
+
out.s = { ...outS && typeof outS === "object" ? outS : {}, n: null };
|
|
2913
|
+
} else if (side === "right" && outS && typeof outS === "object" && "n" in outS) {
|
|
2914
|
+
const rest = withoutStyleKeys(outS, /* @__PURE__ */ new Set(["n"]));
|
|
2915
|
+
if (rest) out.s = rest;
|
|
2916
|
+
else delete out.s;
|
|
2917
|
+
xLost = true;
|
|
2918
|
+
}
|
|
2919
|
+
}
|
|
2849
2920
|
return { entries: Object.keys(out).length ? [out, ...tail] : tail, xLost, yLost };
|
|
2850
2921
|
}
|
|
2851
2922
|
function transformCellsOverCells(x, y, side) {
|
|
@@ -4006,7 +4077,7 @@ function createSheetsOtAdapter(port, hooks = {}) {
|
|
|
4006
4077
|
decode: decodeSheetOp,
|
|
4007
4078
|
apply(op) {
|
|
4008
4079
|
if (isNoopSheetOp(op)) return true;
|
|
4009
|
-
if (port.busy() || queue.length) {
|
|
4080
|
+
if (port.busy() || queue.length || port.defers?.(op)) {
|
|
4010
4081
|
queue.push(op);
|
|
4011
4082
|
if (!draining) {
|
|
4012
4083
|
draining = true;
|
|
@@ -4039,9 +4110,9 @@ function createSheetsOtAdapter(port, hooks = {}) {
|
|
|
4039
4110
|
async hash() {
|
|
4040
4111
|
if (port.busy() || queue.length) {
|
|
4041
4112
|
await new Promise((resolve) => {
|
|
4042
|
-
const done = setTimeout(resolve, 5e3);
|
|
4113
|
+
const done = queue.length ? null : setTimeout(resolve, 5e3);
|
|
4043
4114
|
port.whenIdle(() => {
|
|
4044
|
-
clearTimeout(done);
|
|
4115
|
+
if (done) clearTimeout(done);
|
|
4045
4116
|
setTimeout(resolve, 0);
|
|
4046
4117
|
});
|
|
4047
4118
|
});
|
|
@@ -4071,7 +4142,6 @@ function createSheetsOtAdapter(port, hooks = {}) {
|
|
|
4071
4142
|
function openSheetsOtRoom(o) {
|
|
4072
4143
|
const { port } = o;
|
|
4073
4144
|
let session = null;
|
|
4074
|
-
const adapter = createSheetsOtAdapter(port);
|
|
4075
4145
|
const notice = (n) => {
|
|
4076
4146
|
try {
|
|
4077
4147
|
o.onNotice?.(n);
|
|
@@ -4079,6 +4149,29 @@ function openSheetsOtRoom(o) {
|
|
|
4079
4149
|
console.warn("[sheets-ot] notice handler failed", err);
|
|
4080
4150
|
}
|
|
4081
4151
|
};
|
|
4152
|
+
const adapter = createSheetsOtAdapter(port);
|
|
4153
|
+
let healing = null;
|
|
4154
|
+
const HEALS = /* @__PURE__ */ new Set(["hash_mismatch", "save_hash_mismatch", "ack_mismatch"]);
|
|
4155
|
+
const screen = () => {
|
|
4156
|
+
try {
|
|
4157
|
+
const s = port.snapshot();
|
|
4158
|
+
return s ? canonicalSheetString(s) : null;
|
|
4159
|
+
} catch {
|
|
4160
|
+
return null;
|
|
4161
|
+
}
|
|
4162
|
+
};
|
|
4163
|
+
const onIncident = (i) => {
|
|
4164
|
+
if (HEALS.has(i.kind) && !healing) healing = { reason: i.kind, before: screen() };
|
|
4165
|
+
o.onIncident?.(i);
|
|
4166
|
+
};
|
|
4167
|
+
const onStatus = (st) => {
|
|
4168
|
+
if (st === "live" && healing) {
|
|
4169
|
+
const h = healing;
|
|
4170
|
+
healing = null;
|
|
4171
|
+
if (h.before !== null && screen() !== h.before) notice({ kind: "resynced", reason: h.reason });
|
|
4172
|
+
} else if (st === "read_only" || st === "closed") healing = null;
|
|
4173
|
+
o.onStatus?.(st);
|
|
4174
|
+
};
|
|
4082
4175
|
const onLocal = (e) => {
|
|
4083
4176
|
if (!session) return;
|
|
4084
4177
|
if (e.kind === "not_shared") {
|
|
@@ -4119,8 +4212,8 @@ function openSheetsOtRoom(o) {
|
|
|
4119
4212
|
clientId: o.clientId,
|
|
4120
4213
|
...o.presence ? { presence: o.presence } : {},
|
|
4121
4214
|
onNotice: (n) => notice(n),
|
|
4122
|
-
|
|
4123
|
-
|
|
4215
|
+
onIncident,
|
|
4216
|
+
onStatus,
|
|
4124
4217
|
...o.offline ? { offline: o.offline } : {},
|
|
4125
4218
|
...o.onOffline ? { onOffline: o.onOffline } : {}
|
|
4126
4219
|
});
|
|
@@ -4213,6 +4306,23 @@ function releaseUnitPluginState(cs, unitId, saved) {
|
|
|
4213
4306
|
}
|
|
4214
4307
|
|
|
4215
4308
|
// src/univer/collab/sheets-ot/univer-port.ts
|
|
4309
|
+
function filterServiceRange(service) {
|
|
4310
|
+
return (unitId, subUnitId) => {
|
|
4311
|
+
try {
|
|
4312
|
+
const r = service()?.getFilterModel(unitId, subUnitId)?.getRange();
|
|
4313
|
+
return r ? { startRow: r.startRow, endRow: r.endRow, startColumn: r.startColumn, endColumn: r.endColumn, ...r.rangeType !== void 0 ? { rangeType: r.rangeType } : {} } : null;
|
|
4314
|
+
} catch {
|
|
4315
|
+
return null;
|
|
4316
|
+
}
|
|
4317
|
+
};
|
|
4318
|
+
}
|
|
4319
|
+
function editorBridgeCell(bridge) {
|
|
4320
|
+
return () => {
|
|
4321
|
+
if (!bridge.isVisible()?.visible) return null;
|
|
4322
|
+
const at = bridge.getEditLocation();
|
|
4323
|
+
return at ? { sheetId: at.sheetId, row: at.row, col: at.column } : null;
|
|
4324
|
+
};
|
|
4325
|
+
}
|
|
4216
4326
|
var COMMAND = 0;
|
|
4217
4327
|
var MUTATION = 2;
|
|
4218
4328
|
var VALUES = "sheet.mutation.set-range-values";
|
|
@@ -4220,6 +4330,7 @@ var ADD_MERGE = "sheet.mutation.add-worksheet-merge";
|
|
|
4220
4330
|
var REMOVE_MERGE = "sheet.mutation.remove-worksheet-merge";
|
|
4221
4331
|
var SHEET_NAME = "sheet.mutation.set-worksheet-name";
|
|
4222
4332
|
var INSERT_SHEET = "sheet.mutation.insert-sheet";
|
|
4333
|
+
var REMOVE_SHEET2 = "sheet.mutation.remove-sheet";
|
|
4223
4334
|
var FILTER_RANGE = "sheet.mutation.set-filter-range";
|
|
4224
4335
|
var RESHAPE = /* @__PURE__ */ new Set(["sheet.mutation.set-worksheet-row-count", "sheet.mutation.set-worksheet-column-count", "sheet.mutation.remove-sheet", INSERT_SHEET]);
|
|
4225
4336
|
var UNDO = "univer.command.undo";
|
|
@@ -4239,6 +4350,18 @@ function univerSheetsOtPort(o) {
|
|
|
4239
4350
|
const tracker = { stack: [], settle: () => settle() };
|
|
4240
4351
|
let group = null;
|
|
4241
4352
|
let applying = false;
|
|
4353
|
+
let editorHold = false;
|
|
4354
|
+
const edited = () => {
|
|
4355
|
+
try {
|
|
4356
|
+
return o.cellEditor?.() ?? null;
|
|
4357
|
+
} catch {
|
|
4358
|
+
return null;
|
|
4359
|
+
}
|
|
4360
|
+
};
|
|
4361
|
+
const holding = () => {
|
|
4362
|
+
if (editorHold && !edited()) editorHold = false;
|
|
4363
|
+
return editorHold;
|
|
4364
|
+
};
|
|
4242
4365
|
const unitId = () => o.workbook()?.getUnitId() ?? null;
|
|
4243
4366
|
const mine = (params) => {
|
|
4244
4367
|
const u = unitId();
|
|
@@ -4267,7 +4390,7 @@ function univerSheetsOtPort(o) {
|
|
|
4267
4390
|
if (!u || !o.filterRange) return null;
|
|
4268
4391
|
try {
|
|
4269
4392
|
const r = o.filterRange(u, sheet);
|
|
4270
|
-
return r ? { startRow: r.startRow, endRow: r.endRow, startColumn: r.startColumn, endColumn: r.endColumn } : null;
|
|
4393
|
+
return r ? { startRow: r.startRow, endRow: r.endRow, startColumn: r.startColumn, endColumn: r.endColumn, ...r.rangeType !== void 0 ? { rangeType: r.rangeType } : {} } : null;
|
|
4271
4394
|
} catch {
|
|
4272
4395
|
return null;
|
|
4273
4396
|
}
|
|
@@ -4283,10 +4406,45 @@ function univerSheetsOtPort(o) {
|
|
|
4283
4406
|
}
|
|
4284
4407
|
}
|
|
4285
4408
|
};
|
|
4409
|
+
const sweepRemovedSheetRefs = (g) => {
|
|
4410
|
+
const removed = g.mutations.filter((m) => m.id === REMOVE_SHEET2).map((m) => String(m.params.subUnitId ?? ""));
|
|
4411
|
+
const wb = o.workbook();
|
|
4412
|
+
const u = unitId();
|
|
4413
|
+
if (!removed.length || !wb || !u) return;
|
|
4414
|
+
const refSheets = {};
|
|
4415
|
+
for (const [id, name] of Object.entries(g.sheets)) refSheets[name] = id;
|
|
4416
|
+
for (const gone of removed) {
|
|
4417
|
+
const name = g.sheets[gone];
|
|
4418
|
+
if (!name) continue;
|
|
4419
|
+
for (const ws of wb.getSheets()) {
|
|
4420
|
+
const sheet = ws.getSheetId();
|
|
4421
|
+
const cells = {};
|
|
4422
|
+
ws.getCellMatrix?.().forValue((r, c, cell) => {
|
|
4423
|
+
const f = cell?.f;
|
|
4424
|
+
if (typeof f !== "string" || !f.includes(name)) return;
|
|
4425
|
+
const out = rewriteFormula(f, { ownSheet: sheet, refSheets }, { kind: "remove-sheet", sheet: gone });
|
|
4426
|
+
if (typeof out !== "string" && out.changed) (cells[r] ??= {})[c] = { f: out.text, si: null };
|
|
4427
|
+
});
|
|
4428
|
+
if (!Object.keys(cells).length) continue;
|
|
4429
|
+
applying = true;
|
|
4430
|
+
try {
|
|
4431
|
+
cs.syncExecuteCommand(VALUES, { unitId: u, subUnitId: sheet, cellValue: json(cells) });
|
|
4432
|
+
} finally {
|
|
4433
|
+
applying = false;
|
|
4434
|
+
}
|
|
4435
|
+
const done = {};
|
|
4436
|
+
for (const r of Object.keys(cells))
|
|
4437
|
+
for (const c of Object.keys(cells[r])) (done[r] ??= {})[c] = completeCellContent(cells[r][c], json(ws.getCellRaw(Number(r), Number(c)) ?? null));
|
|
4438
|
+
g.mutations.push({ id: VALUES, params: { subUnitId: sheet, cellValue: done } });
|
|
4439
|
+
g.inverses.push(void 0);
|
|
4440
|
+
}
|
|
4441
|
+
}
|
|
4442
|
+
};
|
|
4286
4443
|
const flush = () => {
|
|
4287
4444
|
const g = group;
|
|
4288
4445
|
group = null;
|
|
4289
4446
|
if (!g) return;
|
|
4447
|
+
if (!g.notShared) sweepRemovedSheetRefs(g);
|
|
4290
4448
|
if (g.notShared) emit({ kind: "not_shared", mutationId: g.notShared, label: g.label });
|
|
4291
4449
|
else if (g.mutations.length) {
|
|
4292
4450
|
const mutations = annotateSheetOps(annotateFormulas(g.mutations, g.sheets, g.names), g.order);
|
|
@@ -4298,7 +4456,7 @@ function univerSheetsOtPort(o) {
|
|
|
4298
4456
|
};
|
|
4299
4457
|
function settle() {
|
|
4300
4458
|
if (tracker.stack.length === 0) flush();
|
|
4301
|
-
if (tracker.stack.length === 0 && !group) for (const fn of idle.splice(0)) fn();
|
|
4459
|
+
if (tracker.stack.length === 0 && !group && !holding()) for (const fn of idle.splice(0)) fn();
|
|
4302
4460
|
}
|
|
4303
4461
|
const before = cs.beforeCommandExecuted((info, options) => {
|
|
4304
4462
|
if (info.id === UNDO || info.id === REDO) for (const fn of [...undoWatchers]) fn();
|
|
@@ -4312,6 +4470,7 @@ function univerSheetsOtPort(o) {
|
|
|
4312
4470
|
const ws = o.workbook()?.getSheetBySheetId(String(p.subUnitId ?? ""));
|
|
4313
4471
|
if (!ws) return;
|
|
4314
4472
|
const record = { merges: json(ws.getMergeData() ?? []) };
|
|
4473
|
+
if (!group) record.lone = openGroup(null);
|
|
4315
4474
|
if (info.id === VALUES) {
|
|
4316
4475
|
record.cells = /* @__PURE__ */ new Map();
|
|
4317
4476
|
const cells = p.cellValue ?? {};
|
|
@@ -4348,6 +4507,7 @@ function univerSheetsOtPort(o) {
|
|
|
4348
4507
|
}
|
|
4349
4508
|
};
|
|
4350
4509
|
const after = cs.onCommandExecuted((info) => {
|
|
4510
|
+
if (editorHold && tracker.stack.length === 0 && !group && !edited()) settle();
|
|
4351
4511
|
if (info.type !== COMMAND) return;
|
|
4352
4512
|
const at = tracker.stack.lastIndexOf(info.id);
|
|
4353
4513
|
if (at >= 0) tracker.stack.splice(at, 1);
|
|
@@ -4429,7 +4589,7 @@ function univerSheetsOtPort(o) {
|
|
|
4429
4589
|
else {
|
|
4430
4590
|
inv = {};
|
|
4431
4591
|
if (CONTENT_KEYS.some((k) => k !== "t" && k in done)) Object.assign(inv, fullContent(p));
|
|
4432
|
-
if ("s" in done) inv.s = p?.s
|
|
4592
|
+
if ("s" in done) inv.s = inverseStyle(p?.s, done.s);
|
|
4433
4593
|
}
|
|
4434
4594
|
(invCells[r] ??= {})[c] = inv;
|
|
4435
4595
|
}
|
|
@@ -4467,7 +4627,7 @@ function univerSheetsOtPort(o) {
|
|
|
4467
4627
|
};
|
|
4468
4628
|
const collab = cs.onMutationExecutedForCollab((info, options) => {
|
|
4469
4629
|
if (applying || flagged(options) || !mine(info.params)) return;
|
|
4470
|
-
if (!group) group = openGroup(null);
|
|
4630
|
+
if (!group) group = pre.get(info.params)?.lone ?? openGroup(null);
|
|
4471
4631
|
const g = group;
|
|
4472
4632
|
if (!g.notShared) {
|
|
4473
4633
|
const r = capture(info);
|
|
@@ -4548,11 +4708,18 @@ function univerSheetsOtPort(o) {
|
|
|
4548
4708
|
listeners.add(listener);
|
|
4549
4709
|
return () => void listeners.delete(listener);
|
|
4550
4710
|
},
|
|
4551
|
-
busy: () => tracker.stack.length > 0 || group !== null,
|
|
4711
|
+
busy: () => tracker.stack.length > 0 || group !== null || holding(),
|
|
4712
|
+
defers(op) {
|
|
4713
|
+
if (holding()) return true;
|
|
4714
|
+
const at = edited();
|
|
4715
|
+
if (!at || !op.some((m) => touchesEditedCell(m, at))) return false;
|
|
4716
|
+
editorHold = true;
|
|
4717
|
+
return true;
|
|
4718
|
+
},
|
|
4552
4719
|
/** The outermost commands still running here (why the port is busy), for logs. */
|
|
4553
4720
|
running: () => [...tracker.stack, ...group && tracker.stack.length === 0 ? ["(group)"] : []],
|
|
4554
4721
|
whenIdle(fn) {
|
|
4555
|
-
if (tracker.stack.length === 0 && !group) fn();
|
|
4722
|
+
if (tracker.stack.length === 0 && !group && !holding()) fn();
|
|
4556
4723
|
else idle.push(fn);
|
|
4557
4724
|
},
|
|
4558
4725
|
applyRemote(m) {
|
|
@@ -4612,6 +4779,20 @@ function univerSheetsOtPort(o) {
|
|
|
4612
4779
|
}
|
|
4613
4780
|
};
|
|
4614
4781
|
}
|
|
4782
|
+
function inverseStyle(prev, wrote) {
|
|
4783
|
+
if (!prev || typeof prev !== "object") return null;
|
|
4784
|
+
if (!wrote || typeof wrote !== "object") return prev;
|
|
4785
|
+
const out = { ...prev };
|
|
4786
|
+
for (const k of Object.keys(wrote)) if (!(k in out)) out[k] = null;
|
|
4787
|
+
return out;
|
|
4788
|
+
}
|
|
4789
|
+
function touchesEditedCell(m, at) {
|
|
4790
|
+
const sheet = String(m.params.subUnitId ?? "");
|
|
4791
|
+
if (sheet !== at.sheetId) return false;
|
|
4792
|
+
if (m.id !== VALUES) return true;
|
|
4793
|
+
const row = m.params.cellValue?.[at.row];
|
|
4794
|
+
return !!row && Object.prototype.hasOwnProperty.call(row, at.col);
|
|
4795
|
+
}
|
|
4615
4796
|
function fullContent(cell) {
|
|
4616
4797
|
const out = {};
|
|
4617
4798
|
for (const k of CONTENT_KEYS) out[k] = cell && cell[k] !== void 0 ? cell[k] : null;
|