@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.cjs
CHANGED
|
@@ -1758,6 +1758,14 @@ var SHEET_MUTATIONS = {
|
|
|
1758
1758
|
"sheet.mutation.set-worksheet-row-auto-height": covered("size", "rowsAutoHeightInfo"),
|
|
1759
1759
|
"sheet.mutation.set-worksheet-col-width": covered("size", "ranges", "colWidth"),
|
|
1760
1760
|
"sheet.mutation.set-worksheet-name": covered("name", "name"),
|
|
1761
|
+
// ── covered (C5c) ────────────────────────────────────────────────────────────────────────────────
|
|
1762
|
+
"sheet.mutation.set.numfmt": covered("numfmt", "values", "refMap"),
|
|
1763
|
+
"sheet.mutation.remove.numfmt": covered("numfmt", "ranges"),
|
|
1764
|
+
"sheet.mutation.set-worksheet-row-count": covered("count", "rowCount"),
|
|
1765
|
+
"sheet.mutation.set-worksheet-column-count": covered("count", "columnCount"),
|
|
1766
|
+
"sheet.mutation.insert-sheet": covered("sheet", "index", "sheet"),
|
|
1767
|
+
"sheet.mutation.remove-sheet": covered("sheet", "sheetIndex", "sheetsLeft"),
|
|
1768
|
+
"sheet.mutation.set-worksheet-order": covered("sheet", "fromOrder", "toOrder"),
|
|
1761
1769
|
// ── never travels ────────────────────────────────────────────────────────────────────────────────
|
|
1762
1770
|
"formula.mutation.set-formula-calculation-start": never(FORMULA_RESULT),
|
|
1763
1771
|
"formula.mutation.set-trigger-formula-calculation-start": never(FORMULA_RESULT),
|
|
@@ -1792,12 +1800,7 @@ var SHEET_MUTATIONS = {
|
|
|
1792
1800
|
"thread-comment.mutation.delete-comment": never(UNIVER_COMMENTS),
|
|
1793
1801
|
// ── barriers: X (no transform yet, design §10) ───────────────────────────────────────────────────
|
|
1794
1802
|
"sheet.mutation.reorder-range": barrier("X", "sort: a permutation, not transformed yet"),
|
|
1795
|
-
"sheet.mutation.set-worksheet-row-count": barrier("X", "absolute row count; needs delta semantics"),
|
|
1796
|
-
"sheet.mutation.set-worksheet-column-count": barrier("X", "absolute column count; needs delta semantics"),
|
|
1797
|
-
"sheet.mutation.set-worksheet-order": barrier("X", "absolute sheet order; needs move semantics"),
|
|
1798
1803
|
"sheet.mutation.move-range": barrier("X", "cut-paste carries the sender's cell matrices"),
|
|
1799
|
-
"sheet.mutation.insert-sheet": barrier("X", "sheet add: not in C5a"),
|
|
1800
|
-
"sheet.mutation.remove-sheet": barrier("X", "sheet remove: not in C5a"),
|
|
1801
1804
|
"sheet.mutation.set-worksheet-hidden": barrier("X", "sheet-level setting: not in C5a"),
|
|
1802
1805
|
"sheet.mutation.set-tab-color": barrier("X", "sheet-level setting: not in C5a"),
|
|
1803
1806
|
"sheet.mutation.set-workbook-name": barrier("X", "workbook-level setting: not in C5a"),
|
|
@@ -1812,8 +1815,6 @@ var SHEET_MUTATIONS = {
|
|
|
1812
1815
|
"sheet.mutation.set-row-visible": barrier("X", "row visibility: not in C5a"),
|
|
1813
1816
|
"sheet.mutation.set-col-hidden": barrier("X", "column visibility: not in C5a"),
|
|
1814
1817
|
"sheet.mutation.set-col-visible": barrier("X", "column visibility: not in C5a"),
|
|
1815
|
-
"sheet.mutation.set.numfmt": barrier("X", "number formats by range: not in C5a"),
|
|
1816
|
-
"sheet.mutation.remove.numfmt": barrier("X", "number formats by range: not in C5a"),
|
|
1817
1818
|
"sheet.mutation.add-range-protection": barrier("X", "permissions: not in C5a"),
|
|
1818
1819
|
"sheet.mutation.set-range-protection": barrier("X", "permissions: not in C5a"),
|
|
1819
1820
|
"sheet.mutation.delete-range-protection": barrier("X", "permissions: not in C5a"),
|
|
@@ -2208,7 +2209,7 @@ function refSheetsFor(texts, sheets) {
|
|
|
2208
2209
|
}
|
|
2209
2210
|
|
|
2210
2211
|
// src/collab/sheets/transform/transform.ts
|
|
2211
|
-
var SHEET_TRANSFORMER_VERSION = "
|
|
2212
|
+
var SHEET_TRANSFORMER_VERSION = "c5c-1";
|
|
2212
2213
|
var ID = {
|
|
2213
2214
|
values: "sheet.mutation.set-range-values",
|
|
2214
2215
|
insertRow: "sheet.mutation.insert-row",
|
|
@@ -2225,7 +2226,14 @@ var ID = {
|
|
|
2225
2226
|
colWidth: "sheet.mutation.set-worksheet-col-width",
|
|
2226
2227
|
name: "sheet.mutation.set-worksheet-name",
|
|
2227
2228
|
setName: "formula.mutation.set-defined-name",
|
|
2228
|
-
removeName: "formula.mutation.remove-defined-name"
|
|
2229
|
+
removeName: "formula.mutation.remove-defined-name",
|
|
2230
|
+
setNumfmt: "sheet.mutation.set.numfmt",
|
|
2231
|
+
removeNumfmt: "sheet.mutation.remove.numfmt",
|
|
2232
|
+
rowCount: "sheet.mutation.set-worksheet-row-count",
|
|
2233
|
+
colCount: "sheet.mutation.set-worksheet-column-count",
|
|
2234
|
+
insertSheet: "sheet.mutation.insert-sheet",
|
|
2235
|
+
removeSheet: "sheet.mutation.remove-sheet",
|
|
2236
|
+
sheetOrder: "sheet.mutation.set-worksheet-order"
|
|
2229
2237
|
};
|
|
2230
2238
|
var PAIR_BARRIERS = {};
|
|
2231
2239
|
var pairKey = (a, b) => a < b ? `${a}|${b}` : `${b}|${a}`;
|
|
@@ -2337,6 +2345,20 @@ function mergeThrough(s, m) {
|
|
|
2337
2345
|
}
|
|
2338
2346
|
return { range: m, fixup: false };
|
|
2339
2347
|
}
|
|
2348
|
+
function mergeFixupsOwed(m, mergesBefore) {
|
|
2349
|
+
const st = structuralOf(m);
|
|
2350
|
+
if (!st) return null;
|
|
2351
|
+
const remove = [];
|
|
2352
|
+
const add = [];
|
|
2353
|
+
for (const q of mergesBefore) {
|
|
2354
|
+
const t = mergeThrough(st, q);
|
|
2355
|
+
if (!t.fixup) continue;
|
|
2356
|
+
remove.push({ startRow: q.startRow, endRow: q.endRow, startColumn: q.startColumn, endColumn: q.endColumn, ...q.rangeType !== void 0 ? { rangeType: q.rangeType } : {} });
|
|
2357
|
+
if (t.range) add.push({ ...t.range });
|
|
2358
|
+
}
|
|
2359
|
+
return remove.length ? { remove, add } : null;
|
|
2360
|
+
}
|
|
2361
|
+
var isStructuralMutation = (m) => structuralOf(m) !== null;
|
|
2340
2362
|
function exactMergeRemovals(group, merges) {
|
|
2341
2363
|
const sim = new Map(Object.entries(merges).map(([k, v]) => [k, v.map((r) => ({ ...r }))]));
|
|
2342
2364
|
const out = [];
|
|
@@ -2383,8 +2405,24 @@ function cellsMutation(template, cells) {
|
|
|
2383
2405
|
function putCell(cells, r, c, v) {
|
|
2384
2406
|
(cells[r] ??= {})[c] = v;
|
|
2385
2407
|
}
|
|
2408
|
+
function cellsOverlap(a, b) {
|
|
2409
|
+
for (const r of Object.keys(a)) {
|
|
2410
|
+
const br = b[r];
|
|
2411
|
+
if (!br) continue;
|
|
2412
|
+
for (const c of Object.keys(a[r] ?? {})) if (c in br) return true;
|
|
2413
|
+
}
|
|
2414
|
+
return false;
|
|
2415
|
+
}
|
|
2386
2416
|
var isEmptyMatrix = (cells) => Object.values(cells).every((row) => Object.keys(row).length === 0);
|
|
2417
|
+
var cellBarrierCache = /* @__PURE__ */ new WeakMap();
|
|
2387
2418
|
function cellBarrier(m) {
|
|
2419
|
+
const hit = cellBarrierCache.get(m);
|
|
2420
|
+
if (hit !== void 0) return hit;
|
|
2421
|
+
const why = cellBarrierOf(m);
|
|
2422
|
+
cellBarrierCache.set(m, why);
|
|
2423
|
+
return why;
|
|
2424
|
+
}
|
|
2425
|
+
function cellBarrierOf(m) {
|
|
2388
2426
|
if (m.params.isOverrideStyle) return "set-range-values with isOverrideStyle (whole-style replace) is not covered";
|
|
2389
2427
|
let why = null;
|
|
2390
2428
|
forEachCell(cellsOf(m), (_r, _c, v) => {
|
|
@@ -2466,6 +2504,7 @@ function transformCell(X, Y4, side) {
|
|
|
2466
2504
|
function transformCellsOverCells(x, y, side) {
|
|
2467
2505
|
if (sheetOf(x) !== sheetOf(y)) return ok([x]);
|
|
2468
2506
|
const ycells = cellsOf(y);
|
|
2507
|
+
if (!cellsOverlap(cellsOf(x), ycells)) return ok([x]);
|
|
2469
2508
|
const xd = isDerived(x);
|
|
2470
2509
|
const yd = isDerived(y);
|
|
2471
2510
|
const eff = derivedSide(x, y, side);
|
|
@@ -2493,7 +2532,7 @@ function transformCellsOverCells(x, y, side) {
|
|
|
2493
2532
|
const op = passes.filter((p) => !isEmptyMatrix(p)).map((p) => cellsMutation(x, p));
|
|
2494
2533
|
return ok(op, lost, dropped);
|
|
2495
2534
|
}
|
|
2496
|
-
var SIDE_CAR_PARAMS = ["refSheets", "previousName", "derived"];
|
|
2535
|
+
var SIDE_CAR_PARAMS = ["refSheets", "previousName", "derived", "sheetIndex", "sheetsLeft"];
|
|
2497
2536
|
var isDerived = (m) => m.params.derived === true;
|
|
2498
2537
|
function derivedSide(x, y, side) {
|
|
2499
2538
|
const xd = isDerived(x);
|
|
@@ -2515,7 +2554,15 @@ function withRefSheets(params, rs) {
|
|
|
2515
2554
|
return out;
|
|
2516
2555
|
}
|
|
2517
2556
|
var hasFormulaText = (v) => !!v && (isFormulaText(v.f) || typeof v.ref === "string");
|
|
2557
|
+
var hasFormulaCache = /* @__PURE__ */ new WeakMap();
|
|
2518
2558
|
function hasFormula(m) {
|
|
2559
|
+
const hit = hasFormulaCache.get(m);
|
|
2560
|
+
if (hit !== void 0) return hit;
|
|
2561
|
+
const any = hasFormulaOf(m);
|
|
2562
|
+
hasFormulaCache.set(m, any);
|
|
2563
|
+
return any;
|
|
2564
|
+
}
|
|
2565
|
+
function hasFormulaOf(m) {
|
|
2519
2566
|
let any = false;
|
|
2520
2567
|
forEachCell(cellsOf(m), (_r, _c, v) => {
|
|
2521
2568
|
any ||= hasFormulaText(v);
|
|
@@ -2554,15 +2601,18 @@ function cellThrough(sheet, change, r, c) {
|
|
|
2554
2601
|
return nr === null || nc === null ? null : [nr, nc];
|
|
2555
2602
|
}
|
|
2556
2603
|
function cellsOverChange(x, change) {
|
|
2604
|
+
if (!hasFormula(x) && (change.kind !== "axis" || change.sheet !== sheetOf(x))) return ok([x]);
|
|
2557
2605
|
const ctx = formulaCtx(x);
|
|
2558
2606
|
const out = {};
|
|
2559
2607
|
const dropped = [];
|
|
2560
2608
|
let why = null;
|
|
2609
|
+
let changed = false;
|
|
2561
2610
|
forEachCell(cellsOf(x), (r, c, v) => {
|
|
2562
2611
|
if (why) return;
|
|
2563
2612
|
const at = cellThrough(sheetOf(x), change, r, c);
|
|
2564
2613
|
if (!at) {
|
|
2565
2614
|
dropped.push(cellRef(sheetOf(x), r, c));
|
|
2615
|
+
changed = true;
|
|
2566
2616
|
return;
|
|
2567
2617
|
}
|
|
2568
2618
|
let e = v;
|
|
@@ -2573,14 +2623,19 @@ function cellsOverChange(x, change) {
|
|
|
2573
2623
|
return;
|
|
2574
2624
|
}
|
|
2575
2625
|
e = res.entry;
|
|
2626
|
+
if (res.changed) changed = true;
|
|
2576
2627
|
}
|
|
2628
|
+
if (at[0] !== r || at[1] !== c) changed = true;
|
|
2577
2629
|
putCell(out, at[0], at[1], e);
|
|
2578
2630
|
});
|
|
2579
2631
|
if (why) return barrier2(why);
|
|
2580
|
-
const
|
|
2632
|
+
const rsAfter = refSheetsAfter(ctx.refSheets, change);
|
|
2633
|
+
if (!changed && JSON.stringify(rsAfter ?? null) === JSON.stringify(ctx.refSheets ?? null)) return ok([x]);
|
|
2634
|
+
const params = { ...withRefSheets(x.params, rsAfter), cellValue: out };
|
|
2581
2635
|
return ok(isEmptyMatrix(out) ? [] : [{ id: x.id, params }], [], dropped);
|
|
2582
2636
|
}
|
|
2583
2637
|
function rewritesOf(y, change) {
|
|
2638
|
+
if (!hasFormula(y)) return null;
|
|
2584
2639
|
const ctx = formulaCtx(y);
|
|
2585
2640
|
const out = {};
|
|
2586
2641
|
let why = null;
|
|
@@ -2726,6 +2781,255 @@ function buildSize(template, values) {
|
|
|
2726
2781
|
const value = uniform !== void 0 && [...values.values()].every((v) => v === uniform) ? uniform : Object.fromEntries(values);
|
|
2727
2782
|
return { id: template.id, params: { ...p, ranges, [field]: value } };
|
|
2728
2783
|
}
|
|
2784
|
+
var isNumfmt = (m) => m.id === ID.setNumfmt || m.id === ID.removeNumfmt;
|
|
2785
|
+
function nfParts(m) {
|
|
2786
|
+
if (m.id === ID.removeNumfmt) return [{ key: null, ranges: (m.params.ranges ?? []).map((r) => ({ ...r })) }];
|
|
2787
|
+
const values = m.params.values ?? {};
|
|
2788
|
+
return Object.keys(values).map((k) => ({ key: k, ranges: (values[k]?.ranges ?? []).map((r) => ({ ...r })) }));
|
|
2789
|
+
}
|
|
2790
|
+
function nfBuild(m, parts) {
|
|
2791
|
+
const keep = parts.filter((p) => p.ranges.length);
|
|
2792
|
+
if (!keep.length) return [];
|
|
2793
|
+
if (m.id === ID.removeNumfmt) return [{ id: m.id, params: { ...m.params, ranges: keep[0].ranges } }];
|
|
2794
|
+
const values = {};
|
|
2795
|
+
const refMap = {};
|
|
2796
|
+
const srcValues = m.params.values ?? {};
|
|
2797
|
+
const srcRef = m.params.refMap ?? {};
|
|
2798
|
+
for (const p of keep) {
|
|
2799
|
+
values[p.key] = { ...srcValues[p.key], ranges: p.ranges };
|
|
2800
|
+
refMap[p.key] = srcRef[p.key];
|
|
2801
|
+
}
|
|
2802
|
+
return [{ id: m.id, params: { ...m.params, values, refMap } }];
|
|
2803
|
+
}
|
|
2804
|
+
function nfValueAt(m, row, col) {
|
|
2805
|
+
for (const p of nfParts(m))
|
|
2806
|
+
if (p.ranges.some((r) => r.startRow <= row && row <= r.endRow && r.startColumn <= col && col <= r.endColumn)) {
|
|
2807
|
+
if (p.key === null) return null;
|
|
2808
|
+
const ref = (m.params.refMap ?? {})[p.key];
|
|
2809
|
+
return { pattern: ref?.pattern };
|
|
2810
|
+
}
|
|
2811
|
+
return void 0;
|
|
2812
|
+
}
|
|
2813
|
+
function spanThrough(op, lo, hi) {
|
|
2814
|
+
const pieces = [];
|
|
2815
|
+
if (op.kind === "insert") pieces.push([0, op.at - 1, 0], [op.at, Infinity, op.count]);
|
|
2816
|
+
else if (op.kind === "remove") pieces.push([0, op.start - 1, 0], [op.start + op.count, Infinity, -op.count]);
|
|
2817
|
+
else if (op.count <= 0 || op.to >= op.from && op.to <= op.from + op.count) pieces.push([0, Infinity, 0]);
|
|
2818
|
+
else if (op.to > op.from) {
|
|
2819
|
+
const n = op.count;
|
|
2820
|
+
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]);
|
|
2821
|
+
} else {
|
|
2822
|
+
const n = op.count;
|
|
2823
|
+
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]);
|
|
2824
|
+
}
|
|
2825
|
+
const out = [];
|
|
2826
|
+
for (const [a, b, d] of pieces) {
|
|
2827
|
+
const x0 = Math.max(a, lo);
|
|
2828
|
+
const x1 = Math.min(b, hi);
|
|
2829
|
+
if (x0 <= x1) out.push([x0 + d, x1 + d]);
|
|
2830
|
+
}
|
|
2831
|
+
out.sort((p, q) => p[0] - q[0]);
|
|
2832
|
+
const merged = [];
|
|
2833
|
+
for (const p of out) {
|
|
2834
|
+
const last = merged[merged.length - 1];
|
|
2835
|
+
if (last && last[1] + 1 >= p[0]) last[1] = Math.max(last[1], p[1]);
|
|
2836
|
+
else merged.push([p[0], p[1]]);
|
|
2837
|
+
}
|
|
2838
|
+
return merged;
|
|
2839
|
+
}
|
|
2840
|
+
function rectsThrough(st, rects) {
|
|
2841
|
+
const [a0, a1] = S(st.axis);
|
|
2842
|
+
const out = [];
|
|
2843
|
+
for (const r of rects) for (const [lo, hi] of spanThrough(st.op, r[a0], r[a1])) out.push({ ...r, [a0]: lo, [a1]: hi });
|
|
2844
|
+
return out;
|
|
2845
|
+
}
|
|
2846
|
+
function rectMinus(a, b) {
|
|
2847
|
+
if (a.startRow > b.endRow || b.startRow > a.endRow || a.startColumn > b.endColumn || b.startColumn > a.endColumn) return [a];
|
|
2848
|
+
const out = [];
|
|
2849
|
+
if (a.startRow < b.startRow) out.push({ ...a, endRow: b.startRow - 1 });
|
|
2850
|
+
if (a.endRow > b.endRow) out.push({ ...a, startRow: b.endRow + 1 });
|
|
2851
|
+
const r0 = Math.max(a.startRow, b.startRow);
|
|
2852
|
+
const r1 = Math.min(a.endRow, b.endRow);
|
|
2853
|
+
if (a.startColumn < b.startColumn) out.push({ ...a, startRow: r0, endRow: r1, endColumn: b.startColumn - 1 });
|
|
2854
|
+
if (a.endColumn > b.endColumn) out.push({ ...a, startRow: r0, endRow: r1, startColumn: b.endColumn + 1 });
|
|
2855
|
+
return out;
|
|
2856
|
+
}
|
|
2857
|
+
function rectsMinus(as, bs) {
|
|
2858
|
+
let cur = as;
|
|
2859
|
+
for (const b of bs) cur = cur.flatMap((a) => rectMinus(a, b));
|
|
2860
|
+
return cur;
|
|
2861
|
+
}
|
|
2862
|
+
function nWrites(m) {
|
|
2863
|
+
const out = [];
|
|
2864
|
+
forEachCell(cellsOf(m), (r, c, v) => {
|
|
2865
|
+
if (v === null || v.s === null || v.s && typeof v.s === "object" && "n" in v.s)
|
|
2866
|
+
out.push({ startRow: r, endRow: r, startColumn: c, endColumn: c });
|
|
2867
|
+
});
|
|
2868
|
+
return out;
|
|
2869
|
+
}
|
|
2870
|
+
function numfmtPair(x, y, side, sx, sy) {
|
|
2871
|
+
const nx = isNumfmt(x);
|
|
2872
|
+
const ny = isNumfmt(y);
|
|
2873
|
+
if (!nx && !ny) return null;
|
|
2874
|
+
if (nx && sy) return ok(nfBuild(x, nfParts(x).map((p) => ({ ...p, ranges: rectsThrough(sy, p.ranges) }))));
|
|
2875
|
+
if (ny && sx) return ok([x]);
|
|
2876
|
+
if (nx && ny) {
|
|
2877
|
+
if (side === "left") return ok([x]);
|
|
2878
|
+
const ys = nfParts(y).flatMap((p) => p.ranges);
|
|
2879
|
+
return ok(nfBuild(x, nfParts(x).map((p) => ({ ...p, ranges: rectsMinus(p.ranges, ys) }))));
|
|
2880
|
+
}
|
|
2881
|
+
if (nx && y.id === ID.values) {
|
|
2882
|
+
if (side === "left") return ok([x]);
|
|
2883
|
+
const ys = nWrites(y);
|
|
2884
|
+
return ys.length ? ok(nfBuild(x, nfParts(x).map((p) => ({ ...p, ranges: rectsMinus(p.ranges, ys) })))) : ok([x]);
|
|
2885
|
+
}
|
|
2886
|
+
if (ny && x.id === ID.values) {
|
|
2887
|
+
if (side === "left") return ok([x]);
|
|
2888
|
+
const out = {};
|
|
2889
|
+
const tail = {};
|
|
2890
|
+
let touched = false;
|
|
2891
|
+
forEachCell(cellsOf(x), (r, c, v) => {
|
|
2892
|
+
const n = nfValueAt(y, r, c);
|
|
2893
|
+
if (n === void 0) return putCell(out, r, c, v);
|
|
2894
|
+
if (v === null || v.s === null) {
|
|
2895
|
+
putCell(out, r, c, v);
|
|
2896
|
+
if (n) {
|
|
2897
|
+
putCell(tail, r, c, { s: { n } });
|
|
2898
|
+
touched = true;
|
|
2899
|
+
}
|
|
2900
|
+
return;
|
|
2901
|
+
}
|
|
2902
|
+
if (v.s && typeof v.s === "object" && "n" in v.s) {
|
|
2903
|
+
const { n: _drop, ...rest } = v.s;
|
|
2904
|
+
const e = { ...v };
|
|
2905
|
+
if (Object.keys(rest).length) e.s = rest;
|
|
2906
|
+
else delete e.s;
|
|
2907
|
+
touched = true;
|
|
2908
|
+
if (Object.keys(e).length) putCell(out, r, c, e);
|
|
2909
|
+
return;
|
|
2910
|
+
}
|
|
2911
|
+
putCell(out, r, c, v);
|
|
2912
|
+
});
|
|
2913
|
+
if (!touched) return ok([x]);
|
|
2914
|
+
const ops = [];
|
|
2915
|
+
if (!isEmptyMatrix(out)) ops.push(cellsMutation(x, out));
|
|
2916
|
+
if (!isEmptyMatrix(tail)) ops.push({ id: ID.values, params: { subUnitId: sheetOf(x), cellValue: tail } });
|
|
2917
|
+
return ok(ops);
|
|
2918
|
+
}
|
|
2919
|
+
return ok([x]);
|
|
2920
|
+
}
|
|
2921
|
+
var isCount = (m) => m.id === ID.rowCount || m.id === ID.colCount;
|
|
2922
|
+
var countAxis = (m) => m.id === ID.rowCount ? "row" : "col";
|
|
2923
|
+
var countKey = (m) => m.id === ID.rowCount ? "rowCount" : "columnCount";
|
|
2924
|
+
function countPair(x, y, sy) {
|
|
2925
|
+
if (!isCount(x)) return isCount(y) ? ok([x]) : null;
|
|
2926
|
+
const k = countKey(x);
|
|
2927
|
+
const v = Number(x.params[k]);
|
|
2928
|
+
if (sy) {
|
|
2929
|
+
if (sy.axis !== countAxis(x) || sy.op.kind === "move") return ok([x]);
|
|
2930
|
+
const d = sy.op.kind === "insert" ? sy.op.count : -sy.op.count;
|
|
2931
|
+
return ok([{ id: x.id, params: { ...x.params, [k]: Math.max(1, v + d) } }]);
|
|
2932
|
+
}
|
|
2933
|
+
if (isCount(y) && y.id === x.id) {
|
|
2934
|
+
const w = Number(y.params[k]);
|
|
2935
|
+
return ok([w > v ? { id: x.id, params: { ...x.params, [k]: w } } : x]);
|
|
2936
|
+
}
|
|
2937
|
+
return ok([x]);
|
|
2938
|
+
}
|
|
2939
|
+
var isSheetOp = (m) => m.id === ID.insertSheet || m.id === ID.removeSheet || m.id === ID.sheetOrder;
|
|
2940
|
+
var sheetIdOf = (m) => m.id === ID.insertSheet ? String(m.params.sheet?.id ?? "") : sheetOf(m);
|
|
2941
|
+
function sheetAxisOf(m) {
|
|
2942
|
+
const p = m.params;
|
|
2943
|
+
if (m.id === ID.insertSheet) return typeof p.index === "number" ? { kind: "insert", at: p.index, count: 1 } : null;
|
|
2944
|
+
if (m.id === ID.removeSheet) return typeof p.sheetIndex === "number" ? { kind: "remove", start: p.sheetIndex, count: 1 } : null;
|
|
2945
|
+
if (m.id === ID.sheetOrder) {
|
|
2946
|
+
const f = Number(p.fromOrder);
|
|
2947
|
+
const t = Number(p.toOrder);
|
|
2948
|
+
return { kind: "move", from: f, count: 1, to: t > f ? t + 1 : t };
|
|
2949
|
+
}
|
|
2950
|
+
return null;
|
|
2951
|
+
}
|
|
2952
|
+
function buildSheetOp(template, op) {
|
|
2953
|
+
if (op.kind === "insert") return { id: template.id, params: { ...template.params, index: op.at } };
|
|
2954
|
+
if (op.kind === "remove") return { id: template.id, params: { ...template.params, sheetIndex: op.start } };
|
|
2955
|
+
return { id: template.id, params: { ...template.params, fromOrder: op.from, toOrder: op.to > op.from ? op.to - 1 : op.to } };
|
|
2956
|
+
}
|
|
2957
|
+
function namesSheet(m, id) {
|
|
2958
|
+
const rs = refSheetsOf(m);
|
|
2959
|
+
return !!rs && Object.values(rs).includes(id) && (m.id === ID.setName || hasFormula(m));
|
|
2960
|
+
}
|
|
2961
|
+
function sheetPair(x, y, side) {
|
|
2962
|
+
const xs = isSheetOp(x);
|
|
2963
|
+
const ys = isSheetOp(y);
|
|
2964
|
+
if (!xs && !ys) return null;
|
|
2965
|
+
if (xs && ys) {
|
|
2966
|
+
const a = sheetAxisOf(x);
|
|
2967
|
+
const b = sheetAxisOf(y);
|
|
2968
|
+
if (!a || !b) return barrier2("a sheet add or remove without its index (capture must call annotateSheetOps)");
|
|
2969
|
+
if (x.id === ID.insertSheet && y.id === ID.insertSheet && sheetIdOf(x) === sheetIdOf(y)) {
|
|
2970
|
+
return JSON.stringify(x.params) === JSON.stringify(y.params) ? ok([]) : barrier2("the same sheet id added twice with different content");
|
|
2971
|
+
}
|
|
2972
|
+
if (x.id === ID.removeSheet && typeof x.params.sheetsLeft === "number" && sheetIdOf(x) !== sheetIdOf(y) && (y.id === ID.removeSheet || y.id === ID.insertSheet)) {
|
|
2973
|
+
const left = x.params.sheetsLeft + (y.id === ID.insertSheet ? 1 : -1);
|
|
2974
|
+
if (left < 1) return barrier2("concurrent sheet removes would leave the workbook without a sheet");
|
|
2975
|
+
const out2 = transformAxis(a, b, side);
|
|
2976
|
+
if (!out2) return barrier2("sheet order: no transform");
|
|
2977
|
+
return ok(out2.map((o) => buildSheetOp({ id: x.id, params: { ...x.params, sheetsLeft: left } }, o)));
|
|
2978
|
+
}
|
|
2979
|
+
const out = transformAxis(a, b, side);
|
|
2980
|
+
if (!out) return barrier2("sheet order: no transform");
|
|
2981
|
+
return ok(out.map((o) => buildSheetOp(x, o)), [], out.length === 0 && x.id === ID.sheetOrder ? [`${sheetIdOf(x)}: sheet order`] : []);
|
|
2982
|
+
}
|
|
2983
|
+
if (ys) {
|
|
2984
|
+
if (y.id !== ID.removeSheet) return ok([x]);
|
|
2985
|
+
const gone2 = sheetOf(y);
|
|
2986
|
+
if (namesSheet(x, gone2)) return barrier2("a formula names a sheet removed at the same time");
|
|
2987
|
+
if (sheetOf(x) === gone2 && x.id !== ID.setName && x.id !== ID.removeName)
|
|
2988
|
+
return ok([], [], isDerived(x) ? [] : [`${gone2}: the sheet was removed`]);
|
|
2989
|
+
return ok([x]);
|
|
2990
|
+
}
|
|
2991
|
+
if (x.id !== ID.removeSheet) return ok([x]);
|
|
2992
|
+
const gone = sheetOf(x);
|
|
2993
|
+
if (namesSheet(y, gone)) return barrier2("a formula names a sheet removed at the same time");
|
|
2994
|
+
return ok([x], sheetOf(y) === gone && !isDerived(y) && y.id !== ID.setName && y.id !== ID.removeName ? [`${gone}: the sheet was removed`] : []);
|
|
2995
|
+
}
|
|
2996
|
+
function annotateSheetOps(group, sheetOrder) {
|
|
2997
|
+
const order = [...sheetOrder];
|
|
2998
|
+
return group.map((m) => {
|
|
2999
|
+
if (m.id === ID.insertSheet) {
|
|
3000
|
+
const index = typeof m.params.index === "number" ? Math.min(m.params.index, order.length) : order.length;
|
|
3001
|
+
order.splice(index, 0, sheetIdOf(m));
|
|
3002
|
+
return index === m.params.index ? m : { id: m.id, params: { ...m.params, index } };
|
|
3003
|
+
}
|
|
3004
|
+
if (m.id === ID.removeSheet) {
|
|
3005
|
+
const i = order.indexOf(sheetOf(m));
|
|
3006
|
+
if (i >= 0) order.splice(i, 1);
|
|
3007
|
+
return i >= 0 ? { id: m.id, params: { ...m.params, sheetIndex: i, sheetsLeft: order.length } } : m;
|
|
3008
|
+
}
|
|
3009
|
+
if (m.id === ID.sheetOrder) {
|
|
3010
|
+
const f = Number(m.params.fromOrder);
|
|
3011
|
+
const [id] = order.splice(f, 1);
|
|
3012
|
+
order.splice(Number(m.params.toOrder), 0, id ?? sheetOf(m));
|
|
3013
|
+
}
|
|
3014
|
+
return m;
|
|
3015
|
+
});
|
|
3016
|
+
}
|
|
3017
|
+
function inlineSheetStyles(sheet, styleOf) {
|
|
3018
|
+
const out = JSON.parse(JSON.stringify(sheet));
|
|
3019
|
+
const fix = (o) => {
|
|
3020
|
+
if (o && typeof o.s === "string") {
|
|
3021
|
+
const st = styleOf(o.s);
|
|
3022
|
+
if (st) o.s = JSON.parse(JSON.stringify(st));
|
|
3023
|
+
}
|
|
3024
|
+
};
|
|
3025
|
+
for (const row of Object.values(out.cellData ?? {})) for (const cell of Object.values(row ?? {})) fix(cell);
|
|
3026
|
+
for (const key of ["rowData", "columnData"]) for (const v of Object.values(out[key] ?? {})) fix(v);
|
|
3027
|
+
if (typeof out.defaultStyle === "string") {
|
|
3028
|
+
const st = styleOf(out.defaultStyle);
|
|
3029
|
+
if (st) out.defaultStyle = JSON.parse(JSON.stringify(st));
|
|
3030
|
+
}
|
|
3031
|
+
return out;
|
|
3032
|
+
}
|
|
2729
3033
|
function familyOf(id) {
|
|
2730
3034
|
const e = SHEET_MUTATIONS[id];
|
|
2731
3035
|
return e && e.kind === "covered" ? e.family : "";
|
|
@@ -2742,6 +3046,8 @@ function transformMutation(x, y, side) {
|
|
|
2742
3046
|
}
|
|
2743
3047
|
const pb = PAIR_BARRIERS[pairKey(x.id, y.id)];
|
|
2744
3048
|
if (pb) return barrier2(`${x.id} \xD7 ${y.id}: ${pb.reason}${pb.seed === null ? "" : ` (fuzz seed ${pb.seed})`}`);
|
|
3049
|
+
const sp = sheetPair(x, y, side);
|
|
3050
|
+
if (sp) return sp;
|
|
2745
3051
|
const fp = formulaPair(x, y, side);
|
|
2746
3052
|
if (fp) return fp;
|
|
2747
3053
|
if (sheetOf(x) !== sheetOf(y)) return ok([x]);
|
|
@@ -2749,6 +3055,10 @@ function transformMutation(x, y, side) {
|
|
|
2749
3055
|
const fy = familyOf(y.id);
|
|
2750
3056
|
const sy = structuralOf(y);
|
|
2751
3057
|
const sx = structuralOf(x);
|
|
3058
|
+
const cp = countPair(x, y, sy);
|
|
3059
|
+
if (cp) return cp;
|
|
3060
|
+
const np = numfmtPair(x, y, side, sx, sy);
|
|
3061
|
+
if (np) return np;
|
|
2752
3062
|
if (sx && sy) {
|
|
2753
3063
|
if (sx.axis !== sy.axis) return ok([x]);
|
|
2754
3064
|
const out = transformAxis(sx.op, sy.op, side);
|
|
@@ -2856,22 +3166,45 @@ function tSeq(xs, ys, side, acc) {
|
|
|
2856
3166
|
acc.dropped.push(...a.dropped);
|
|
2857
3167
|
return [a.op, b.op];
|
|
2858
3168
|
}
|
|
3169
|
+
const outX = [];
|
|
3170
|
+
let curY = ys;
|
|
3171
|
+
for (const x of xs) {
|
|
3172
|
+
let curX = [x];
|
|
3173
|
+
const nextY = [];
|
|
3174
|
+
for (const y of curY) {
|
|
3175
|
+
if (curX.length === 0) {
|
|
3176
|
+
nextY.push(y);
|
|
3177
|
+
continue;
|
|
3178
|
+
}
|
|
3179
|
+
const r = tSeq(curX, [y], side, acc);
|
|
3180
|
+
if (blocked(r)) return r;
|
|
3181
|
+
curX = r[0];
|
|
3182
|
+
for (const m of r[1]) nextY.push(m);
|
|
3183
|
+
}
|
|
3184
|
+
for (const m of curX) outX.push(m);
|
|
3185
|
+
curY = nextY;
|
|
3186
|
+
}
|
|
3187
|
+
return [outX, curY];
|
|
3188
|
+
}
|
|
3189
|
+
function tSeqOld(xs, ys, side, acc) {
|
|
3190
|
+
if (xs.length === 0 || ys.length === 0) return [xs, ys];
|
|
3191
|
+
if (xs.length === 1 && ys.length === 1) return tSeq(xs, ys, side, acc);
|
|
2859
3192
|
if (xs.length > 1) {
|
|
2860
|
-
const first2 =
|
|
3193
|
+
const first2 = tSeqOld([xs[0]], ys, side, acc);
|
|
2861
3194
|
if (blocked(first2)) return first2;
|
|
2862
|
-
const rest2 =
|
|
3195
|
+
const rest2 = tSeqOld(xs.slice(1), first2[1], side, acc);
|
|
2863
3196
|
if (blocked(rest2)) return rest2;
|
|
2864
3197
|
return [[...first2[0], ...rest2[0]], rest2[1]];
|
|
2865
3198
|
}
|
|
2866
|
-
const first =
|
|
3199
|
+
const first = tSeqOld(xs, [ys[0]], side, acc);
|
|
2867
3200
|
if (blocked(first)) return first;
|
|
2868
|
-
const rest =
|
|
3201
|
+
const rest = tSeqOld(first[0], ys.slice(1), side, acc);
|
|
2869
3202
|
if (blocked(rest)) return rest;
|
|
2870
3203
|
return [rest[0], [...first[1], ...rest[1]]];
|
|
2871
3204
|
}
|
|
2872
3205
|
function transformGroup(x, y, side) {
|
|
2873
3206
|
const acc = { lost: [], dropped: [] };
|
|
2874
|
-
const r = tSeq([...x], [...y], side, acc);
|
|
3207
|
+
const r = (process.env.OLD_TSEQ ? tSeqOld : tSeq)([...x], [...y], side, acc);
|
|
2875
3208
|
if (blocked(r)) return r;
|
|
2876
3209
|
return { op: r[0], lost: [...new Set(acc.lost)], dropped: [...new Set(acc.dropped)] };
|
|
2877
3210
|
}
|
|
@@ -2941,7 +3274,7 @@ async function sheetsStateHash(snapshot) {
|
|
|
2941
3274
|
}
|
|
2942
3275
|
|
|
2943
3276
|
// src/univer/collab/sheets-ot/room.ts
|
|
2944
|
-
var SHEETS_COLLAB_PROTO =
|
|
3277
|
+
var SHEETS_COLLAB_PROTO = 2;
|
|
2945
3278
|
var SHEETS_EDIT_GROUP = "sheets.edit";
|
|
2946
3279
|
var flip2 = (side) => side === "left" ? "right" : "left";
|
|
2947
3280
|
var isNoopSheetOp = (op) => op == null || op.length === 0;
|
|
@@ -2988,6 +3321,11 @@ function travelingShape(m) {
|
|
|
2988
3321
|
}
|
|
2989
3322
|
return { id: m.id, params };
|
|
2990
3323
|
}
|
|
3324
|
+
var shapedLists = /* @__PURE__ */ new WeakMap();
|
|
3325
|
+
function cachedShape(list) {
|
|
3326
|
+
const hit = shapedLists.get(list);
|
|
3327
|
+
return hit && hit.src.length === list.length && hit.src.every((m, i) => m === list[i]) ? hit.shaped : null;
|
|
3328
|
+
}
|
|
2991
3329
|
function rebaseSheetUndoStack(items, remote, unitId) {
|
|
2992
3330
|
if (isNoopSheetOp(remote)) return 0;
|
|
2993
3331
|
let dropped = 0;
|
|
@@ -2999,7 +3337,11 @@ function rebaseSheetUndoStack(items, remote, unitId) {
|
|
|
2999
3337
|
if (!ok2 || !list?.length) continue;
|
|
3000
3338
|
const isOperation = (id) => !SHEET_MUTATIONS[id] && id.includes(".operation.");
|
|
3001
3339
|
const operations = list.filter((m) => isOperation(m.id));
|
|
3002
|
-
|
|
3340
|
+
let shaped = cachedShape(list);
|
|
3341
|
+
if (!shaped) {
|
|
3342
|
+
shaped = list.filter((m) => !isOperation(m.id)).map(travelingShape);
|
|
3343
|
+
shapedLists.set(list, { src: list.slice(), shaped });
|
|
3344
|
+
}
|
|
3003
3345
|
if (shaped.some((m) => m === null)) {
|
|
3004
3346
|
ok2 = false;
|
|
3005
3347
|
continue;
|
|
@@ -3011,8 +3353,10 @@ function rebaseSheetUndoStack(items, remote, unitId) {
|
|
|
3011
3353
|
ok2 = false;
|
|
3012
3354
|
continue;
|
|
3013
3355
|
}
|
|
3014
|
-
if (
|
|
3015
|
-
|
|
3356
|
+
if (r.op.length === shaped.length && r.op.every((m, i2) => m === shaped[i2])) continue;
|
|
3357
|
+
const next = [...r.op.map((m) => ({ id: m.id, params: { ...forApply(m).params, unitId } })), ...operations];
|
|
3358
|
+
shapedLists.set(next, { src: next.slice(), shaped: r.op });
|
|
3359
|
+
item[key] = next;
|
|
3016
3360
|
} catch {
|
|
3017
3361
|
ok2 = false;
|
|
3018
3362
|
}
|
|
@@ -3087,7 +3431,7 @@ function createSheetsOtAdapter(port, hooks = {}) {
|
|
|
3087
3431
|
});
|
|
3088
3432
|
});
|
|
3089
3433
|
}
|
|
3090
|
-
return sheetsStateHash(port.snapshot());
|
|
3434
|
+
return (hooks.stateHash ?? sheetsStateHash)(port.snapshot());
|
|
3091
3435
|
},
|
|
3092
3436
|
held: () => queue.length,
|
|
3093
3437
|
rebaseLocalOverHeld(local) {
|
|
@@ -3199,6 +3543,8 @@ var VALUES = "sheet.mutation.set-range-values";
|
|
|
3199
3543
|
var ADD_MERGE = "sheet.mutation.add-worksheet-merge";
|
|
3200
3544
|
var REMOVE_MERGE = "sheet.mutation.remove-worksheet-merge";
|
|
3201
3545
|
var SHEET_NAME = "sheet.mutation.set-worksheet-name";
|
|
3546
|
+
var INSERT_SHEET = "sheet.mutation.insert-sheet";
|
|
3547
|
+
var RESHAPE = /* @__PURE__ */ new Set(["sheet.mutation.set-worksheet-row-count", "sheet.mutation.set-worksheet-column-count", "sheet.mutation.remove-sheet", INSERT_SHEET]);
|
|
3202
3548
|
var DEPTH_GUARD = /* @__PURE__ */ Symbol.for("ai-matrx.office.sheets.command-depth-guard");
|
|
3203
3549
|
var json = (v) => v === void 0 ? v : JSON.parse(JSON.stringify(v));
|
|
3204
3550
|
var flagged = (options) => {
|
|
@@ -3235,7 +3581,8 @@ function univerSheetsOtPort(o) {
|
|
|
3235
3581
|
for (const [id, d] of Object.entries(map)) out[id] = String(d?.name ?? "");
|
|
3236
3582
|
return out;
|
|
3237
3583
|
};
|
|
3238
|
-
const
|
|
3584
|
+
const sheetOrder = () => (o.workbook()?.getSheets() ?? []).map((ws) => ws.getSheetId());
|
|
3585
|
+
const openGroup = (label) => ({ label, order: sheetOrder(), sheets: sheetNames(), names: definedNames(), mutations: [], inverses: [], notShared: null });
|
|
3239
3586
|
const emit = (e) => {
|
|
3240
3587
|
for (const l of [...listeners]) {
|
|
3241
3588
|
try {
|
|
@@ -3251,7 +3598,8 @@ function univerSheetsOtPort(o) {
|
|
|
3251
3598
|
if (!g) return;
|
|
3252
3599
|
if (g.notShared) emit({ kind: "not_shared", mutationId: g.notShared, label: g.label });
|
|
3253
3600
|
else if (g.mutations.length) {
|
|
3254
|
-
const mutations = annotateFormulas(g.mutations, g.sheets, g.names);
|
|
3601
|
+
const mutations = annotateSheetOps(annotateFormulas(g.mutations, g.sheets, g.names), g.order);
|
|
3602
|
+
if (mutations.some((m) => isStructuralMutation(m) || RESHAPE.has(m.id))) clampSelection();
|
|
3255
3603
|
const known = g.inverses.every((i) => i !== void 0);
|
|
3256
3604
|
const inverse = known ? annotateFormulas(g.inverses.slice().reverse().flat(), g.sheets, g.names) : void 0;
|
|
3257
3605
|
emit({ kind: "group", mutations, ...inverse !== void 0 ? { inverse } : {}, label: g.label });
|
|
@@ -3285,7 +3633,27 @@ function univerSheetsOtPort(o) {
|
|
|
3285
3633
|
}
|
|
3286
3634
|
if (info.id === SHEET_NAME) record.name = ws.getName();
|
|
3287
3635
|
pre.set(p, record);
|
|
3636
|
+
const owed = isStructuralMutation({ id: info.id, params: p }) ? mergeFixupsOwed({ id: info.id, params: p }, record.merges ?? []) : null;
|
|
3637
|
+
if (owed) {
|
|
3638
|
+
runOwn(REMOVE_MERGE, String(p.subUnitId), owed.remove, ADD_MERGE);
|
|
3639
|
+
if (owed.add.length) record.addAfter = owed.add;
|
|
3640
|
+
}
|
|
3288
3641
|
});
|
|
3642
|
+
const runOwn = (id, sheet, ranges, inverseId) => {
|
|
3643
|
+
const u = unitId();
|
|
3644
|
+
if (!u) return;
|
|
3645
|
+
applying = true;
|
|
3646
|
+
try {
|
|
3647
|
+
cs.syncExecuteCommand(id, { unitId: u, subUnitId: sheet, ranges: json(ranges) }, { onlyLocal: true });
|
|
3648
|
+
} finally {
|
|
3649
|
+
applying = false;
|
|
3650
|
+
}
|
|
3651
|
+
if (!group) group = openGroup(null);
|
|
3652
|
+
if (!group.notShared) {
|
|
3653
|
+
group.mutations.push({ id, params: { subUnitId: sheet, ranges: json(ranges) } });
|
|
3654
|
+
group.inverses.push([{ id: inverseId, params: { subUnitId: sheet, ranges: json(ranges) } }]);
|
|
3655
|
+
}
|
|
3656
|
+
};
|
|
3289
3657
|
const after = cs.onCommandExecuted((info) => {
|
|
3290
3658
|
if (info.type !== COMMAND) return;
|
|
3291
3659
|
const at = tracker.stack.lastIndexOf(info.id);
|
|
@@ -3383,6 +3751,8 @@ function univerSheetsOtPort(o) {
|
|
|
3383
3751
|
if (!m2) return { m: null, inverse: void 0 };
|
|
3384
3752
|
return { m: m2, inverse: [{ id: ADD_MERGE, params: { subUnitId: sheet, ranges: json(m2.params.ranges) } }] };
|
|
3385
3753
|
}
|
|
3754
|
+
if (info.id === INSERT_SHEET && params.sheet && typeof params.sheet === "object")
|
|
3755
|
+
params.sheet = inlineSheetStyles(params.sheet, (id) => o.workbook()?.getStyles().get(id));
|
|
3386
3756
|
const m = { id: info.id, params };
|
|
3387
3757
|
switch (info.id) {
|
|
3388
3758
|
case "sheet.mutation.insert-row":
|
|
@@ -3399,8 +3769,7 @@ function univerSheetsOtPort(o) {
|
|
|
3399
3769
|
};
|
|
3400
3770
|
const collab = cs.onMutationExecutedForCollab((info, options) => {
|
|
3401
3771
|
if (applying || flagged(options) || !mine(info.params)) return;
|
|
3402
|
-
|
|
3403
|
-
if (lone) group = openGroup(null);
|
|
3772
|
+
if (!group) group = openGroup(null);
|
|
3404
3773
|
const g = group;
|
|
3405
3774
|
if (!g.notShared) {
|
|
3406
3775
|
const r = capture(info);
|
|
@@ -3410,11 +3779,29 @@ function univerSheetsOtPort(o) {
|
|
|
3410
3779
|
g.inverses.push(r.inverse);
|
|
3411
3780
|
}
|
|
3412
3781
|
}
|
|
3413
|
-
|
|
3782
|
+
const owedAdd = pre.get(info.params)?.addAfter;
|
|
3783
|
+
if (owedAdd?.length) runOwn(ADD_MERGE, String(info.params.subUnitId ?? ""), owedAdd, REMOVE_MERGE);
|
|
3784
|
+
if (tracker.stack.length === 0) settle();
|
|
3414
3785
|
});
|
|
3786
|
+
const clampSelection = () => {
|
|
3787
|
+
const sel = o.selections;
|
|
3788
|
+
if (!sel) return;
|
|
3789
|
+
try {
|
|
3790
|
+
const sheet = sel.sheetId();
|
|
3791
|
+
const ws = sheet ? o.workbook()?.getSheetBySheetId(sheet) : null;
|
|
3792
|
+
const current = sel.get();
|
|
3793
|
+
if (!ws || !current?.length) return;
|
|
3794
|
+
const rows = ws.getMaxRows?.() ?? Number.MAX_SAFE_INTEGER;
|
|
3795
|
+
const cols = ws.getMaxColumns?.() ?? Number.MAX_SAFE_INTEGER;
|
|
3796
|
+
const next = moveSelectionsThrough(json(current), { id: "", params: {} }, rows, cols);
|
|
3797
|
+
if (JSON.stringify(next) !== JSON.stringify(current)) sel.set(next);
|
|
3798
|
+
} catch (err) {
|
|
3799
|
+
console.warn("[sheets-ot] could not keep this seat's selection inside the sheet after its own row or column change", err);
|
|
3800
|
+
}
|
|
3801
|
+
};
|
|
3415
3802
|
const followSelection = (m) => {
|
|
3416
3803
|
const sel = o.selections;
|
|
3417
|
-
if (!sel || !axisOpOf(m)) return;
|
|
3804
|
+
if (!sel || !axisOpOf(m) && !RESHAPE.has(m.id)) return;
|
|
3418
3805
|
try {
|
|
3419
3806
|
const sheet = String(m.params.subUnitId ?? "");
|
|
3420
3807
|
if (sel.sheetId() !== sheet) return;
|