@ai-matrx/office 0.8.20 → 0.8.21
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 +20 -2
- package/dist/collab-sheets-transform.cjs +354 -16
- package/dist/collab-sheets-transform.cjs.map +1 -1
- package/dist/collab-sheets-transform.d.cts +32 -4
- package/dist/collab-sheets-transform.d.ts +32 -4
- package/dist/collab-sheets-transform.js +354 -16
- package/dist/collab-sheets-transform.js.map +1 -1
- package/dist/univer-collab.cjs +414 -27
- package/dist/univer-collab.cjs.map +1 -1
- package/dist/univer-collab.d.cts +6 -1
- package/dist/univer-collab.d.ts +6 -1
- package/dist/univer-collab.js +414 -27
- package/dist/univer-collab.js.map +1 -1
- package/package.json +3 -3
package/dist/univer-collab.js
CHANGED
|
@@ -1685,6 +1685,14 @@ var SHEET_MUTATIONS = {
|
|
|
1685
1685
|
"sheet.mutation.set-worksheet-row-auto-height": covered("size", "rowsAutoHeightInfo"),
|
|
1686
1686
|
"sheet.mutation.set-worksheet-col-width": covered("size", "ranges", "colWidth"),
|
|
1687
1687
|
"sheet.mutation.set-worksheet-name": covered("name", "name"),
|
|
1688
|
+
// ── covered (C5c) ────────────────────────────────────────────────────────────────────────────────
|
|
1689
|
+
"sheet.mutation.set.numfmt": covered("numfmt", "values", "refMap"),
|
|
1690
|
+
"sheet.mutation.remove.numfmt": covered("numfmt", "ranges"),
|
|
1691
|
+
"sheet.mutation.set-worksheet-row-count": covered("count", "rowCount"),
|
|
1692
|
+
"sheet.mutation.set-worksheet-column-count": covered("count", "columnCount"),
|
|
1693
|
+
"sheet.mutation.insert-sheet": covered("sheet", "index", "sheet"),
|
|
1694
|
+
"sheet.mutation.remove-sheet": covered("sheet", "sheetIndex", "sheetsLeft"),
|
|
1695
|
+
"sheet.mutation.set-worksheet-order": covered("sheet", "fromOrder", "toOrder"),
|
|
1688
1696
|
// ── never travels ────────────────────────────────────────────────────────────────────────────────
|
|
1689
1697
|
"formula.mutation.set-formula-calculation-start": never(FORMULA_RESULT),
|
|
1690
1698
|
"formula.mutation.set-trigger-formula-calculation-start": never(FORMULA_RESULT),
|
|
@@ -1719,12 +1727,7 @@ var SHEET_MUTATIONS = {
|
|
|
1719
1727
|
"thread-comment.mutation.delete-comment": never(UNIVER_COMMENTS),
|
|
1720
1728
|
// ── barriers: X (no transform yet, design §10) ───────────────────────────────────────────────────
|
|
1721
1729
|
"sheet.mutation.reorder-range": barrier("X", "sort: a permutation, not transformed yet"),
|
|
1722
|
-
"sheet.mutation.set-worksheet-row-count": barrier("X", "absolute row count; needs delta semantics"),
|
|
1723
|
-
"sheet.mutation.set-worksheet-column-count": barrier("X", "absolute column count; needs delta semantics"),
|
|
1724
|
-
"sheet.mutation.set-worksheet-order": barrier("X", "absolute sheet order; needs move semantics"),
|
|
1725
1730
|
"sheet.mutation.move-range": barrier("X", "cut-paste carries the sender's cell matrices"),
|
|
1726
|
-
"sheet.mutation.insert-sheet": barrier("X", "sheet add: not in C5a"),
|
|
1727
|
-
"sheet.mutation.remove-sheet": barrier("X", "sheet remove: not in C5a"),
|
|
1728
1731
|
"sheet.mutation.set-worksheet-hidden": barrier("X", "sheet-level setting: not in C5a"),
|
|
1729
1732
|
"sheet.mutation.set-tab-color": barrier("X", "sheet-level setting: not in C5a"),
|
|
1730
1733
|
"sheet.mutation.set-workbook-name": barrier("X", "workbook-level setting: not in C5a"),
|
|
@@ -1739,8 +1742,6 @@ var SHEET_MUTATIONS = {
|
|
|
1739
1742
|
"sheet.mutation.set-row-visible": barrier("X", "row visibility: not in C5a"),
|
|
1740
1743
|
"sheet.mutation.set-col-hidden": barrier("X", "column visibility: not in C5a"),
|
|
1741
1744
|
"sheet.mutation.set-col-visible": barrier("X", "column visibility: not in C5a"),
|
|
1742
|
-
"sheet.mutation.set.numfmt": barrier("X", "number formats by range: not in C5a"),
|
|
1743
|
-
"sheet.mutation.remove.numfmt": barrier("X", "number formats by range: not in C5a"),
|
|
1744
1745
|
"sheet.mutation.add-range-protection": barrier("X", "permissions: not in C5a"),
|
|
1745
1746
|
"sheet.mutation.set-range-protection": barrier("X", "permissions: not in C5a"),
|
|
1746
1747
|
"sheet.mutation.delete-range-protection": barrier("X", "permissions: not in C5a"),
|
|
@@ -2144,7 +2145,7 @@ function refSheetsFor(texts, sheets) {
|
|
|
2144
2145
|
}
|
|
2145
2146
|
|
|
2146
2147
|
// src/collab/sheets/transform/transform.ts
|
|
2147
|
-
var SHEET_TRANSFORMER_VERSION = "
|
|
2148
|
+
var SHEET_TRANSFORMER_VERSION = "c5c-1";
|
|
2148
2149
|
var ID = {
|
|
2149
2150
|
values: "sheet.mutation.set-range-values",
|
|
2150
2151
|
insertRow: "sheet.mutation.insert-row",
|
|
@@ -2161,7 +2162,14 @@ var ID = {
|
|
|
2161
2162
|
colWidth: "sheet.mutation.set-worksheet-col-width",
|
|
2162
2163
|
name: "sheet.mutation.set-worksheet-name",
|
|
2163
2164
|
setName: "formula.mutation.set-defined-name",
|
|
2164
|
-
removeName: "formula.mutation.remove-defined-name"
|
|
2165
|
+
removeName: "formula.mutation.remove-defined-name",
|
|
2166
|
+
setNumfmt: "sheet.mutation.set.numfmt",
|
|
2167
|
+
removeNumfmt: "sheet.mutation.remove.numfmt",
|
|
2168
|
+
rowCount: "sheet.mutation.set-worksheet-row-count",
|
|
2169
|
+
colCount: "sheet.mutation.set-worksheet-column-count",
|
|
2170
|
+
insertSheet: "sheet.mutation.insert-sheet",
|
|
2171
|
+
removeSheet: "sheet.mutation.remove-sheet",
|
|
2172
|
+
sheetOrder: "sheet.mutation.set-worksheet-order"
|
|
2165
2173
|
};
|
|
2166
2174
|
var PAIR_BARRIERS = {};
|
|
2167
2175
|
var pairKey = (a, b) => a < b ? `${a}|${b}` : `${b}|${a}`;
|
|
@@ -2273,6 +2281,20 @@ function mergeThrough(s, m) {
|
|
|
2273
2281
|
}
|
|
2274
2282
|
return { range: m, fixup: false };
|
|
2275
2283
|
}
|
|
2284
|
+
function mergeFixupsOwed(m, mergesBefore) {
|
|
2285
|
+
const st = structuralOf(m);
|
|
2286
|
+
if (!st) return null;
|
|
2287
|
+
const remove = [];
|
|
2288
|
+
const add = [];
|
|
2289
|
+
for (const q of mergesBefore) {
|
|
2290
|
+
const t = mergeThrough(st, q);
|
|
2291
|
+
if (!t.fixup) continue;
|
|
2292
|
+
remove.push({ startRow: q.startRow, endRow: q.endRow, startColumn: q.startColumn, endColumn: q.endColumn, ...q.rangeType !== void 0 ? { rangeType: q.rangeType } : {} });
|
|
2293
|
+
if (t.range) add.push({ ...t.range });
|
|
2294
|
+
}
|
|
2295
|
+
return remove.length ? { remove, add } : null;
|
|
2296
|
+
}
|
|
2297
|
+
var isStructuralMutation = (m) => structuralOf(m) !== null;
|
|
2276
2298
|
function exactMergeRemovals(group, merges) {
|
|
2277
2299
|
const sim = new Map(Object.entries(merges).map(([k, v]) => [k, v.map((r) => ({ ...r }))]));
|
|
2278
2300
|
const out = [];
|
|
@@ -2319,8 +2341,24 @@ function cellsMutation(template, cells) {
|
|
|
2319
2341
|
function putCell(cells, r, c, v) {
|
|
2320
2342
|
(cells[r] ??= {})[c] = v;
|
|
2321
2343
|
}
|
|
2344
|
+
function cellsOverlap(a, b) {
|
|
2345
|
+
for (const r of Object.keys(a)) {
|
|
2346
|
+
const br = b[r];
|
|
2347
|
+
if (!br) continue;
|
|
2348
|
+
for (const c of Object.keys(a[r] ?? {})) if (c in br) return true;
|
|
2349
|
+
}
|
|
2350
|
+
return false;
|
|
2351
|
+
}
|
|
2322
2352
|
var isEmptyMatrix = (cells) => Object.values(cells).every((row) => Object.keys(row).length === 0);
|
|
2353
|
+
var cellBarrierCache = /* @__PURE__ */ new WeakMap();
|
|
2323
2354
|
function cellBarrier(m) {
|
|
2355
|
+
const hit = cellBarrierCache.get(m);
|
|
2356
|
+
if (hit !== void 0) return hit;
|
|
2357
|
+
const why = cellBarrierOf(m);
|
|
2358
|
+
cellBarrierCache.set(m, why);
|
|
2359
|
+
return why;
|
|
2360
|
+
}
|
|
2361
|
+
function cellBarrierOf(m) {
|
|
2324
2362
|
if (m.params.isOverrideStyle) return "set-range-values with isOverrideStyle (whole-style replace) is not covered";
|
|
2325
2363
|
let why = null;
|
|
2326
2364
|
forEachCell(cellsOf(m), (_r, _c, v) => {
|
|
@@ -2402,6 +2440,7 @@ function transformCell(X, Y4, side) {
|
|
|
2402
2440
|
function transformCellsOverCells(x, y, side) {
|
|
2403
2441
|
if (sheetOf(x) !== sheetOf(y)) return ok([x]);
|
|
2404
2442
|
const ycells = cellsOf(y);
|
|
2443
|
+
if (!cellsOverlap(cellsOf(x), ycells)) return ok([x]);
|
|
2405
2444
|
const xd = isDerived(x);
|
|
2406
2445
|
const yd = isDerived(y);
|
|
2407
2446
|
const eff = derivedSide(x, y, side);
|
|
@@ -2429,7 +2468,7 @@ function transformCellsOverCells(x, y, side) {
|
|
|
2429
2468
|
const op = passes.filter((p) => !isEmptyMatrix(p)).map((p) => cellsMutation(x, p));
|
|
2430
2469
|
return ok(op, lost, dropped);
|
|
2431
2470
|
}
|
|
2432
|
-
var SIDE_CAR_PARAMS = ["refSheets", "previousName", "derived"];
|
|
2471
|
+
var SIDE_CAR_PARAMS = ["refSheets", "previousName", "derived", "sheetIndex", "sheetsLeft"];
|
|
2433
2472
|
var isDerived = (m) => m.params.derived === true;
|
|
2434
2473
|
function derivedSide(x, y, side) {
|
|
2435
2474
|
const xd = isDerived(x);
|
|
@@ -2451,7 +2490,15 @@ function withRefSheets(params, rs) {
|
|
|
2451
2490
|
return out;
|
|
2452
2491
|
}
|
|
2453
2492
|
var hasFormulaText = (v) => !!v && (isFormulaText(v.f) || typeof v.ref === "string");
|
|
2493
|
+
var hasFormulaCache = /* @__PURE__ */ new WeakMap();
|
|
2454
2494
|
function hasFormula(m) {
|
|
2495
|
+
const hit = hasFormulaCache.get(m);
|
|
2496
|
+
if (hit !== void 0) return hit;
|
|
2497
|
+
const any = hasFormulaOf(m);
|
|
2498
|
+
hasFormulaCache.set(m, any);
|
|
2499
|
+
return any;
|
|
2500
|
+
}
|
|
2501
|
+
function hasFormulaOf(m) {
|
|
2455
2502
|
let any = false;
|
|
2456
2503
|
forEachCell(cellsOf(m), (_r, _c, v) => {
|
|
2457
2504
|
any ||= hasFormulaText(v);
|
|
@@ -2490,15 +2537,18 @@ function cellThrough(sheet, change, r, c) {
|
|
|
2490
2537
|
return nr === null || nc === null ? null : [nr, nc];
|
|
2491
2538
|
}
|
|
2492
2539
|
function cellsOverChange(x, change) {
|
|
2540
|
+
if (!hasFormula(x) && (change.kind !== "axis" || change.sheet !== sheetOf(x))) return ok([x]);
|
|
2493
2541
|
const ctx = formulaCtx(x);
|
|
2494
2542
|
const out = {};
|
|
2495
2543
|
const dropped = [];
|
|
2496
2544
|
let why = null;
|
|
2545
|
+
let changed = false;
|
|
2497
2546
|
forEachCell(cellsOf(x), (r, c, v) => {
|
|
2498
2547
|
if (why) return;
|
|
2499
2548
|
const at = cellThrough(sheetOf(x), change, r, c);
|
|
2500
2549
|
if (!at) {
|
|
2501
2550
|
dropped.push(cellRef(sheetOf(x), r, c));
|
|
2551
|
+
changed = true;
|
|
2502
2552
|
return;
|
|
2503
2553
|
}
|
|
2504
2554
|
let e = v;
|
|
@@ -2509,14 +2559,19 @@ function cellsOverChange(x, change) {
|
|
|
2509
2559
|
return;
|
|
2510
2560
|
}
|
|
2511
2561
|
e = res.entry;
|
|
2562
|
+
if (res.changed) changed = true;
|
|
2512
2563
|
}
|
|
2564
|
+
if (at[0] !== r || at[1] !== c) changed = true;
|
|
2513
2565
|
putCell(out, at[0], at[1], e);
|
|
2514
2566
|
});
|
|
2515
2567
|
if (why) return barrier2(why);
|
|
2516
|
-
const
|
|
2568
|
+
const rsAfter = refSheetsAfter(ctx.refSheets, change);
|
|
2569
|
+
if (!changed && JSON.stringify(rsAfter ?? null) === JSON.stringify(ctx.refSheets ?? null)) return ok([x]);
|
|
2570
|
+
const params = { ...withRefSheets(x.params, rsAfter), cellValue: out };
|
|
2517
2571
|
return ok(isEmptyMatrix(out) ? [] : [{ id: x.id, params }], [], dropped);
|
|
2518
2572
|
}
|
|
2519
2573
|
function rewritesOf(y, change) {
|
|
2574
|
+
if (!hasFormula(y)) return null;
|
|
2520
2575
|
const ctx = formulaCtx(y);
|
|
2521
2576
|
const out = {};
|
|
2522
2577
|
let why = null;
|
|
@@ -2662,6 +2717,255 @@ function buildSize(template, values) {
|
|
|
2662
2717
|
const value = uniform !== void 0 && [...values.values()].every((v) => v === uniform) ? uniform : Object.fromEntries(values);
|
|
2663
2718
|
return { id: template.id, params: { ...p, ranges, [field]: value } };
|
|
2664
2719
|
}
|
|
2720
|
+
var isNumfmt = (m) => m.id === ID.setNumfmt || m.id === ID.removeNumfmt;
|
|
2721
|
+
function nfParts(m) {
|
|
2722
|
+
if (m.id === ID.removeNumfmt) return [{ key: null, ranges: (m.params.ranges ?? []).map((r) => ({ ...r })) }];
|
|
2723
|
+
const values = m.params.values ?? {};
|
|
2724
|
+
return Object.keys(values).map((k) => ({ key: k, ranges: (values[k]?.ranges ?? []).map((r) => ({ ...r })) }));
|
|
2725
|
+
}
|
|
2726
|
+
function nfBuild(m, parts) {
|
|
2727
|
+
const keep = parts.filter((p) => p.ranges.length);
|
|
2728
|
+
if (!keep.length) return [];
|
|
2729
|
+
if (m.id === ID.removeNumfmt) return [{ id: m.id, params: { ...m.params, ranges: keep[0].ranges } }];
|
|
2730
|
+
const values = {};
|
|
2731
|
+
const refMap = {};
|
|
2732
|
+
const srcValues = m.params.values ?? {};
|
|
2733
|
+
const srcRef = m.params.refMap ?? {};
|
|
2734
|
+
for (const p of keep) {
|
|
2735
|
+
values[p.key] = { ...srcValues[p.key], ranges: p.ranges };
|
|
2736
|
+
refMap[p.key] = srcRef[p.key];
|
|
2737
|
+
}
|
|
2738
|
+
return [{ id: m.id, params: { ...m.params, values, refMap } }];
|
|
2739
|
+
}
|
|
2740
|
+
function nfValueAt(m, row, col) {
|
|
2741
|
+
for (const p of nfParts(m))
|
|
2742
|
+
if (p.ranges.some((r) => r.startRow <= row && row <= r.endRow && r.startColumn <= col && col <= r.endColumn)) {
|
|
2743
|
+
if (p.key === null) return null;
|
|
2744
|
+
const ref = (m.params.refMap ?? {})[p.key];
|
|
2745
|
+
return { pattern: ref?.pattern };
|
|
2746
|
+
}
|
|
2747
|
+
return void 0;
|
|
2748
|
+
}
|
|
2749
|
+
function spanThrough(op, lo, hi) {
|
|
2750
|
+
const pieces = [];
|
|
2751
|
+
if (op.kind === "insert") pieces.push([0, op.at - 1, 0], [op.at, Infinity, op.count]);
|
|
2752
|
+
else if (op.kind === "remove") pieces.push([0, op.start - 1, 0], [op.start + op.count, Infinity, -op.count]);
|
|
2753
|
+
else if (op.count <= 0 || op.to >= op.from && op.to <= op.from + op.count) pieces.push([0, Infinity, 0]);
|
|
2754
|
+
else if (op.to > op.from) {
|
|
2755
|
+
const n = op.count;
|
|
2756
|
+
pieces.push([0, op.from - 1, 0], [op.from, op.from + n - 1, op.to - n - op.from], [op.from + n, op.to - 1, -n], [op.to, Infinity, 0]);
|
|
2757
|
+
} else {
|
|
2758
|
+
const n = op.count;
|
|
2759
|
+
pieces.push([0, op.to - 1, 0], [op.to, op.from - 1, n], [op.from, op.from + n - 1, op.to - op.from], [op.from + n, Infinity, 0]);
|
|
2760
|
+
}
|
|
2761
|
+
const out = [];
|
|
2762
|
+
for (const [a, b, d] of pieces) {
|
|
2763
|
+
const x0 = Math.max(a, lo);
|
|
2764
|
+
const x1 = Math.min(b, hi);
|
|
2765
|
+
if (x0 <= x1) out.push([x0 + d, x1 + d]);
|
|
2766
|
+
}
|
|
2767
|
+
out.sort((p, q) => p[0] - q[0]);
|
|
2768
|
+
const merged = [];
|
|
2769
|
+
for (const p of out) {
|
|
2770
|
+
const last = merged[merged.length - 1];
|
|
2771
|
+
if (last && last[1] + 1 >= p[0]) last[1] = Math.max(last[1], p[1]);
|
|
2772
|
+
else merged.push([p[0], p[1]]);
|
|
2773
|
+
}
|
|
2774
|
+
return merged;
|
|
2775
|
+
}
|
|
2776
|
+
function rectsThrough(st, rects) {
|
|
2777
|
+
const [a0, a1] = S(st.axis);
|
|
2778
|
+
const out = [];
|
|
2779
|
+
for (const r of rects) for (const [lo, hi] of spanThrough(st.op, r[a0], r[a1])) out.push({ ...r, [a0]: lo, [a1]: hi });
|
|
2780
|
+
return out;
|
|
2781
|
+
}
|
|
2782
|
+
function rectMinus(a, b) {
|
|
2783
|
+
if (a.startRow > b.endRow || b.startRow > a.endRow || a.startColumn > b.endColumn || b.startColumn > a.endColumn) return [a];
|
|
2784
|
+
const out = [];
|
|
2785
|
+
if (a.startRow < b.startRow) out.push({ ...a, endRow: b.startRow - 1 });
|
|
2786
|
+
if (a.endRow > b.endRow) out.push({ ...a, startRow: b.endRow + 1 });
|
|
2787
|
+
const r0 = Math.max(a.startRow, b.startRow);
|
|
2788
|
+
const r1 = Math.min(a.endRow, b.endRow);
|
|
2789
|
+
if (a.startColumn < b.startColumn) out.push({ ...a, startRow: r0, endRow: r1, endColumn: b.startColumn - 1 });
|
|
2790
|
+
if (a.endColumn > b.endColumn) out.push({ ...a, startRow: r0, endRow: r1, startColumn: b.endColumn + 1 });
|
|
2791
|
+
return out;
|
|
2792
|
+
}
|
|
2793
|
+
function rectsMinus(as, bs) {
|
|
2794
|
+
let cur = as;
|
|
2795
|
+
for (const b of bs) cur = cur.flatMap((a) => rectMinus(a, b));
|
|
2796
|
+
return cur;
|
|
2797
|
+
}
|
|
2798
|
+
function nWrites(m) {
|
|
2799
|
+
const out = [];
|
|
2800
|
+
forEachCell(cellsOf(m), (r, c, v) => {
|
|
2801
|
+
if (v === null || v.s === null || v.s && typeof v.s === "object" && "n" in v.s)
|
|
2802
|
+
out.push({ startRow: r, endRow: r, startColumn: c, endColumn: c });
|
|
2803
|
+
});
|
|
2804
|
+
return out;
|
|
2805
|
+
}
|
|
2806
|
+
function numfmtPair(x, y, side, sx, sy) {
|
|
2807
|
+
const nx = isNumfmt(x);
|
|
2808
|
+
const ny = isNumfmt(y);
|
|
2809
|
+
if (!nx && !ny) return null;
|
|
2810
|
+
if (nx && sy) return ok(nfBuild(x, nfParts(x).map((p) => ({ ...p, ranges: rectsThrough(sy, p.ranges) }))));
|
|
2811
|
+
if (ny && sx) return ok([x]);
|
|
2812
|
+
if (nx && ny) {
|
|
2813
|
+
if (side === "left") return ok([x]);
|
|
2814
|
+
const ys = nfParts(y).flatMap((p) => p.ranges);
|
|
2815
|
+
return ok(nfBuild(x, nfParts(x).map((p) => ({ ...p, ranges: rectsMinus(p.ranges, ys) }))));
|
|
2816
|
+
}
|
|
2817
|
+
if (nx && y.id === ID.values) {
|
|
2818
|
+
if (side === "left") return ok([x]);
|
|
2819
|
+
const ys = nWrites(y);
|
|
2820
|
+
return ys.length ? ok(nfBuild(x, nfParts(x).map((p) => ({ ...p, ranges: rectsMinus(p.ranges, ys) })))) : ok([x]);
|
|
2821
|
+
}
|
|
2822
|
+
if (ny && x.id === ID.values) {
|
|
2823
|
+
if (side === "left") return ok([x]);
|
|
2824
|
+
const out = {};
|
|
2825
|
+
const tail = {};
|
|
2826
|
+
let touched = false;
|
|
2827
|
+
forEachCell(cellsOf(x), (r, c, v) => {
|
|
2828
|
+
const n = nfValueAt(y, r, c);
|
|
2829
|
+
if (n === void 0) return putCell(out, r, c, v);
|
|
2830
|
+
if (v === null || v.s === null) {
|
|
2831
|
+
putCell(out, r, c, v);
|
|
2832
|
+
if (n) {
|
|
2833
|
+
putCell(tail, r, c, { s: { n } });
|
|
2834
|
+
touched = true;
|
|
2835
|
+
}
|
|
2836
|
+
return;
|
|
2837
|
+
}
|
|
2838
|
+
if (v.s && typeof v.s === "object" && "n" in v.s) {
|
|
2839
|
+
const { n: _drop, ...rest } = v.s;
|
|
2840
|
+
const e = { ...v };
|
|
2841
|
+
if (Object.keys(rest).length) e.s = rest;
|
|
2842
|
+
else delete e.s;
|
|
2843
|
+
touched = true;
|
|
2844
|
+
if (Object.keys(e).length) putCell(out, r, c, e);
|
|
2845
|
+
return;
|
|
2846
|
+
}
|
|
2847
|
+
putCell(out, r, c, v);
|
|
2848
|
+
});
|
|
2849
|
+
if (!touched) return ok([x]);
|
|
2850
|
+
const ops = [];
|
|
2851
|
+
if (!isEmptyMatrix(out)) ops.push(cellsMutation(x, out));
|
|
2852
|
+
if (!isEmptyMatrix(tail)) ops.push({ id: ID.values, params: { subUnitId: sheetOf(x), cellValue: tail } });
|
|
2853
|
+
return ok(ops);
|
|
2854
|
+
}
|
|
2855
|
+
return ok([x]);
|
|
2856
|
+
}
|
|
2857
|
+
var isCount = (m) => m.id === ID.rowCount || m.id === ID.colCount;
|
|
2858
|
+
var countAxis = (m) => m.id === ID.rowCount ? "row" : "col";
|
|
2859
|
+
var countKey = (m) => m.id === ID.rowCount ? "rowCount" : "columnCount";
|
|
2860
|
+
function countPair(x, y, sy) {
|
|
2861
|
+
if (!isCount(x)) return isCount(y) ? ok([x]) : null;
|
|
2862
|
+
const k = countKey(x);
|
|
2863
|
+
const v = Number(x.params[k]);
|
|
2864
|
+
if (sy) {
|
|
2865
|
+
if (sy.axis !== countAxis(x) || sy.op.kind === "move") return ok([x]);
|
|
2866
|
+
const d = sy.op.kind === "insert" ? sy.op.count : -sy.op.count;
|
|
2867
|
+
return ok([{ id: x.id, params: { ...x.params, [k]: Math.max(1, v + d) } }]);
|
|
2868
|
+
}
|
|
2869
|
+
if (isCount(y) && y.id === x.id) {
|
|
2870
|
+
const w = Number(y.params[k]);
|
|
2871
|
+
return ok([w > v ? { id: x.id, params: { ...x.params, [k]: w } } : x]);
|
|
2872
|
+
}
|
|
2873
|
+
return ok([x]);
|
|
2874
|
+
}
|
|
2875
|
+
var isSheetOp = (m) => m.id === ID.insertSheet || m.id === ID.removeSheet || m.id === ID.sheetOrder;
|
|
2876
|
+
var sheetIdOf = (m) => m.id === ID.insertSheet ? String(m.params.sheet?.id ?? "") : sheetOf(m);
|
|
2877
|
+
function sheetAxisOf(m) {
|
|
2878
|
+
const p = m.params;
|
|
2879
|
+
if (m.id === ID.insertSheet) return typeof p.index === "number" ? { kind: "insert", at: p.index, count: 1 } : null;
|
|
2880
|
+
if (m.id === ID.removeSheet) return typeof p.sheetIndex === "number" ? { kind: "remove", start: p.sheetIndex, count: 1 } : null;
|
|
2881
|
+
if (m.id === ID.sheetOrder) {
|
|
2882
|
+
const f = Number(p.fromOrder);
|
|
2883
|
+
const t = Number(p.toOrder);
|
|
2884
|
+
return { kind: "move", from: f, count: 1, to: t > f ? t + 1 : t };
|
|
2885
|
+
}
|
|
2886
|
+
return null;
|
|
2887
|
+
}
|
|
2888
|
+
function buildSheetOp(template, op) {
|
|
2889
|
+
if (op.kind === "insert") return { id: template.id, params: { ...template.params, index: op.at } };
|
|
2890
|
+
if (op.kind === "remove") return { id: template.id, params: { ...template.params, sheetIndex: op.start } };
|
|
2891
|
+
return { id: template.id, params: { ...template.params, fromOrder: op.from, toOrder: op.to > op.from ? op.to - 1 : op.to } };
|
|
2892
|
+
}
|
|
2893
|
+
function namesSheet(m, id) {
|
|
2894
|
+
const rs = refSheetsOf(m);
|
|
2895
|
+
return !!rs && Object.values(rs).includes(id) && (m.id === ID.setName || hasFormula(m));
|
|
2896
|
+
}
|
|
2897
|
+
function sheetPair(x, y, side) {
|
|
2898
|
+
const xs = isSheetOp(x);
|
|
2899
|
+
const ys = isSheetOp(y);
|
|
2900
|
+
if (!xs && !ys) return null;
|
|
2901
|
+
if (xs && ys) {
|
|
2902
|
+
const a = sheetAxisOf(x);
|
|
2903
|
+
const b = sheetAxisOf(y);
|
|
2904
|
+
if (!a || !b) return barrier2("a sheet add or remove without its index (capture must call annotateSheetOps)");
|
|
2905
|
+
if (x.id === ID.insertSheet && y.id === ID.insertSheet && sheetIdOf(x) === sheetIdOf(y)) {
|
|
2906
|
+
return JSON.stringify(x.params) === JSON.stringify(y.params) ? ok([]) : barrier2("the same sheet id added twice with different content");
|
|
2907
|
+
}
|
|
2908
|
+
if (x.id === ID.removeSheet && typeof x.params.sheetsLeft === "number" && sheetIdOf(x) !== sheetIdOf(y) && (y.id === ID.removeSheet || y.id === ID.insertSheet)) {
|
|
2909
|
+
const left = x.params.sheetsLeft + (y.id === ID.insertSheet ? 1 : -1);
|
|
2910
|
+
if (left < 1) return barrier2("concurrent sheet removes would leave the workbook without a sheet");
|
|
2911
|
+
const out2 = transformAxis(a, b, side);
|
|
2912
|
+
if (!out2) return barrier2("sheet order: no transform");
|
|
2913
|
+
return ok(out2.map((o) => buildSheetOp({ id: x.id, params: { ...x.params, sheetsLeft: left } }, o)));
|
|
2914
|
+
}
|
|
2915
|
+
const out = transformAxis(a, b, side);
|
|
2916
|
+
if (!out) return barrier2("sheet order: no transform");
|
|
2917
|
+
return ok(out.map((o) => buildSheetOp(x, o)), [], out.length === 0 && x.id === ID.sheetOrder ? [`${sheetIdOf(x)}: sheet order`] : []);
|
|
2918
|
+
}
|
|
2919
|
+
if (ys) {
|
|
2920
|
+
if (y.id !== ID.removeSheet) return ok([x]);
|
|
2921
|
+
const gone2 = sheetOf(y);
|
|
2922
|
+
if (namesSheet(x, gone2)) return barrier2("a formula names a sheet removed at the same time");
|
|
2923
|
+
if (sheetOf(x) === gone2 && x.id !== ID.setName && x.id !== ID.removeName)
|
|
2924
|
+
return ok([], [], isDerived(x) ? [] : [`${gone2}: the sheet was removed`]);
|
|
2925
|
+
return ok([x]);
|
|
2926
|
+
}
|
|
2927
|
+
if (x.id !== ID.removeSheet) return ok([x]);
|
|
2928
|
+
const gone = sheetOf(x);
|
|
2929
|
+
if (namesSheet(y, gone)) return barrier2("a formula names a sheet removed at the same time");
|
|
2930
|
+
return ok([x], sheetOf(y) === gone && !isDerived(y) && y.id !== ID.setName && y.id !== ID.removeName ? [`${gone}: the sheet was removed`] : []);
|
|
2931
|
+
}
|
|
2932
|
+
function annotateSheetOps(group, sheetOrder) {
|
|
2933
|
+
const order = [...sheetOrder];
|
|
2934
|
+
return group.map((m) => {
|
|
2935
|
+
if (m.id === ID.insertSheet) {
|
|
2936
|
+
const index = typeof m.params.index === "number" ? Math.min(m.params.index, order.length) : order.length;
|
|
2937
|
+
order.splice(index, 0, sheetIdOf(m));
|
|
2938
|
+
return index === m.params.index ? m : { id: m.id, params: { ...m.params, index } };
|
|
2939
|
+
}
|
|
2940
|
+
if (m.id === ID.removeSheet) {
|
|
2941
|
+
const i = order.indexOf(sheetOf(m));
|
|
2942
|
+
if (i >= 0) order.splice(i, 1);
|
|
2943
|
+
return i >= 0 ? { id: m.id, params: { ...m.params, sheetIndex: i, sheetsLeft: order.length } } : m;
|
|
2944
|
+
}
|
|
2945
|
+
if (m.id === ID.sheetOrder) {
|
|
2946
|
+
const f = Number(m.params.fromOrder);
|
|
2947
|
+
const [id] = order.splice(f, 1);
|
|
2948
|
+
order.splice(Number(m.params.toOrder), 0, id ?? sheetOf(m));
|
|
2949
|
+
}
|
|
2950
|
+
return m;
|
|
2951
|
+
});
|
|
2952
|
+
}
|
|
2953
|
+
function inlineSheetStyles(sheet, styleOf) {
|
|
2954
|
+
const out = JSON.parse(JSON.stringify(sheet));
|
|
2955
|
+
const fix = (o) => {
|
|
2956
|
+
if (o && typeof o.s === "string") {
|
|
2957
|
+
const st = styleOf(o.s);
|
|
2958
|
+
if (st) o.s = JSON.parse(JSON.stringify(st));
|
|
2959
|
+
}
|
|
2960
|
+
};
|
|
2961
|
+
for (const row of Object.values(out.cellData ?? {})) for (const cell of Object.values(row ?? {})) fix(cell);
|
|
2962
|
+
for (const key of ["rowData", "columnData"]) for (const v of Object.values(out[key] ?? {})) fix(v);
|
|
2963
|
+
if (typeof out.defaultStyle === "string") {
|
|
2964
|
+
const st = styleOf(out.defaultStyle);
|
|
2965
|
+
if (st) out.defaultStyle = JSON.parse(JSON.stringify(st));
|
|
2966
|
+
}
|
|
2967
|
+
return out;
|
|
2968
|
+
}
|
|
2665
2969
|
function familyOf(id) {
|
|
2666
2970
|
const e = SHEET_MUTATIONS[id];
|
|
2667
2971
|
return e && e.kind === "covered" ? e.family : "";
|
|
@@ -2678,6 +2982,8 @@ function transformMutation(x, y, side) {
|
|
|
2678
2982
|
}
|
|
2679
2983
|
const pb = PAIR_BARRIERS[pairKey(x.id, y.id)];
|
|
2680
2984
|
if (pb) return barrier2(`${x.id} \xD7 ${y.id}: ${pb.reason}${pb.seed === null ? "" : ` (fuzz seed ${pb.seed})`}`);
|
|
2985
|
+
const sp = sheetPair(x, y, side);
|
|
2986
|
+
if (sp) return sp;
|
|
2681
2987
|
const fp = formulaPair(x, y, side);
|
|
2682
2988
|
if (fp) return fp;
|
|
2683
2989
|
if (sheetOf(x) !== sheetOf(y)) return ok([x]);
|
|
@@ -2685,6 +2991,10 @@ function transformMutation(x, y, side) {
|
|
|
2685
2991
|
const fy = familyOf(y.id);
|
|
2686
2992
|
const sy = structuralOf(y);
|
|
2687
2993
|
const sx = structuralOf(x);
|
|
2994
|
+
const cp = countPair(x, y, sy);
|
|
2995
|
+
if (cp) return cp;
|
|
2996
|
+
const np = numfmtPair(x, y, side, sx, sy);
|
|
2997
|
+
if (np) return np;
|
|
2688
2998
|
if (sx && sy) {
|
|
2689
2999
|
if (sx.axis !== sy.axis) return ok([x]);
|
|
2690
3000
|
const out = transformAxis(sx.op, sy.op, side);
|
|
@@ -2792,22 +3102,45 @@ function tSeq(xs, ys, side, acc) {
|
|
|
2792
3102
|
acc.dropped.push(...a.dropped);
|
|
2793
3103
|
return [a.op, b.op];
|
|
2794
3104
|
}
|
|
3105
|
+
const outX = [];
|
|
3106
|
+
let curY = ys;
|
|
3107
|
+
for (const x of xs) {
|
|
3108
|
+
let curX = [x];
|
|
3109
|
+
const nextY = [];
|
|
3110
|
+
for (const y of curY) {
|
|
3111
|
+
if (curX.length === 0) {
|
|
3112
|
+
nextY.push(y);
|
|
3113
|
+
continue;
|
|
3114
|
+
}
|
|
3115
|
+
const r = tSeq(curX, [y], side, acc);
|
|
3116
|
+
if (blocked(r)) return r;
|
|
3117
|
+
curX = r[0];
|
|
3118
|
+
for (const m of r[1]) nextY.push(m);
|
|
3119
|
+
}
|
|
3120
|
+
for (const m of curX) outX.push(m);
|
|
3121
|
+
curY = nextY;
|
|
3122
|
+
}
|
|
3123
|
+
return [outX, curY];
|
|
3124
|
+
}
|
|
3125
|
+
function tSeqOld(xs, ys, side, acc) {
|
|
3126
|
+
if (xs.length === 0 || ys.length === 0) return [xs, ys];
|
|
3127
|
+
if (xs.length === 1 && ys.length === 1) return tSeq(xs, ys, side, acc);
|
|
2795
3128
|
if (xs.length > 1) {
|
|
2796
|
-
const first2 =
|
|
3129
|
+
const first2 = tSeqOld([xs[0]], ys, side, acc);
|
|
2797
3130
|
if (blocked(first2)) return first2;
|
|
2798
|
-
const rest2 =
|
|
3131
|
+
const rest2 = tSeqOld(xs.slice(1), first2[1], side, acc);
|
|
2799
3132
|
if (blocked(rest2)) return rest2;
|
|
2800
3133
|
return [[...first2[0], ...rest2[0]], rest2[1]];
|
|
2801
3134
|
}
|
|
2802
|
-
const first =
|
|
3135
|
+
const first = tSeqOld(xs, [ys[0]], side, acc);
|
|
2803
3136
|
if (blocked(first)) return first;
|
|
2804
|
-
const rest =
|
|
3137
|
+
const rest = tSeqOld(first[0], ys.slice(1), side, acc);
|
|
2805
3138
|
if (blocked(rest)) return rest;
|
|
2806
3139
|
return [rest[0], [...first[1], ...rest[1]]];
|
|
2807
3140
|
}
|
|
2808
3141
|
function transformGroup(x, y, side) {
|
|
2809
3142
|
const acc = { lost: [], dropped: [] };
|
|
2810
|
-
const r = tSeq([...x], [...y], side, acc);
|
|
3143
|
+
const r = (process.env.OLD_TSEQ ? tSeqOld : tSeq)([...x], [...y], side, acc);
|
|
2811
3144
|
if (blocked(r)) return r;
|
|
2812
3145
|
return { op: r[0], lost: [...new Set(acc.lost)], dropped: [...new Set(acc.dropped)] };
|
|
2813
3146
|
}
|
|
@@ -2877,7 +3210,7 @@ async function sheetsStateHash(snapshot) {
|
|
|
2877
3210
|
}
|
|
2878
3211
|
|
|
2879
3212
|
// src/univer/collab/sheets-ot/room.ts
|
|
2880
|
-
var SHEETS_COLLAB_PROTO =
|
|
3213
|
+
var SHEETS_COLLAB_PROTO = 2;
|
|
2881
3214
|
var SHEETS_EDIT_GROUP = "sheets.edit";
|
|
2882
3215
|
var flip2 = (side) => side === "left" ? "right" : "left";
|
|
2883
3216
|
var isNoopSheetOp = (op) => op == null || op.length === 0;
|
|
@@ -2924,6 +3257,11 @@ function travelingShape(m) {
|
|
|
2924
3257
|
}
|
|
2925
3258
|
return { id: m.id, params };
|
|
2926
3259
|
}
|
|
3260
|
+
var shapedLists = /* @__PURE__ */ new WeakMap();
|
|
3261
|
+
function cachedShape(list) {
|
|
3262
|
+
const hit = shapedLists.get(list);
|
|
3263
|
+
return hit && hit.src.length === list.length && hit.src.every((m, i) => m === list[i]) ? hit.shaped : null;
|
|
3264
|
+
}
|
|
2927
3265
|
function rebaseSheetUndoStack(items, remote, unitId) {
|
|
2928
3266
|
if (isNoopSheetOp(remote)) return 0;
|
|
2929
3267
|
let dropped = 0;
|
|
@@ -2935,7 +3273,11 @@ function rebaseSheetUndoStack(items, remote, unitId) {
|
|
|
2935
3273
|
if (!ok2 || !list?.length) continue;
|
|
2936
3274
|
const isOperation = (id) => !SHEET_MUTATIONS[id] && id.includes(".operation.");
|
|
2937
3275
|
const operations = list.filter((m) => isOperation(m.id));
|
|
2938
|
-
|
|
3276
|
+
let shaped = cachedShape(list);
|
|
3277
|
+
if (!shaped) {
|
|
3278
|
+
shaped = list.filter((m) => !isOperation(m.id)).map(travelingShape);
|
|
3279
|
+
shapedLists.set(list, { src: list.slice(), shaped });
|
|
3280
|
+
}
|
|
2939
3281
|
if (shaped.some((m) => m === null)) {
|
|
2940
3282
|
ok2 = false;
|
|
2941
3283
|
continue;
|
|
@@ -2947,8 +3289,10 @@ function rebaseSheetUndoStack(items, remote, unitId) {
|
|
|
2947
3289
|
ok2 = false;
|
|
2948
3290
|
continue;
|
|
2949
3291
|
}
|
|
2950
|
-
if (
|
|
2951
|
-
|
|
3292
|
+
if (r.op.length === shaped.length && r.op.every((m, i2) => m === shaped[i2])) continue;
|
|
3293
|
+
const next = [...r.op.map((m) => ({ id: m.id, params: { ...forApply(m).params, unitId } })), ...operations];
|
|
3294
|
+
shapedLists.set(next, { src: next.slice(), shaped: r.op });
|
|
3295
|
+
item[key] = next;
|
|
2952
3296
|
} catch {
|
|
2953
3297
|
ok2 = false;
|
|
2954
3298
|
}
|
|
@@ -3023,7 +3367,7 @@ function createSheetsOtAdapter(port, hooks = {}) {
|
|
|
3023
3367
|
});
|
|
3024
3368
|
});
|
|
3025
3369
|
}
|
|
3026
|
-
return sheetsStateHash(port.snapshot());
|
|
3370
|
+
return (hooks.stateHash ?? sheetsStateHash)(port.snapshot());
|
|
3027
3371
|
},
|
|
3028
3372
|
held: () => queue.length,
|
|
3029
3373
|
rebaseLocalOverHeld(local) {
|
|
@@ -3135,6 +3479,8 @@ var VALUES = "sheet.mutation.set-range-values";
|
|
|
3135
3479
|
var ADD_MERGE = "sheet.mutation.add-worksheet-merge";
|
|
3136
3480
|
var REMOVE_MERGE = "sheet.mutation.remove-worksheet-merge";
|
|
3137
3481
|
var SHEET_NAME = "sheet.mutation.set-worksheet-name";
|
|
3482
|
+
var INSERT_SHEET = "sheet.mutation.insert-sheet";
|
|
3483
|
+
var RESHAPE = /* @__PURE__ */ new Set(["sheet.mutation.set-worksheet-row-count", "sheet.mutation.set-worksheet-column-count", "sheet.mutation.remove-sheet", INSERT_SHEET]);
|
|
3138
3484
|
var DEPTH_GUARD = /* @__PURE__ */ Symbol.for("ai-matrx.office.sheets.command-depth-guard");
|
|
3139
3485
|
var json = (v) => v === void 0 ? v : JSON.parse(JSON.stringify(v));
|
|
3140
3486
|
var flagged = (options) => {
|
|
@@ -3171,7 +3517,8 @@ function univerSheetsOtPort(o) {
|
|
|
3171
3517
|
for (const [id, d] of Object.entries(map)) out[id] = String(d?.name ?? "");
|
|
3172
3518
|
return out;
|
|
3173
3519
|
};
|
|
3174
|
-
const
|
|
3520
|
+
const sheetOrder = () => (o.workbook()?.getSheets() ?? []).map((ws) => ws.getSheetId());
|
|
3521
|
+
const openGroup = (label) => ({ label, order: sheetOrder(), sheets: sheetNames(), names: definedNames(), mutations: [], inverses: [], notShared: null });
|
|
3175
3522
|
const emit = (e) => {
|
|
3176
3523
|
for (const l of [...listeners]) {
|
|
3177
3524
|
try {
|
|
@@ -3187,7 +3534,8 @@ function univerSheetsOtPort(o) {
|
|
|
3187
3534
|
if (!g) return;
|
|
3188
3535
|
if (g.notShared) emit({ kind: "not_shared", mutationId: g.notShared, label: g.label });
|
|
3189
3536
|
else if (g.mutations.length) {
|
|
3190
|
-
const mutations = annotateFormulas(g.mutations, g.sheets, g.names);
|
|
3537
|
+
const mutations = annotateSheetOps(annotateFormulas(g.mutations, g.sheets, g.names), g.order);
|
|
3538
|
+
if (mutations.some((m) => isStructuralMutation(m) || RESHAPE.has(m.id))) clampSelection();
|
|
3191
3539
|
const known = g.inverses.every((i) => i !== void 0);
|
|
3192
3540
|
const inverse = known ? annotateFormulas(g.inverses.slice().reverse().flat(), g.sheets, g.names) : void 0;
|
|
3193
3541
|
emit({ kind: "group", mutations, ...inverse !== void 0 ? { inverse } : {}, label: g.label });
|
|
@@ -3221,7 +3569,27 @@ function univerSheetsOtPort(o) {
|
|
|
3221
3569
|
}
|
|
3222
3570
|
if (info.id === SHEET_NAME) record.name = ws.getName();
|
|
3223
3571
|
pre.set(p, record);
|
|
3572
|
+
const owed = isStructuralMutation({ id: info.id, params: p }) ? mergeFixupsOwed({ id: info.id, params: p }, record.merges ?? []) : null;
|
|
3573
|
+
if (owed) {
|
|
3574
|
+
runOwn(REMOVE_MERGE, String(p.subUnitId), owed.remove, ADD_MERGE);
|
|
3575
|
+
if (owed.add.length) record.addAfter = owed.add;
|
|
3576
|
+
}
|
|
3224
3577
|
});
|
|
3578
|
+
const runOwn = (id, sheet, ranges, inverseId) => {
|
|
3579
|
+
const u = unitId();
|
|
3580
|
+
if (!u) return;
|
|
3581
|
+
applying = true;
|
|
3582
|
+
try {
|
|
3583
|
+
cs.syncExecuteCommand(id, { unitId: u, subUnitId: sheet, ranges: json(ranges) }, { onlyLocal: true });
|
|
3584
|
+
} finally {
|
|
3585
|
+
applying = false;
|
|
3586
|
+
}
|
|
3587
|
+
if (!group) group = openGroup(null);
|
|
3588
|
+
if (!group.notShared) {
|
|
3589
|
+
group.mutations.push({ id, params: { subUnitId: sheet, ranges: json(ranges) } });
|
|
3590
|
+
group.inverses.push([{ id: inverseId, params: { subUnitId: sheet, ranges: json(ranges) } }]);
|
|
3591
|
+
}
|
|
3592
|
+
};
|
|
3225
3593
|
const after = cs.onCommandExecuted((info) => {
|
|
3226
3594
|
if (info.type !== COMMAND) return;
|
|
3227
3595
|
const at = tracker.stack.lastIndexOf(info.id);
|
|
@@ -3319,6 +3687,8 @@ function univerSheetsOtPort(o) {
|
|
|
3319
3687
|
if (!m2) return { m: null, inverse: void 0 };
|
|
3320
3688
|
return { m: m2, inverse: [{ id: ADD_MERGE, params: { subUnitId: sheet, ranges: json(m2.params.ranges) } }] };
|
|
3321
3689
|
}
|
|
3690
|
+
if (info.id === INSERT_SHEET && params.sheet && typeof params.sheet === "object")
|
|
3691
|
+
params.sheet = inlineSheetStyles(params.sheet, (id) => o.workbook()?.getStyles().get(id));
|
|
3322
3692
|
const m = { id: info.id, params };
|
|
3323
3693
|
switch (info.id) {
|
|
3324
3694
|
case "sheet.mutation.insert-row":
|
|
@@ -3335,8 +3705,7 @@ function univerSheetsOtPort(o) {
|
|
|
3335
3705
|
};
|
|
3336
3706
|
const collab = cs.onMutationExecutedForCollab((info, options) => {
|
|
3337
3707
|
if (applying || flagged(options) || !mine(info.params)) return;
|
|
3338
|
-
|
|
3339
|
-
if (lone) group = openGroup(null);
|
|
3708
|
+
if (!group) group = openGroup(null);
|
|
3340
3709
|
const g = group;
|
|
3341
3710
|
if (!g.notShared) {
|
|
3342
3711
|
const r = capture(info);
|
|
@@ -3346,11 +3715,29 @@ function univerSheetsOtPort(o) {
|
|
|
3346
3715
|
g.inverses.push(r.inverse);
|
|
3347
3716
|
}
|
|
3348
3717
|
}
|
|
3349
|
-
|
|
3718
|
+
const owedAdd = pre.get(info.params)?.addAfter;
|
|
3719
|
+
if (owedAdd?.length) runOwn(ADD_MERGE, String(info.params.subUnitId ?? ""), owedAdd, REMOVE_MERGE);
|
|
3720
|
+
if (tracker.stack.length === 0) settle();
|
|
3350
3721
|
});
|
|
3722
|
+
const clampSelection = () => {
|
|
3723
|
+
const sel = o.selections;
|
|
3724
|
+
if (!sel) return;
|
|
3725
|
+
try {
|
|
3726
|
+
const sheet = sel.sheetId();
|
|
3727
|
+
const ws = sheet ? o.workbook()?.getSheetBySheetId(sheet) : null;
|
|
3728
|
+
const current = sel.get();
|
|
3729
|
+
if (!ws || !current?.length) return;
|
|
3730
|
+
const rows = ws.getMaxRows?.() ?? Number.MAX_SAFE_INTEGER;
|
|
3731
|
+
const cols = ws.getMaxColumns?.() ?? Number.MAX_SAFE_INTEGER;
|
|
3732
|
+
const next = moveSelectionsThrough(json(current), { id: "", params: {} }, rows, cols);
|
|
3733
|
+
if (JSON.stringify(next) !== JSON.stringify(current)) sel.set(next);
|
|
3734
|
+
} catch (err) {
|
|
3735
|
+
console.warn("[sheets-ot] could not keep this seat's selection inside the sheet after its own row or column change", err);
|
|
3736
|
+
}
|
|
3737
|
+
};
|
|
3351
3738
|
const followSelection = (m) => {
|
|
3352
3739
|
const sel = o.selections;
|
|
3353
|
-
if (!sel || !axisOpOf(m)) return;
|
|
3740
|
+
if (!sel || !axisOpOf(m) && !RESHAPE.has(m.id)) return;
|
|
3354
3741
|
try {
|
|
3355
3742
|
const sheet = String(m.params.subUnitId ?? "");
|
|
3356
3743
|
if (sel.sheetId() !== sheet) return;
|