@ai-matrx/office 0.8.16 → 0.8.18
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 +39 -2
- package/dist/{chunk-HX5TXQIX.cjs → chunk-JMVPAJJA.cjs} +6 -5
- package/dist/chunk-JMVPAJJA.cjs.map +1 -0
- package/dist/{chunk-2X3KR6Y4.js → chunk-TRA2BTPL.js} +6 -5
- package/dist/{chunk-2X3KR6Y4.js.map → chunk-TRA2BTPL.js.map} +1 -1
- package/dist/docs-io.cjs +6 -6
- package/dist/docs-io.js +1 -1
- package/dist/docs.cjs +2 -2
- package/dist/docs.d.cts +5 -1
- package/dist/docs.d.ts +5 -1
- package/dist/docs.js +1 -1
- package/dist/univer-collab.cjs +224 -34
- package/dist/univer-collab.cjs.map +1 -1
- package/dist/univer-collab.d.cts +40 -12
- package/dist/univer-collab.d.ts +40 -12
- package/dist/univer-collab.js +206 -15
- package/dist/univer-collab.js.map +1 -1
- package/package.json +2 -2
- package/dist/chunk-HX5TXQIX.cjs.map +0 -1
package/dist/univer-collab.cjs
CHANGED
|
@@ -41,6 +41,7 @@ __export(collab_exports, {
|
|
|
41
41
|
SHEETS_EDIT_GROUP: () => SHEETS_EDIT_GROUP,
|
|
42
42
|
WorkbookCollabSession: () => WorkbookCollabSession,
|
|
43
43
|
applyDocsOp: () => applyDocsOp,
|
|
44
|
+
asLoadedDocsSnapshot: () => asLoadedDocsSnapshot,
|
|
44
45
|
canonicalDocsSnapshot: () => canonicalDocsSnapshot,
|
|
45
46
|
canonicalDocsString: () => canonicalDocsString,
|
|
46
47
|
canonicalKeys: () => canonicalKeys,
|
|
@@ -57,6 +58,7 @@ __export(collab_exports, {
|
|
|
57
58
|
invertDocsOp: () => invertDocsOp,
|
|
58
59
|
isCellEditorScratch: () => isCellEditorScratch,
|
|
59
60
|
isNoopDocsOp: () => isNoopDocsOp,
|
|
61
|
+
moveSelectionsThrough: () => moveSelectionsThrough,
|
|
60
62
|
normalizeDocsOp: () => normalizeDocsOp,
|
|
61
63
|
openDocsOtRoom: () => openDocsOtRoom,
|
|
62
64
|
openSheetsOtRoom: () => openSheetsOtRoom,
|
|
@@ -948,6 +950,104 @@ function invertDocsOp(op, preDoc) {
|
|
|
948
950
|
}
|
|
949
951
|
var DOCS_TRANSFORM_VERSION = "univer-1.0.4+docs-ot-r6";
|
|
950
952
|
|
|
953
|
+
// src/univer/collab/docs-ot/state-hash.ts
|
|
954
|
+
var import_core4 = require("@univerjs/core");
|
|
955
|
+
|
|
956
|
+
// src/docs/sanitize-univer-doc-snapshot.ts
|
|
957
|
+
var import_core2 = require("@univerjs/core");
|
|
958
|
+
|
|
959
|
+
// src/core/document-page-style.ts
|
|
960
|
+
var TRADITIONAL = 1;
|
|
961
|
+
var PORTRAIT = 0;
|
|
962
|
+
var PX_PER_INCH = 96;
|
|
963
|
+
var DEFAULT_DOCUMENT_PAGE_STYLE = {
|
|
964
|
+
pageSize: { width: 816, height: 1056 },
|
|
965
|
+
documentFlavor: TRADITIONAL,
|
|
966
|
+
pageOrient: PORTRAIT,
|
|
967
|
+
marginTop: PX_PER_INCH,
|
|
968
|
+
marginBottom: PX_PER_INCH,
|
|
969
|
+
marginLeft: PX_PER_INCH,
|
|
970
|
+
marginRight: PX_PER_INCH,
|
|
971
|
+
// Univer applies no paragraph spacing to a paginated page by itself; without this every paragraph
|
|
972
|
+
// runs into the next (Google Docs' own default: 1.15 lines, 10px after).
|
|
973
|
+
defaultParagraphStyle: { spaceAbove: { v: 0 }, spaceBelow: { v: 10 }, lineSpacing: 1.15 }
|
|
974
|
+
};
|
|
975
|
+
function defaultDocumentPageStyle() {
|
|
976
|
+
return {
|
|
977
|
+
...DEFAULT_DOCUMENT_PAGE_STYLE,
|
|
978
|
+
pageSize: { ...DEFAULT_DOCUMENT_PAGE_STYLE.pageSize },
|
|
979
|
+
defaultParagraphStyle: { ...DEFAULT_DOCUMENT_PAGE_STYLE.defaultParagraphStyle }
|
|
980
|
+
};
|
|
981
|
+
}
|
|
982
|
+
function isLegacySqueezedPageStyle(style) {
|
|
983
|
+
const size = style?.pageSize;
|
|
984
|
+
return !!size && size.width === 595 && size.height === 842 && style?.marginLeft === 90 && style?.marginRight === 90 && style?.marginTop === 72 && style?.marginBottom === 72;
|
|
985
|
+
}
|
|
986
|
+
var PAGE_COLORS = ["#ffffff", "#fff8e7", "#f3f3f3", "#e8f0fe", "#e6f4ea", "#fef7e0"];
|
|
987
|
+
var DEFAULT_PAGE_COLOR = PAGE_COLORS[0];
|
|
988
|
+
|
|
989
|
+
// src/docs/sanitize-univer-doc-snapshot.ts
|
|
990
|
+
var NAMED_STYLE_STRING_TO_NUMBER = Object.fromEntries(
|
|
991
|
+
Object.entries(import_core2.NamedStyleType).filter(([key, val]) => typeof val === "number" && isNaN(Number(key))).map(([key, val]) => [key, val])
|
|
992
|
+
);
|
|
993
|
+
function sanitizeUniverDocSnapshot(snapshot, docId, opts = {}) {
|
|
994
|
+
restorePageStyle(snapshot, docId, opts.quiet === true);
|
|
995
|
+
ensureTextRuns(snapshot);
|
|
996
|
+
const paragraphs = snapshot?.body?.paragraphs;
|
|
997
|
+
if (!Array.isArray(paragraphs)) return snapshot;
|
|
998
|
+
let fixed = 0;
|
|
999
|
+
for (const paragraph of paragraphs) {
|
|
1000
|
+
const style = paragraph?.paragraphStyle;
|
|
1001
|
+
const value = style?.namedStyleType;
|
|
1002
|
+
if (typeof value === "string") {
|
|
1003
|
+
const numeric = NAMED_STYLE_STRING_TO_NUMBER[value];
|
|
1004
|
+
if (numeric !== void 0) {
|
|
1005
|
+
style.namedStyleType = numeric;
|
|
1006
|
+
fixed += 1;
|
|
1007
|
+
} else {
|
|
1008
|
+
delete style.namedStyleType;
|
|
1009
|
+
fixed += 1;
|
|
1010
|
+
}
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
if (fixed > 0 && opts.quiet !== true) {
|
|
1014
|
+
console.warn(
|
|
1015
|
+
`[data-tables] RECOVERY: sanitized ${fixed} string namedStyleType value(s) to numeric NamedStyleType in document snapshot${docId ? ` ${docId}` : ""}. The snapshot was written with the wrong enum encoding (string instead of number) and would have crashed Univer's <ParagraphMenu>. Fix the snapshot writer to emit numeric NamedStyleType values.`
|
|
1016
|
+
);
|
|
1017
|
+
}
|
|
1018
|
+
return snapshot;
|
|
1019
|
+
}
|
|
1020
|
+
function restorePageStyle(snapshot, docId, quiet = false) {
|
|
1021
|
+
if (!snapshot || typeof snapshot !== "object") return;
|
|
1022
|
+
const style = snapshot.documentStyle;
|
|
1023
|
+
if (style?.pageSize?.width && isLegacySqueezedPageStyle(style)) {
|
|
1024
|
+
const page = defaultDocumentPageStyle();
|
|
1025
|
+
snapshot.documentStyle = { ...style, ...page, defaultParagraphStyle: style.defaultParagraphStyle ?? page.defaultParagraphStyle };
|
|
1026
|
+
return;
|
|
1027
|
+
}
|
|
1028
|
+
if (style?.pageSize?.width) {
|
|
1029
|
+
if (!style.documentFlavor) {
|
|
1030
|
+
const page = defaultDocumentPageStyle();
|
|
1031
|
+
Object.assign(style, { documentFlavor: page.documentFlavor });
|
|
1032
|
+
if (page.defaultParagraphStyle) style.defaultParagraphStyle ??= page.defaultParagraphStyle;
|
|
1033
|
+
}
|
|
1034
|
+
return;
|
|
1035
|
+
}
|
|
1036
|
+
snapshot.documentStyle = {
|
|
1037
|
+
...defaultDocumentPageStyle(),
|
|
1038
|
+
...snapshot.documentStyle ?? {},
|
|
1039
|
+
pageSize: defaultDocumentPageStyle().pageSize
|
|
1040
|
+
};
|
|
1041
|
+
if (quiet) return;
|
|
1042
|
+
console.warn(
|
|
1043
|
+
`[data-tables] RECOVERY: document snapshot${docId ? ` ${docId}` : ""} had no documentStyle.pageSize \u2014 restored the default Letter page geometry. Without a page box Univer lays the body out unbounded: text does not wrap and the viewport has no scrollable extent, so the document appears frozen. Fix the snapshot writer (agent/markdown converters must stamp DEFAULT_DOCUMENT_PAGE_STYLE).`
|
|
1044
|
+
);
|
|
1045
|
+
}
|
|
1046
|
+
function ensureTextRuns(snapshot) {
|
|
1047
|
+
const body = snapshot?.body;
|
|
1048
|
+
if (body && typeof body === "object" && !Array.isArray(body.textRuns)) body.textRuns = [];
|
|
1049
|
+
}
|
|
1050
|
+
|
|
951
1051
|
// src/univer/collab/docs-ot/state-hash.ts
|
|
952
1052
|
var DOC_LOCAL_KEYS = ["rev", "__matrxCollabCovered", "__collab", "disabled", "layoutState", "textRanges", "selections"];
|
|
953
1053
|
function sortDeep(v) {
|
|
@@ -1007,6 +1107,7 @@ function canonicalBody(body) {
|
|
|
1007
1107
|
const b = { ...body };
|
|
1008
1108
|
b.textRuns = canonicalRuns(b.textRuns);
|
|
1009
1109
|
if (Array.isArray(b.paragraphs)) b.paragraphs = b.paragraphs.map(({ paragraphId: _p, ...p }) => p);
|
|
1110
|
+
if (Array.isArray(b.sectionBreaks)) b.sectionBreaks = b.sectionBreaks.map(({ sectionId: _s, ...x }) => x);
|
|
1010
1111
|
b.customRanges = foldPieces(b.customRanges, (r) => JSON.stringify([rootId(r.rangeId), r.rangeType, sortDeep(r.properties ?? {})])).map((r) => ({
|
|
1011
1112
|
...r,
|
|
1012
1113
|
rangeId: rootId(r.rangeId)
|
|
@@ -1021,8 +1122,20 @@ function canonicalBody(body) {
|
|
|
1021
1122
|
}
|
|
1022
1123
|
return b;
|
|
1023
1124
|
}
|
|
1125
|
+
function asLoadedDocsSnapshot(snapshot) {
|
|
1126
|
+
const s = stampDeterministicIds(structuredClone(snapshot ?? {}));
|
|
1127
|
+
delete s.id;
|
|
1128
|
+
for (const k of DOC_LOCAL_KEYS) delete s[k];
|
|
1129
|
+
sanitizeUniverDocSnapshot(s, void 0, { quiet: true });
|
|
1130
|
+
const model = new import_core4.DocumentDataModel(s);
|
|
1131
|
+
try {
|
|
1132
|
+
return structuredClone(model.getSnapshot());
|
|
1133
|
+
} finally {
|
|
1134
|
+
model.dispose();
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
1024
1137
|
function canonicalDocsSnapshot(snapshot) {
|
|
1025
|
-
const s =
|
|
1138
|
+
const s = asLoadedDocsSnapshot(snapshot);
|
|
1026
1139
|
delete s.id;
|
|
1027
1140
|
for (const k of DOC_LOCAL_KEYS) delete s[k];
|
|
1028
1141
|
s.body = canonicalBody(s.body);
|
|
@@ -1231,7 +1344,10 @@ function openDocsOtRoom(o) {
|
|
|
1231
1344
|
queue = next.filter((q) => !isNoopDocsOp(q));
|
|
1232
1345
|
if (isNoopDocsOp(op)) return;
|
|
1233
1346
|
}
|
|
1234
|
-
if (!session.local(op, { ...inverse !== void 0 ? { inverse } : {}, label: m.cmd ?? RICH_TEXT_EDITING }))
|
|
1347
|
+
if (!session.local(op, { ...inverse !== void 0 ? { inverse } : {}, label: m.cmd ?? RICH_TEXT_EDITING })) {
|
|
1348
|
+
notice({ kind: "not_live" });
|
|
1349
|
+
session.rebuild("not_live");
|
|
1350
|
+
}
|
|
1235
1351
|
};
|
|
1236
1352
|
const unsubLocal = port.onLocal(onLocal);
|
|
1237
1353
|
const target = o.compositionTarget === void 0 ? typeof document !== "undefined" ? document : null : o.compositionTarget;
|
|
@@ -1293,7 +1409,7 @@ var import_awareness2 = require("y-protocols/awareness");
|
|
|
1293
1409
|
var import_collab3 = require("@ai-matrx/data/realtime/collab");
|
|
1294
1410
|
|
|
1295
1411
|
// src/docs/remote-carets.ts
|
|
1296
|
-
var
|
|
1412
|
+
var import_core5 = require("@univerjs/core");
|
|
1297
1413
|
var CARET_HEARTBEAT_MS = 2e3;
|
|
1298
1414
|
var CARET_STALE_MS = 12e3;
|
|
1299
1415
|
var CARET_MAX_RANGES = 4;
|
|
@@ -1311,8 +1427,8 @@ function movePeerRangesThroughBodyEdit(ranges, actions) {
|
|
|
1311
1427
|
const e = sub.e;
|
|
1312
1428
|
return ranges.map((r) => {
|
|
1313
1429
|
const collapsed = r.start === r.end;
|
|
1314
|
-
const start =
|
|
1315
|
-
return { start, end: collapsed ? start :
|
|
1430
|
+
const start = import_core5.TextX.transformPosition(e, r.start, false);
|
|
1431
|
+
return { start, end: collapsed ? start : import_core5.TextX.transformPosition(e, r.end, true) };
|
|
1316
1432
|
});
|
|
1317
1433
|
}
|
|
1318
1434
|
var sameRanges = (a, b) => a.length === b.length && a.every((r, i) => r.start === b[i].start && r.end === b[i].end);
|
|
@@ -1450,15 +1566,6 @@ async function documentUsesOrderedRoom(documentId, knob, isNewDocument) {
|
|
|
1450
1566
|
if (knob === "new") return isNewDocument();
|
|
1451
1567
|
return false;
|
|
1452
1568
|
}
|
|
1453
|
-
function pickColor2(uid) {
|
|
1454
|
-
const palette = ["#ef4444", "#f59e0b", "#10b981", "#3b82f6", "#8b5cf6", "#ec4899", "#14b8a6", "#f97316"];
|
|
1455
|
-
let h = 2166136261;
|
|
1456
|
-
for (let i = 0; i < uid.length; i++) {
|
|
1457
|
-
h ^= uid.charCodeAt(i);
|
|
1458
|
-
h = Math.imul(h, 16777619);
|
|
1459
|
-
}
|
|
1460
|
-
return palette[Math.abs(h) % palette.length] ?? "#ec4899";
|
|
1461
|
-
}
|
|
1462
1569
|
function documentOtFactory(o) {
|
|
1463
1570
|
return async (basePort, onAwareness) => {
|
|
1464
1571
|
const latest = await getLatestDocumentSnapshot(o.documentId);
|
|
@@ -1472,7 +1579,8 @@ function documentOtFactory(o) {
|
|
|
1472
1579
|
}
|
|
1473
1580
|
const doc = new Y2.Doc();
|
|
1474
1581
|
const awareness = new import_awareness2.Awareness(doc);
|
|
1475
|
-
awareness.setLocalState({ uid: o.uid, clientId: o.clientId, name: o.displayName ?? o.uid.slice(0, 8),
|
|
1582
|
+
awareness.setLocalState({ uid: o.uid, clientId: o.clientId, name: o.displayName ?? o.uid.slice(0, 8), ts: Date.now() });
|
|
1583
|
+
const stopColor = (0, import_collab3.claimCollaboratorColor)(awareness, { uid: o.uid, clientId: o.clientId });
|
|
1476
1584
|
const carets = new RemoteCaretBook(awareness.clientID);
|
|
1477
1585
|
const emit = () => onAwareness({ states: new Map(awareness.getStates()), selfUid: o.uid, carets: carets.list() });
|
|
1478
1586
|
const publishAwareness = () => {
|
|
@@ -1558,6 +1666,7 @@ function documentOtFactory(o) {
|
|
|
1558
1666
|
replace: (snapshot) => room.replace(snapshot),
|
|
1559
1667
|
stop: () => {
|
|
1560
1668
|
clearInterval(caretTimer);
|
|
1669
|
+
stopColor();
|
|
1561
1670
|
room.stop();
|
|
1562
1671
|
awareness.off("change", publishAwareness);
|
|
1563
1672
|
provider.disconnect();
|
|
@@ -1879,7 +1988,7 @@ function transformAxis(x, y, side) {
|
|
|
1879
1988
|
}
|
|
1880
1989
|
|
|
1881
1990
|
// src/collab/sheets/transform/formula.ts
|
|
1882
|
-
var
|
|
1991
|
+
var import_core6 = require("@univerjs/core");
|
|
1883
1992
|
var import_engine_formula = require("@univerjs/engine-formula");
|
|
1884
1993
|
var import_sheets = require("@univerjs/sheets");
|
|
1885
1994
|
var REF_ERROR = "#REF!";
|
|
@@ -1931,8 +2040,8 @@ function referencedSheetNames(text) {
|
|
|
1931
2040
|
}
|
|
1932
2041
|
return [...out];
|
|
1933
2042
|
}
|
|
1934
|
-
var fullRowsRange = (start, count) => ({ startRow: start, endRow: start + count - 1, startColumn: 0, endColumn: FULL, rangeType:
|
|
1935
|
-
var fullColsRange = (start, count) => ({ startRow: 0, endRow: FULL, startColumn: start, endColumn: start + count - 1, rangeType:
|
|
2043
|
+
var fullRowsRange = (start, count) => ({ startRow: start, endRow: start + count - 1, startColumn: 0, endColumn: FULL, rangeType: import_core6.RANGE_TYPE.ROW });
|
|
2044
|
+
var fullColsRange = (start, count) => ({ startRow: 0, endRow: FULL, startColumn: start, endColumn: start + count - 1, rangeType: import_core6.RANGE_TYPE.COLUMN });
|
|
1936
2045
|
var startV = (v) => Number.isNaN(v) || v == null ? -Infinity : v;
|
|
1937
2046
|
var endV = (v) => Number.isNaN(v) || v == null ? Infinity : v;
|
|
1938
2047
|
function startEnd(r) {
|
|
@@ -1941,9 +2050,9 @@ function startEnd(r) {
|
|
|
1941
2050
|
function checkMoveEdge(origin, from) {
|
|
1942
2051
|
const startRow = startV(origin.startRow), endRow = endV(origin.endRow), startColumn = startV(origin.startColumn), endColumn = endV(origin.endColumn);
|
|
1943
2052
|
const fromStartRow = startV(from.startRow), fromEndRow = endV(from.endRow), fromStartColumn = startV(from.startColumn), fromEndColumn = endV(from.endColumn);
|
|
1944
|
-
const rowsCover = () => origin.rangeType ===
|
|
1945
|
-
const columnsCover = () => origin.rangeType ===
|
|
1946
|
-
const allCover = () => origin.rangeType ===
|
|
2053
|
+
const rowsCover = () => origin.rangeType === import_core6.RANGE_TYPE.COLUMN && from.rangeType === import_core6.RANGE_TYPE.COLUMN || startRow >= fromStartRow && endRow <= fromEndRow;
|
|
2054
|
+
const columnsCover = () => origin.rangeType === import_core6.RANGE_TYPE.ROW && from.rangeType === import_core6.RANGE_TYPE.ROW || startColumn >= fromStartColumn && endColumn <= fromEndColumn;
|
|
2055
|
+
const allCover = () => origin.rangeType === import_core6.RANGE_TYPE.ALL && from.rangeType === import_core6.RANGE_TYPE.ALL;
|
|
1947
2056
|
if (rowsCover() && columnsCover() || allCover()) return 4;
|
|
1948
2057
|
if (columnsCover() && startRow >= fromStartRow && startRow <= fromEndRow && endRow > fromEndRow) return 0;
|
|
1949
2058
|
if (columnsCover() && endRow >= fromStartRow && endRow <= fromEndRow && startRow < fromStartRow) return 1;
|
|
@@ -1954,14 +2063,14 @@ function checkMoveEdge(origin, from) {
|
|
|
1954
2063
|
function getMoveNewRange(moveEdge, result, from, to, origin, remain) {
|
|
1955
2064
|
const { startRow, endRow, startColumn, endColumn, rangeType } = startEnd(result);
|
|
1956
2065
|
const f = startEnd(from);
|
|
1957
|
-
const fromRangeType = from.rangeType ??
|
|
2066
|
+
const fromRangeType = from.rangeType ?? import_core6.RANGE_TYPE.NORMAL;
|
|
1958
2067
|
const t = startEnd(to);
|
|
1959
2068
|
const rm = startEnd(remain);
|
|
1960
2069
|
const o = startEnd(origin);
|
|
1961
|
-
const originRangeType = origin.rangeType ??
|
|
2070
|
+
const originRangeType = origin.rangeType ?? import_core6.RANGE_TYPE.NORMAL;
|
|
1962
2071
|
const newRange = { ...origin };
|
|
1963
|
-
const rowsCover = () => rangeType ===
|
|
1964
|
-
const columnsCover = () => rangeType ===
|
|
2072
|
+
const rowsCover = () => rangeType === import_core6.RANGE_TYPE.COLUMN && originRangeType === import_core6.RANGE_TYPE.COLUMN || startColumn >= o.startColumn && endColumn <= o.endColumn;
|
|
2073
|
+
const columnsCover = () => rangeType === import_core6.RANGE_TYPE.ROW && originRangeType === import_core6.RANGE_TYPE.ROW || startRow >= o.startRow && endRow <= o.endRow;
|
|
1965
2074
|
if (moveEdge === 0) {
|
|
1966
2075
|
if (!rowsCover()) return void 0;
|
|
1967
2076
|
if (startRow < o.startRow) newRange.startRow = startRow;
|
|
@@ -1984,7 +2093,7 @@ function getMoveNewRange(moveEdge, result, from, to, origin, remain) {
|
|
|
1984
2093
|
else return void 0;
|
|
1985
2094
|
} else if (moveEdge === 4) {
|
|
1986
2095
|
Object.assign(newRange, { startRow, startColumn, endRow, endColumn });
|
|
1987
|
-
} else if (f.startColumn <= o.startColumn && f.endColumn >= o.endColumn || fromRangeType ===
|
|
2096
|
+
} else if (f.startColumn <= o.startColumn && f.endColumn >= o.endColumn || fromRangeType === import_core6.RANGE_TYPE.ROW && originRangeType === import_core6.RANGE_TYPE.ROW) {
|
|
1988
2097
|
const n = f.endRow - f.startRow + 1;
|
|
1989
2098
|
if (from.endRow < o.startRow) {
|
|
1990
2099
|
if (t.startRow >= o.startRow) newRange.startRow -= n;
|
|
@@ -1996,7 +2105,7 @@ function getMoveNewRange(moveEdge, result, from, to, origin, remain) {
|
|
|
1996
2105
|
if (t.startRow <= o.startRow) newRange.startRow += n;
|
|
1997
2106
|
else if (t.startRow >= o.endRow) newRange.endRow -= n;
|
|
1998
2107
|
}
|
|
1999
|
-
} else if (f.startRow <= o.startRow && f.endRow >= o.endRow || fromRangeType ===
|
|
2108
|
+
} else if (f.startRow <= o.startRow && f.endRow >= o.endRow || fromRangeType === import_core6.RANGE_TYPE.COLUMN && originRangeType === import_core6.RANGE_TYPE.COLUMN) {
|
|
2000
2109
|
const n = f.endColumn - f.startColumn + 1;
|
|
2001
2110
|
if (from.endColumn < o.startColumn) {
|
|
2002
2111
|
if (t.startColumn >= o.startColumn) newRange.startColumn -= n;
|
|
@@ -2018,7 +2127,7 @@ function moveRange(range, axis, op) {
|
|
|
2018
2127
|
const isRow = axis === "row";
|
|
2019
2128
|
if (op.kind === "insert") {
|
|
2020
2129
|
const r = isRow ? fullRowsRange(op.at, op.count) : fullColsRange(op.at, op.count);
|
|
2021
|
-
const ops2 = isRow ? (0, import_sheets.handleInsertRow)({ id: import_sheets.EffectRefRangId.InsertRowCommandId, params: { range: r, unitId: "", subUnitId: "", direction:
|
|
2130
|
+
const ops2 = isRow ? (0, import_sheets.handleInsertRow)({ id: import_sheets.EffectRefRangId.InsertRowCommandId, params: { range: r, unitId: "", subUnitId: "", direction: import_core6.Direction.DOWN } }, range) : (0, import_sheets.handleInsertCol)({ id: import_sheets.EffectRefRangId.InsertColCommandId, params: { range: r, unitId: "", subUnitId: "", direction: import_core6.Direction.RIGHT } }, range);
|
|
2022
2131
|
const res2 = (0, import_sheets.runRefRangeMutations)(ops2, range);
|
|
2023
2132
|
return res2 == null ? void 0 : { ...range, ...res2 };
|
|
2024
2133
|
}
|
|
@@ -2031,11 +2140,11 @@ function moveRange(range, axis, op) {
|
|
|
2031
2140
|
const from = isRow ? fullRowsRange(op.from, op.count) : fullColsRange(op.from, op.count);
|
|
2032
2141
|
const to = isRow ? fullRowsRange(op.to, op.count) : fullColsRange(op.to, op.count);
|
|
2033
2142
|
const moveEdge = checkMoveEdge(range, from);
|
|
2034
|
-
let remain = (0,
|
|
2143
|
+
let remain = (0, import_core6.getIntersectRange)(range, from);
|
|
2035
2144
|
if (isRow) {
|
|
2036
2145
|
if (remain == null && (from.endRow < range.startRow && to.endRow <= range.startRow || from.startRow > range.endRow && to.startRow > range.endRow)) return void 0;
|
|
2037
2146
|
} else if (remain == null && (from.endColumn < range.startColumn && to.endColumn <= range.startColumn || from.startColumn > range.endColumn && to.startColumn > range.endColumn)) return void 0;
|
|
2038
|
-
remain ??= { startRow: range.startRow, endRow: range.endRow, startColumn: range.startColumn, endColumn: range.endColumn, rangeType:
|
|
2147
|
+
remain ??= { startRow: range.startRow, endRow: range.endRow, startColumn: range.startColumn, endColumn: range.endColumn, rangeType: import_core6.RANGE_TYPE.NORMAL };
|
|
2039
2148
|
const ops = isRow ? (0, import_sheets.handleMoveRows)({ id: import_sheets.EffectRefRangId.MoveRowsCommandId, params: { toRange: to, fromRange: from } }, remain) : (0, import_sheets.handleMoveCols)({ id: import_sheets.EffectRefRangId.MoveColsCommandId, params: { toRange: to, fromRange: from } }, remain);
|
|
2040
2149
|
const res = (0, import_sheets.runRefRangeMutations)(ops, remain);
|
|
2041
2150
|
if (res == null) return REF_ERROR;
|
|
@@ -2066,7 +2175,7 @@ function rewriteFormula(text, ctx, change) {
|
|
|
2066
2175
|
if (!sheetName) continue;
|
|
2067
2176
|
token = (0, import_engine_formula.serializeRangeToRefString)({ range, sheetName: change.name, unitId });
|
|
2068
2177
|
} else {
|
|
2069
|
-
const moved = moveRange(
|
|
2178
|
+
const moved = moveRange(import_core6.Rectangle.moveOffset(range, 0, 0), change.axis, change.op);
|
|
2070
2179
|
if (moved === void 0) continue;
|
|
2071
2180
|
token = moved === REF_ERROR ? REF_ERROR : (0, import_engine_formula.serializeRangeToRefString)({ range: moved, sheetName: target === ctx.ownSheet && !ctx.keepQualifier ? "" : sheetName, unitId });
|
|
2072
2181
|
}
|
|
@@ -3303,12 +3412,30 @@ function univerSheetsOtPort(o) {
|
|
|
3303
3412
|
}
|
|
3304
3413
|
if (lone && tracker.stack.length === 0) settle();
|
|
3305
3414
|
});
|
|
3415
|
+
const followSelection = (m) => {
|
|
3416
|
+
const sel = o.selections;
|
|
3417
|
+
if (!sel || !axisOpOf(m)) return;
|
|
3418
|
+
try {
|
|
3419
|
+
const sheet = String(m.params.subUnitId ?? "");
|
|
3420
|
+
if (sel.sheetId() !== sheet) return;
|
|
3421
|
+
const ws = o.workbook()?.getSheetBySheetId(sheet);
|
|
3422
|
+
const current = sel.get();
|
|
3423
|
+
if (!ws || !current?.length) return;
|
|
3424
|
+
const rows = ws.getMaxRows?.() ?? Number.MAX_SAFE_INTEGER;
|
|
3425
|
+
const cols = ws.getMaxColumns?.() ?? Number.MAX_SAFE_INTEGER;
|
|
3426
|
+
sel.set(moveSelectionsThrough(json(current), m, rows, cols));
|
|
3427
|
+
} catch (err) {
|
|
3428
|
+
console.warn("[sheets-ot] could not move this seat's selection past a collaborator's row or column change", err);
|
|
3429
|
+
}
|
|
3430
|
+
};
|
|
3306
3431
|
return {
|
|
3307
3432
|
onLocal(listener) {
|
|
3308
3433
|
listeners.add(listener);
|
|
3309
3434
|
return () => void listeners.delete(listener);
|
|
3310
3435
|
},
|
|
3311
3436
|
busy: () => tracker.stack.length > 0 || group !== null,
|
|
3437
|
+
/** The outermost commands still running here (why the port is busy), for logs. */
|
|
3438
|
+
running: () => [...tracker.stack, ...group && tracker.stack.length === 0 ? ["(group)"] : []],
|
|
3312
3439
|
whenIdle(fn) {
|
|
3313
3440
|
if (tracker.stack.length === 0 && !group) fn();
|
|
3314
3441
|
else idle.push(fn);
|
|
@@ -3319,11 +3446,12 @@ function univerSheetsOtPort(o) {
|
|
|
3319
3446
|
const a = forApply(m);
|
|
3320
3447
|
applying = true;
|
|
3321
3448
|
try {
|
|
3322
|
-
const ok2 = cs.syncExecuteCommand(a.id, { ...json(a.params), unitId: u }, {
|
|
3449
|
+
const ok2 = cs.syncExecuteCommand(a.id, { ...json(a.params), unitId: u }, { fromCollab: true });
|
|
3323
3450
|
if (ok2 === false) throw new Error(`"${m.id}" was refused by the editor`);
|
|
3324
3451
|
} finally {
|
|
3325
3452
|
applying = false;
|
|
3326
3453
|
}
|
|
3454
|
+
followSelection(m);
|
|
3327
3455
|
},
|
|
3328
3456
|
snapshot() {
|
|
3329
3457
|
const wb = o.workbook();
|
|
@@ -3361,6 +3489,68 @@ function fullContent(cell) {
|
|
|
3361
3489
|
if (out.v === null) delete out.t;
|
|
3362
3490
|
return out;
|
|
3363
3491
|
}
|
|
3492
|
+
function axisOpOf(m) {
|
|
3493
|
+
const p = m.params;
|
|
3494
|
+
const span = (r, axis) => axis === "row" ? [r.startRow, r.endRow - r.startRow + 1] : [r.startColumn, r.endColumn - r.startColumn + 1];
|
|
3495
|
+
switch (m.id) {
|
|
3496
|
+
case "sheet.mutation.insert-row": {
|
|
3497
|
+
const [at, count] = span(p.range, "row");
|
|
3498
|
+
return { axis: "row", op: { kind: "insert", at, count } };
|
|
3499
|
+
}
|
|
3500
|
+
case "sheet.mutation.insert-col": {
|
|
3501
|
+
const [at, count] = span(p.range, "col");
|
|
3502
|
+
return { axis: "col", op: { kind: "insert", at, count } };
|
|
3503
|
+
}
|
|
3504
|
+
case "sheet.mutation.remove-rows": {
|
|
3505
|
+
const [start, count] = span(p.range, "row");
|
|
3506
|
+
return { axis: "row", op: { kind: "remove", start, count } };
|
|
3507
|
+
}
|
|
3508
|
+
case "sheet.mutation.remove-col": {
|
|
3509
|
+
const [start, count] = span(p.range, "col");
|
|
3510
|
+
return { axis: "col", op: { kind: "remove", start, count } };
|
|
3511
|
+
}
|
|
3512
|
+
case "sheet.mutation.move-rows": {
|
|
3513
|
+
const [from, count] = span(p.sourceRange, "row");
|
|
3514
|
+
return { axis: "row", op: { kind: "move", from, count, to: p.targetRange.startRow } };
|
|
3515
|
+
}
|
|
3516
|
+
case "sheet.mutation.move-columns": {
|
|
3517
|
+
const [from, count] = span(p.sourceRange, "col");
|
|
3518
|
+
return { axis: "col", op: { kind: "move", from, count, to: p.targetRange.startColumn } };
|
|
3519
|
+
}
|
|
3520
|
+
default:
|
|
3521
|
+
return null;
|
|
3522
|
+
}
|
|
3523
|
+
}
|
|
3524
|
+
function moveSelectionsThrough(selections, m, maxRows, maxCols) {
|
|
3525
|
+
const a = axisOpOf(m);
|
|
3526
|
+
const clamp = (v, max) => Math.max(0, Math.min(v, Math.max(0, max - 1)));
|
|
3527
|
+
const through = (i, axis) => {
|
|
3528
|
+
if (typeof i !== "number") return i;
|
|
3529
|
+
let next = i;
|
|
3530
|
+
if (a && a.axis === axis) {
|
|
3531
|
+
const mapped = mapIndex(a.op, i);
|
|
3532
|
+
next = mapped ?? (a.op.kind === "remove" ? a.op.start : i);
|
|
3533
|
+
}
|
|
3534
|
+
return clamp(next, axis === "row" ? maxRows : maxCols);
|
|
3535
|
+
};
|
|
3536
|
+
const box = (r, rangeType) => {
|
|
3537
|
+
const out = { ...r };
|
|
3538
|
+
for (const k of ["startRow", "endRow", "actualRow"]) if (k in out) out[k] = through(out[k], "row");
|
|
3539
|
+
for (const k of ["startColumn", "endColumn", "actualColumn"]) if (k in out) out[k] = through(out[k], "col");
|
|
3540
|
+
if (typeof out.startRow === "number" && typeof out.endRow === "number" && out.endRow < out.startRow) out.endRow = out.startRow;
|
|
3541
|
+
if (typeof out.startColumn === "number" && typeof out.endColumn === "number" && out.endColumn < out.startColumn) out.endColumn = out.startColumn;
|
|
3542
|
+
if (rangeType === 1 || rangeType === 3) {
|
|
3543
|
+
out.startColumn = 0;
|
|
3544
|
+
out.endColumn = Math.max(0, maxCols - 1);
|
|
3545
|
+
}
|
|
3546
|
+
if (rangeType === 2 || rangeType === 3) {
|
|
3547
|
+
out.startRow = 0;
|
|
3548
|
+
out.endRow = Math.max(0, maxRows - 1);
|
|
3549
|
+
}
|
|
3550
|
+
return out;
|
|
3551
|
+
};
|
|
3552
|
+
return selections.map((s) => ({ ...s, range: box(s.range, s.range.rangeType), ...s.primary ? { primary: box(s.primary) } : {} }));
|
|
3553
|
+
}
|
|
3364
3554
|
|
|
3365
3555
|
// src/sheets/workbook-ot-room.ts
|
|
3366
3556
|
var Y3 = __toESM(require("yjs"), 1);
|
|
@@ -3430,7 +3620,7 @@ async function workbookUsesOrderedRoom(workbookId, knob, isNewWorkbook) {
|
|
|
3430
3620
|
if (knob === "new") return isNewWorkbook();
|
|
3431
3621
|
return false;
|
|
3432
3622
|
}
|
|
3433
|
-
function
|
|
3623
|
+
function pickColor2(uid) {
|
|
3434
3624
|
const palette = ["#ef4444", "#f59e0b", "#10b981", "#3b82f6", "#8b5cf6", "#ec4899", "#14b8a6", "#f97316"];
|
|
3435
3625
|
let h = 2166136261;
|
|
3436
3626
|
for (let i = 0; i < uid.length; i++) {
|
|
@@ -3455,7 +3645,7 @@ async function startWorkbookOtRoom(port, o) {
|
|
|
3455
3645
|
uid: o.uid,
|
|
3456
3646
|
clientId: o.clientId,
|
|
3457
3647
|
name: o.displayName ?? o.uid.slice(0, 8),
|
|
3458
|
-
color:
|
|
3648
|
+
color: pickColor2(o.uid),
|
|
3459
3649
|
sheetId: null,
|
|
3460
3650
|
row: null,
|
|
3461
3651
|
col: null,
|