@arbidocs/coedit 0.5.21 → 0.5.22
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/dist/encoding.cjs +54 -56
- package/dist/encoding.cjs.map +1 -1
- package/dist/encoding.d.cts +50 -14
- package/dist/encoding.d.ts +50 -14
- package/dist/encoding.js +54 -57
- package/dist/encoding.js.map +1 -1
- package/dist/hocuspocus.cjs +211 -109
- package/dist/hocuspocus.cjs.map +1 -1
- package/dist/hocuspocus.js +211 -109
- package/dist/hocuspocus.js.map +1 -1
- package/dist/index.cjs +210 -108
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +210 -108
- package/dist/index.js.map +1 -1
- package/dist/server.cjs +214 -112
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/server.js +214 -112
- package/dist/server.js.map +1 -1
- package/dist/template.cjs +3 -2
- package/dist/template.cjs.map +1 -1
- package/dist/template.d.cts +5 -0
- package/dist/template.d.ts +5 -0
- package/dist/template.js +3 -2
- package/dist/template.js.map +1 -1
- package/dist/{versions-DXiFQMA6.d.cts → versions-XSYTVmOU.d.cts} +1 -1
- package/dist/{versions-DXiFQMA6.d.ts → versions-XSYTVmOU.d.ts} +1 -1
- package/package.json +1 -1
package/dist/server.cjs
CHANGED
|
@@ -6,7 +6,7 @@ var replication = require('@docx-editor.dev/core/collaboration/replication');
|
|
|
6
6
|
var store = require('@docx-editor.dev/core/store');
|
|
7
7
|
var layout = require('@docx-editor.dev/core/layout');
|
|
8
8
|
var fflate = require('fflate');
|
|
9
|
-
var
|
|
9
|
+
var Y = require('yjs');
|
|
10
10
|
var collaboration = require('@docx-editor.dev/core/collaboration');
|
|
11
11
|
|
|
12
12
|
function _interopNamespace(e) {
|
|
@@ -27,7 +27,7 @@ function _interopNamespace(e) {
|
|
|
27
27
|
return Object.freeze(n);
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
var
|
|
30
|
+
var Y__namespace = /*#__PURE__*/_interopNamespace(Y);
|
|
31
31
|
|
|
32
32
|
// src/server.ts
|
|
33
33
|
|
|
@@ -896,6 +896,92 @@ function writeUnits(text, units) {
|
|
|
896
896
|
function isRichParagraph(map) {
|
|
897
897
|
return map.has("inline");
|
|
898
898
|
}
|
|
899
|
+
var PACKED = "xml";
|
|
900
|
+
function isPackedElement(map) {
|
|
901
|
+
return map.has(PACKED);
|
|
902
|
+
}
|
|
903
|
+
function isCompact(map) {
|
|
904
|
+
return isRichParagraph(map) || isPackedElement(map);
|
|
905
|
+
}
|
|
906
|
+
var TEXT_BEARING = /* @__PURE__ */ new Set(["p", "t", "delText", "instrText", "delInstrText"]);
|
|
907
|
+
function packable(xml) {
|
|
908
|
+
if (xml.ns === WML2 && TEXT_BEARING.has(xml.local)) return false;
|
|
909
|
+
return xml.children.every((c) => typeof c === "string" || packable(c));
|
|
910
|
+
}
|
|
911
|
+
function createPacked(xml, scope) {
|
|
912
|
+
const map = new Y__namespace.Map();
|
|
913
|
+
map.set(PACKED, serializeXml(xml, scope));
|
|
914
|
+
return map;
|
|
915
|
+
}
|
|
916
|
+
function repack(map, xml) {
|
|
917
|
+
const next = serializeXml(xml, scopeOf(map));
|
|
918
|
+
if (map.get(PACKED) !== next) map.set(PACKED, next);
|
|
919
|
+
}
|
|
920
|
+
function scopeOf(node) {
|
|
921
|
+
const chain = [];
|
|
922
|
+
let parent = node.parent;
|
|
923
|
+
while (parent instanceof Y__namespace.Array) {
|
|
924
|
+
const owner = parent.parent;
|
|
925
|
+
if (!(owner instanceof Y__namespace.Map)) break;
|
|
926
|
+
chain.push(owner);
|
|
927
|
+
parent = owner.parent;
|
|
928
|
+
}
|
|
929
|
+
const scope = /* @__PURE__ */ new Map();
|
|
930
|
+
for (const el2 of chain.reverse()) {
|
|
931
|
+
for (const b of el2.get("bindings").toArray()) scope.set(b.prefix, b.ns);
|
|
932
|
+
}
|
|
933
|
+
return scope;
|
|
934
|
+
}
|
|
935
|
+
function scopeWithin(el2) {
|
|
936
|
+
const scope = scopeOf(el2);
|
|
937
|
+
if (!isPackedElement(el2)) {
|
|
938
|
+
for (const b of el2.get("bindings").toArray()) scope.set(b.prefix, b.ns);
|
|
939
|
+
}
|
|
940
|
+
return scope;
|
|
941
|
+
}
|
|
942
|
+
var unpackLimits = { maxBytes: 64 * 1024 * 1024, maxElements: 2e6 };
|
|
943
|
+
function unpack(text, scope) {
|
|
944
|
+
const read = store.readXml(text, unpackLimits);
|
|
945
|
+
if (!read.ok) throw new Error(`collab: a packed element is not readable XML (${read.reason})`);
|
|
946
|
+
const convert = (node, outer) => {
|
|
947
|
+
const bindings = [];
|
|
948
|
+
const named = [];
|
|
949
|
+
for (const [name, value] of Object.entries(node.attributes)) {
|
|
950
|
+
if (name === "xmlns") bindings.push({ prefix: "", ns: value });
|
|
951
|
+
else if (name.startsWith("xmlns:")) bindings.push({ prefix: name.slice(6), ns: value });
|
|
952
|
+
else named.push([name, value]);
|
|
953
|
+
}
|
|
954
|
+
const inner = new Map(outer);
|
|
955
|
+
for (const b of bindings) inner.set(b.prefix, b.ns);
|
|
956
|
+
const resolve = (prefix) => {
|
|
957
|
+
if (prefix === "xml") return store.XML_NAMESPACE_URI;
|
|
958
|
+
const ns = inner.get(prefix);
|
|
959
|
+
if (ns === void 0)
|
|
960
|
+
throw new Error(`collab: prefix ${prefix} is not bound in a packed element`);
|
|
961
|
+
return ns;
|
|
962
|
+
};
|
|
963
|
+
const colon = node.name.indexOf(":");
|
|
964
|
+
const xml = {
|
|
965
|
+
ns: colon < 0 ? inner.get("") ?? "" : resolve(node.name.slice(0, colon)),
|
|
966
|
+
local: colon < 0 ? node.name : node.name.slice(colon + 1),
|
|
967
|
+
attrs: named.map(([name, value]) => {
|
|
968
|
+
const at = name.indexOf(":");
|
|
969
|
+
if (at < 0) return { ns: "", local: name, value };
|
|
970
|
+
const prefix = name.slice(0, at);
|
|
971
|
+
return { ns: resolve(prefix), local: name.slice(at + 1), prefix, value };
|
|
972
|
+
}),
|
|
973
|
+
bindings,
|
|
974
|
+
children: node.children.map(
|
|
975
|
+
(child) => child.type === "text" ? child.value : convert(child, inner)
|
|
976
|
+
)
|
|
977
|
+
};
|
|
978
|
+
if (colon >= 0) xml.prefix = node.name.slice(0, colon);
|
|
979
|
+
return xml;
|
|
980
|
+
};
|
|
981
|
+
const root = read.nodes.find((n) => n.type === "element");
|
|
982
|
+
if (!root || root.type !== "element") throw new Error("collab: a packed element is empty");
|
|
983
|
+
return convert(root, scope);
|
|
984
|
+
}
|
|
899
985
|
function isParagraphEl(el2) {
|
|
900
986
|
return el2.ns === WML2 && el2.local === "p";
|
|
901
987
|
}
|
|
@@ -903,47 +989,53 @@ function fieldsOf(map, xml) {
|
|
|
903
989
|
map.set("ns", xml.ns);
|
|
904
990
|
map.set("local", xml.local);
|
|
905
991
|
if (xml.prefix !== void 0) map.set("prefix", xml.prefix);
|
|
906
|
-
const attrs = new
|
|
992
|
+
const attrs = new Y__namespace.Array();
|
|
907
993
|
attrs.push(xml.attrs.map((a) => ({ ...a })));
|
|
908
994
|
map.set("attrs", attrs);
|
|
909
|
-
const bindings = new
|
|
995
|
+
const bindings = new Y__namespace.Array();
|
|
910
996
|
bindings.push(xml.bindings.map((b) => ({ ...b })));
|
|
911
997
|
map.set("bindings", bindings);
|
|
912
998
|
}
|
|
913
999
|
function newText(value) {
|
|
914
|
-
const text = new
|
|
1000
|
+
const text = new Y__namespace.Text();
|
|
915
1001
|
text.insert(0, value);
|
|
916
1002
|
return text;
|
|
917
1003
|
}
|
|
918
|
-
function createRichParagraph(xml, encoded) {
|
|
919
|
-
const map = new
|
|
1004
|
+
function createRichParagraph(xml, encoded, scope = /* @__PURE__ */ new Map()) {
|
|
1005
|
+
const map = new Y__namespace.Map();
|
|
920
1006
|
fieldsOf(map, xml);
|
|
921
|
-
const
|
|
922
|
-
children
|
|
1007
|
+
const inner = withBindings(scope, xml.bindings);
|
|
1008
|
+
const children = new Y__namespace.Array();
|
|
1009
|
+
children.push(encoded.head.map((el2) => xmlToLive(el2, inner)));
|
|
923
1010
|
map.set("children", children);
|
|
924
|
-
const inline = new
|
|
1011
|
+
const inline = new Y__namespace.Text();
|
|
925
1012
|
writeUnits(inline, encoded.units);
|
|
926
1013
|
map.set("inline", inline);
|
|
927
1014
|
return map;
|
|
928
1015
|
}
|
|
929
|
-
function
|
|
1016
|
+
function withBindings(scope, bindings) {
|
|
1017
|
+
const inner = new Map(scope);
|
|
1018
|
+
for (const b of bindings) inner.set(b.prefix, b.ns);
|
|
1019
|
+
return inner;
|
|
1020
|
+
}
|
|
1021
|
+
function xmlToLive(xml, scope = /* @__PURE__ */ new Map(), root = false) {
|
|
930
1022
|
if (isParagraphEl(xml)) {
|
|
931
1023
|
const encoded = encodeParagraph(xml.children);
|
|
932
|
-
if (encoded) return createRichParagraph(xml, encoded);
|
|
1024
|
+
if (encoded) return createRichParagraph(xml, encoded, scope);
|
|
933
1025
|
}
|
|
934
|
-
return
|
|
935
|
-
|
|
936
|
-
function xmlToGenericLive(xml) {
|
|
937
|
-
const map = new Y3__namespace.Map();
|
|
1026
|
+
if (!root && packable(xml)) return createPacked(xml, scope);
|
|
1027
|
+
const map = new Y__namespace.Map();
|
|
938
1028
|
fieldsOf(map, xml);
|
|
939
|
-
const
|
|
940
|
-
children
|
|
1029
|
+
const inner = withBindings(scope, xml.bindings);
|
|
1030
|
+
const children = new Y__namespace.Array();
|
|
1031
|
+
children.push(xml.children.map((c) => typeof c === "string" ? newText(c) : xmlToLive(c, inner)));
|
|
941
1032
|
map.set("children", children);
|
|
942
1033
|
return map;
|
|
943
1034
|
}
|
|
944
1035
|
function liveToXml(map) {
|
|
1036
|
+
if (isPackedElement(map)) return unpack(map.get(PACKED), scopeOf(map));
|
|
945
1037
|
const prefix = map.get("prefix");
|
|
946
|
-
const stored = map.get("children").toArray().map((child) => child instanceof
|
|
1038
|
+
const stored = map.get("children").toArray().map((child) => child instanceof Y__namespace.Text ? child.toString() : liveToXml(child));
|
|
947
1039
|
const children = isRichParagraph(map) ? [...stored, ...decodeInline(readUnits(map.get("inline")))] : stored;
|
|
948
1040
|
const xml = {
|
|
949
1041
|
ns: map.get("ns"),
|
|
@@ -958,14 +1050,13 @@ function liveToXml(map) {
|
|
|
958
1050
|
var escapeText = (value) => value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
959
1051
|
var escapeAttr = (value) => value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/\t/g, "	").replace(/\n/g, " ").replace(/\r/g, " ");
|
|
960
1052
|
var qualified = (prefix, local) => prefix ? `${prefix}:${local}` : local;
|
|
961
|
-
function
|
|
962
|
-
const inScope =
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
for (const b of el2.bindings) {
|
|
1053
|
+
function startTag(prefix, local, bindings, attrs, scope) {
|
|
1054
|
+
const inScope = withBindings(scope, bindings);
|
|
1055
|
+
let out = `<${qualified(prefix, local)}`;
|
|
1056
|
+
for (const b of bindings) {
|
|
966
1057
|
out += b.prefix === "" ? ` xmlns="${escapeAttr(b.ns)}"` : ` xmlns:${b.prefix}="${escapeAttr(b.ns)}"`;
|
|
967
1058
|
}
|
|
968
|
-
for (const a of
|
|
1059
|
+
for (const a of attrs) {
|
|
969
1060
|
let p = a.prefix;
|
|
970
1061
|
if (a.ns !== "" && !p) {
|
|
971
1062
|
for (const [candidate, uri] of inScope) {
|
|
@@ -977,48 +1068,41 @@ function serializeXml(el2, scope) {
|
|
|
977
1068
|
}
|
|
978
1069
|
out += ` ${qualified(p, a.local)}="${escapeAttr(a.value)}"`;
|
|
979
1070
|
}
|
|
1071
|
+
return [out, inScope];
|
|
1072
|
+
}
|
|
1073
|
+
function serializeXml(el2, scope) {
|
|
1074
|
+
const [out, inScope] = startTag(el2.prefix, el2.local, el2.bindings, el2.attrs, scope);
|
|
980
1075
|
if (el2.children.length === 0) return `${out}/>`;
|
|
981
|
-
|
|
1076
|
+
let body = "";
|
|
982
1077
|
for (const child of el2.children) {
|
|
983
|
-
|
|
1078
|
+
body += typeof child === "string" ? escapeText(child) : serializeXml(child, inScope);
|
|
984
1079
|
}
|
|
985
|
-
return `${out}</${qualified(el2.prefix, el2.local)}>`;
|
|
1080
|
+
return `${out}>${body}</${qualified(el2.prefix, el2.local)}>`;
|
|
986
1081
|
}
|
|
987
1082
|
function serializeLive(el2, scope) {
|
|
988
|
-
if (
|
|
1083
|
+
if (isPackedElement(el2)) return el2.get(PACKED);
|
|
989
1084
|
const prefix = el2.get("prefix");
|
|
990
1085
|
const local = el2.get("local");
|
|
991
1086
|
const bindings = el2.get("bindings").toArray();
|
|
992
1087
|
const attrs = el2.get("attrs").toArray();
|
|
993
1088
|
const children = el2.get("children").toArray();
|
|
994
|
-
const inScope =
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
out += b.prefix === "" ? ` xmlns="${escapeAttr(b.ns)}"` : ` xmlns:${b.prefix}="${escapeAttr(b.ns)}"`;
|
|
999
|
-
}
|
|
1000
|
-
for (const a of attrs) {
|
|
1001
|
-
let p = a.prefix;
|
|
1002
|
-
if (a.ns !== "" && !p) {
|
|
1003
|
-
for (const [candidate, uri] of inScope) {
|
|
1004
|
-
if (candidate !== "" && uri === a.ns) {
|
|
1005
|
-
p = candidate;
|
|
1006
|
-
break;
|
|
1007
|
-
}
|
|
1008
|
-
}
|
|
1009
|
-
}
|
|
1010
|
-
out += ` ${qualified(p, a.local)}="${escapeAttr(a.value)}"`;
|
|
1011
|
-
}
|
|
1012
|
-
if (children.length === 0) return `${out}/>`;
|
|
1013
|
-
out += ">";
|
|
1089
|
+
const [out, inScope] = startTag(prefix, local, bindings, attrs, scope);
|
|
1090
|
+
const inline = isRichParagraph(el2) ? decodeInline(readUnits(el2.get("inline"))) : [];
|
|
1091
|
+
if (children.length === 0 && inline.length === 0) return `${out}/>`;
|
|
1092
|
+
let body = "";
|
|
1014
1093
|
for (const child of children) {
|
|
1015
|
-
|
|
1094
|
+
body += child instanceof Y__namespace.Text ? escapeText(child.toString()) : serializeLive(child, inScope);
|
|
1016
1095
|
}
|
|
1017
|
-
|
|
1096
|
+
for (const child of inline) body += serializeXml(child, inScope);
|
|
1097
|
+
return `${out}>${body}</${qualified(prefix, local)}>`;
|
|
1018
1098
|
}
|
|
1019
1099
|
|
|
1020
1100
|
// src/encoding.ts
|
|
1021
|
-
var COLLAB_FORMAT = "arbi-docx/
|
|
1101
|
+
var COLLAB_FORMAT = "arbi-docx/2";
|
|
1102
|
+
var READABLE_FORMATS = /* @__PURE__ */ new Set(["arbi-docx/1", COLLAB_FORMAT]);
|
|
1103
|
+
function isReadableFormat(format) {
|
|
1104
|
+
return format !== void 0 && READABLE_FORMATS.has(format);
|
|
1105
|
+
}
|
|
1022
1106
|
function isText(node) {
|
|
1023
1107
|
return node.kind === "textValue";
|
|
1024
1108
|
}
|
|
@@ -1039,7 +1123,7 @@ function canonicalToXml(node) {
|
|
|
1039
1123
|
return xml;
|
|
1040
1124
|
}
|
|
1041
1125
|
function encodeElement(el2) {
|
|
1042
|
-
return xmlToLive(canonicalToXml(el2));
|
|
1126
|
+
return xmlToLive(canonicalToXml(el2), /* @__PURE__ */ new Map(), true);
|
|
1043
1127
|
}
|
|
1044
1128
|
function bootstrap(doc, pkg) {
|
|
1045
1129
|
doc.transact(() => {
|
|
@@ -1057,7 +1141,7 @@ function bootstrap(doc, pkg) {
|
|
|
1057
1141
|
}
|
|
1058
1142
|
const rels = doc.getMap("rels");
|
|
1059
1143
|
for (const [owner, records] of pkg.relationships) {
|
|
1060
|
-
const byId = new
|
|
1144
|
+
const byId = new Y__namespace.Map();
|
|
1061
1145
|
for (const r of records) {
|
|
1062
1146
|
byId.set(r.id, {
|
|
1063
1147
|
ownerPart: r.ownerPart,
|
|
@@ -1073,7 +1157,7 @@ function bootstrap(doc, pkg) {
|
|
|
1073
1157
|
for (const e of pkg.externalTargets) {
|
|
1074
1158
|
let byId = rels.get(e.ownerPart);
|
|
1075
1159
|
if (!byId) {
|
|
1076
|
-
byId = new
|
|
1160
|
+
byId = new Y__namespace.Map();
|
|
1077
1161
|
rels.set(e.ownerPart, byId);
|
|
1078
1162
|
}
|
|
1079
1163
|
byId.set(e.id, {
|
|
@@ -1393,7 +1477,7 @@ var NodeRegistry = class {
|
|
|
1393
1477
|
require(id) {
|
|
1394
1478
|
let entry = this.entries.get(id) ?? this.resolveInsideParagraph(id);
|
|
1395
1479
|
if (!entry) throw new RegistryError(`journal names unknown node ${id}`);
|
|
1396
|
-
if ("live" in entry && entry.live instanceof
|
|
1480
|
+
if ("live" in entry && entry.live instanceof Y__namespace.Map && isCompact(entry.live)) {
|
|
1397
1481
|
this.openParagraph(entry.live);
|
|
1398
1482
|
entry = this.entries.get(id);
|
|
1399
1483
|
}
|
|
@@ -1411,7 +1495,7 @@ var NodeRegistry = class {
|
|
|
1411
1495
|
for (let length = path.length - 1; length >= 1; length--) {
|
|
1412
1496
|
const ancestor = this.entries.get(id.slice(0, hash + 1) + path.slice(0, length).join("."));
|
|
1413
1497
|
if (!ancestor) continue;
|
|
1414
|
-
if ("live" in ancestor && ancestor.live instanceof
|
|
1498
|
+
if ("live" in ancestor && ancestor.live instanceof Y__namespace.Map && isCompact(ancestor.live)) {
|
|
1415
1499
|
this.openParagraph(ancestor.live);
|
|
1416
1500
|
return this.entries.get(id);
|
|
1417
1501
|
}
|
|
@@ -1443,13 +1527,13 @@ var NodeRegistry = class {
|
|
|
1443
1527
|
/**
|
|
1444
1528
|
* Walk a mirror root and register every node under its positional id, `${part}#0` for the root and
|
|
1445
1529
|
* `${parent}.${index}` below it. This is the id scheme core assigns when it reads a part. A rich
|
|
1446
|
-
* paragraph is registered as one node; its inner nodes appear when it is opened.
|
|
1530
|
+
* paragraph or a packed element is registered as one node; its inner nodes appear when it is opened.
|
|
1447
1531
|
*/
|
|
1448
1532
|
registerTree(partName, root) {
|
|
1449
1533
|
const walk = (node, id) => {
|
|
1450
1534
|
this.registerLive(id, node);
|
|
1451
|
-
if (node instanceof
|
|
1452
|
-
if (
|
|
1535
|
+
if (node instanceof Y__namespace.Text) return;
|
|
1536
|
+
if (isCompact(node)) return;
|
|
1453
1537
|
childrenOf(node).forEach((child, index) => walk(child, `${id}.${index}`));
|
|
1454
1538
|
};
|
|
1455
1539
|
walk(root, `${partName}#0`);
|
|
@@ -1506,7 +1590,7 @@ var NodeRegistry = class {
|
|
|
1506
1590
|
for (const child of children) this.own(child, owner);
|
|
1507
1591
|
if (owner) this.dirty.add(owner);
|
|
1508
1592
|
}
|
|
1509
|
-
/** Write every changed open paragraph back into the mirror. Call at the end of a journal. */
|
|
1593
|
+
/** Write every changed open paragraph or packed element back into the mirror. Call at the end of a journal. */
|
|
1510
1594
|
flushRich() {
|
|
1511
1595
|
for (const live of [...this.dirty]) {
|
|
1512
1596
|
this.dirty.delete(live);
|
|
@@ -1517,6 +1601,11 @@ var NodeRegistry = class {
|
|
|
1517
1601
|
writeBack(record) {
|
|
1518
1602
|
const { live, root } = record;
|
|
1519
1603
|
const xml = plainToXml(root);
|
|
1604
|
+
if (isPackedElement(live)) {
|
|
1605
|
+
if (packable(xml)) repack(live, xml);
|
|
1606
|
+
else this.degrade(record);
|
|
1607
|
+
return;
|
|
1608
|
+
}
|
|
1520
1609
|
const encoded = encodeParagraph(xml.children);
|
|
1521
1610
|
if (!encoded) {
|
|
1522
1611
|
this.degrade(record);
|
|
@@ -1533,21 +1622,22 @@ var NodeRegistry = class {
|
|
|
1533
1622
|
bindings.push(xml.bindings.map((b) => ({ ...b })));
|
|
1534
1623
|
}
|
|
1535
1624
|
const head = childrenOf(live);
|
|
1536
|
-
const
|
|
1537
|
-
|
|
1625
|
+
const scope = scopeWithin(live);
|
|
1626
|
+
const stored = head.toArray().map((child) => serializeLive(child, scope)).join("");
|
|
1627
|
+
if (stored !== encoded.head.map((el2) => serializeXml(el2, scope)).join("")) {
|
|
1538
1628
|
head.delete(0, head.length);
|
|
1539
|
-
head.push(encoded.head.map((el2) => xmlToLive(el2)));
|
|
1629
|
+
head.push(encoded.head.map((el2) => xmlToLive(el2, scope)));
|
|
1540
1630
|
}
|
|
1541
1631
|
const inline = live.get("inline");
|
|
1542
1632
|
applyUnits(inline, readUnits(inline), encoded.units);
|
|
1543
1633
|
}
|
|
1544
|
-
/** The paragraph can no longer be held as rich text: store it as
|
|
1634
|
+
/** The paragraph can no longer be held as rich text, or the element packed: store it as a tree. */
|
|
1545
1635
|
degrade(record) {
|
|
1546
1636
|
const parent = record.live.parent;
|
|
1547
|
-
if (!(parent instanceof
|
|
1637
|
+
if (!(parent instanceof Y__namespace.Array))
|
|
1548
1638
|
throw new RegistryError("a paragraph outside a parent cannot change form");
|
|
1549
1639
|
const index = parent.toArray().indexOf(record.live);
|
|
1550
|
-
const generic = this.toGenericLive(record.root);
|
|
1640
|
+
const generic = this.toGenericLive(record.root, scopeOf(record.live));
|
|
1551
1641
|
this.open.delete(record.live);
|
|
1552
1642
|
parent.delete(index, 1);
|
|
1553
1643
|
parent.insert(index, [generic]);
|
|
@@ -1562,8 +1652,8 @@ var NodeRegistry = class {
|
|
|
1562
1652
|
snapshotLive(node) {
|
|
1563
1653
|
const id = this.liveIds.get(node);
|
|
1564
1654
|
if (id === void 0) throw new RegistryError("live node has no registered id");
|
|
1565
|
-
if (node instanceof
|
|
1566
|
-
if (
|
|
1655
|
+
if (node instanceof Y__namespace.Text) return { type: "text", id, value: node.toString() };
|
|
1656
|
+
if (isCompact(node)) {
|
|
1567
1657
|
return this.open.get(node)?.root ?? xmlToPlain(liveToXml(node), id);
|
|
1568
1658
|
}
|
|
1569
1659
|
const prefix = node.get("prefix");
|
|
@@ -1591,8 +1681,8 @@ var NodeRegistry = class {
|
|
|
1591
1681
|
if (id !== void 0 && this.isCurrentLive(id, node)) {
|
|
1592
1682
|
this.entries.set(id, { plain });
|
|
1593
1683
|
}
|
|
1594
|
-
if (node instanceof
|
|
1595
|
-
if (
|
|
1684
|
+
if (node instanceof Y__namespace.Text || plain.type === "text") return;
|
|
1685
|
+
if (isCompact(node)) {
|
|
1596
1686
|
this.open.delete(node);
|
|
1597
1687
|
this.dirty.delete(node);
|
|
1598
1688
|
return;
|
|
@@ -1600,53 +1690,61 @@ var NodeRegistry = class {
|
|
|
1600
1690
|
const liveChildren = childrenOf(node).toArray();
|
|
1601
1691
|
liveChildren.forEach((child, index) => this.detachInto(child, plain.children[index]));
|
|
1602
1692
|
}
|
|
1603
|
-
/**
|
|
1604
|
-
|
|
1693
|
+
/**
|
|
1694
|
+
* Build Yjs types for a plain subtree placed where `scope` is in force, and register every node as
|
|
1695
|
+
* live. A rich paragraph or packed element stays open on the plain tree, which is already current.
|
|
1696
|
+
* A part's `root` is never packed.
|
|
1697
|
+
*/
|
|
1698
|
+
toLive(plain, scope = /* @__PURE__ */ new Map(), root = false) {
|
|
1605
1699
|
if (plain.type === "text") {
|
|
1606
|
-
const text = new
|
|
1700
|
+
const text = new Y__namespace.Text();
|
|
1607
1701
|
text.insert(0, plain.value);
|
|
1608
1702
|
this.registerLive(plain.id, text);
|
|
1609
1703
|
return text;
|
|
1610
1704
|
}
|
|
1705
|
+
const xml = plainToXml(plain);
|
|
1706
|
+
let map;
|
|
1611
1707
|
if (isParagraphEl(plain)) {
|
|
1612
|
-
const xml = plainToXml(plain);
|
|
1613
1708
|
const encoded = encodeParagraph(xml.children);
|
|
1614
|
-
if (encoded)
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
}
|
|
1709
|
+
if (encoded) map = createRichParagraph(xml, encoded, scope);
|
|
1710
|
+
}
|
|
1711
|
+
if (!map && !root && packable(xml)) map = xmlToLive(xml, scope);
|
|
1712
|
+
if (map) {
|
|
1713
|
+
this.liveIds.set(map, plain.id);
|
|
1714
|
+
this.registerPlain(plain);
|
|
1715
|
+
this.own(plain, map);
|
|
1716
|
+
this.open.set(map, { live: map, root: plain, id: plain.id });
|
|
1717
|
+
return map;
|
|
1622
1718
|
}
|
|
1623
|
-
return this.toGenericLive(plain);
|
|
1719
|
+
return this.toGenericLive(plain, scope);
|
|
1624
1720
|
}
|
|
1625
|
-
toGenericLive(plain) {
|
|
1721
|
+
toGenericLive(plain, scope) {
|
|
1626
1722
|
const map = xmlToGenericShell(plain);
|
|
1627
|
-
const
|
|
1628
|
-
children
|
|
1723
|
+
const inner = withBindings(scope, plain.bindings);
|
|
1724
|
+
const children = new Y__namespace.Array();
|
|
1725
|
+
children.push(plain.children.map((child) => this.toLive(child, inner)));
|
|
1629
1726
|
map.set("children", children);
|
|
1630
1727
|
this.registerLive(plain.id, map);
|
|
1631
1728
|
return map;
|
|
1632
1729
|
}
|
|
1633
1730
|
/**
|
|
1634
|
-
* A live node that can be inserted into a parent
|
|
1635
|
-
* attached node is copied, because a Yjs type cannot
|
|
1731
|
+
* A live node that can be inserted into a parent (`scope` is in force there), or a part's `root`.
|
|
1732
|
+
* Anything not yet attached is built fresh; an attached node is copied, because a Yjs type cannot
|
|
1733
|
+
* have two parents.
|
|
1636
1734
|
*/
|
|
1637
|
-
attachable(id) {
|
|
1638
|
-
return this.toLive(this.snapshot(id));
|
|
1735
|
+
attachable(id, scope = /* @__PURE__ */ new Map(), root = false) {
|
|
1736
|
+
return this.toLive(this.snapshot(id), scope, root);
|
|
1639
1737
|
}
|
|
1640
1738
|
};
|
|
1641
1739
|
function xmlToGenericShell(plain) {
|
|
1642
|
-
const map = new
|
|
1740
|
+
const map = new Y__namespace.Map();
|
|
1643
1741
|
map.set("ns", plain.ns);
|
|
1644
1742
|
map.set("local", plain.local);
|
|
1645
1743
|
if (plain.prefix !== void 0) map.set("prefix", plain.prefix);
|
|
1646
|
-
const attrs = new
|
|
1744
|
+
const attrs = new Y__namespace.Array();
|
|
1647
1745
|
attrs.push(plain.attrs.map((a) => ({ ...a })));
|
|
1648
1746
|
map.set("attrs", attrs);
|
|
1649
|
-
const bindings = new
|
|
1747
|
+
const bindings = new Y__namespace.Array();
|
|
1650
1748
|
bindings.push(plain.bindings.map((b) => ({ ...b })));
|
|
1651
1749
|
map.set("bindings", bindings);
|
|
1652
1750
|
return map;
|
|
@@ -1711,7 +1809,7 @@ function setNamespaceBinding(registry, id, prefix, uri) {
|
|
|
1711
1809
|
}
|
|
1712
1810
|
}
|
|
1713
1811
|
function asLiveElement(node, id) {
|
|
1714
|
-
if (node instanceof
|
|
1812
|
+
if (node instanceof Y__namespace.Text) throw new JournalError(`${id} is a text node, not an element`);
|
|
1715
1813
|
return node;
|
|
1716
1814
|
}
|
|
1717
1815
|
function asPlainElement(node, id) {
|
|
@@ -1727,7 +1825,7 @@ function spliceText(registry, id, start, deleteCount, insert) {
|
|
|
1727
1825
|
return;
|
|
1728
1826
|
}
|
|
1729
1827
|
const text = entry.live;
|
|
1730
|
-
if (!(text instanceof
|
|
1828
|
+
if (!(text instanceof Y__namespace.Text)) throw new JournalError(`${id} is not a text node`);
|
|
1731
1829
|
if (start < 0 || start + deleteCount > text.length) {
|
|
1732
1830
|
throw new JournalError(`text splice out of range on ${id}`);
|
|
1733
1831
|
}
|
|
@@ -1740,27 +1838,29 @@ function detachRemoved(registry, parent, start, count) {
|
|
|
1740
1838
|
function spliceChildren(registry, parentId, start, deleteCount, childIds) {
|
|
1741
1839
|
const parentEntry = registry.require(parentId);
|
|
1742
1840
|
if ("plain" in parentEntry) {
|
|
1743
|
-
const
|
|
1744
|
-
if (start < 0 || start + deleteCount >
|
|
1841
|
+
const parent2 = asPlainElement(parentEntry.plain, parentId);
|
|
1842
|
+
if (start < 0 || start + deleteCount > parent2.children.length) {
|
|
1745
1843
|
throw new JournalError(`child splice out of range on ${parentId}`);
|
|
1746
1844
|
}
|
|
1747
1845
|
const inserted2 = childIds.map((id) => registry.snapshot(id));
|
|
1748
|
-
|
|
1749
|
-
registry.adopt(
|
|
1846
|
+
parent2.children.splice(start, deleteCount, ...inserted2);
|
|
1847
|
+
registry.adopt(parent2, inserted2);
|
|
1750
1848
|
return;
|
|
1751
1849
|
}
|
|
1752
|
-
const
|
|
1850
|
+
const parent = asLiveElement(parentEntry.live, parentId);
|
|
1851
|
+
const children = childrenOf(parent);
|
|
1753
1852
|
if (start < 0 || start + deleteCount > children.length) {
|
|
1754
1853
|
throw new JournalError(`child splice out of range on ${parentId}`);
|
|
1755
1854
|
}
|
|
1756
1855
|
detachRemoved(registry, children, start, deleteCount);
|
|
1757
|
-
const
|
|
1856
|
+
const scope = scopeWithin(parent);
|
|
1857
|
+
const inserted = childIds.map((id) => registry.attachable(id, scope));
|
|
1758
1858
|
if (deleteCount > 0) children.delete(start, deleteCount);
|
|
1759
1859
|
if (inserted.length > 0) children.insert(start, inserted);
|
|
1760
1860
|
}
|
|
1761
1861
|
function locate(registry, id, node) {
|
|
1762
1862
|
const children = node.parent;
|
|
1763
|
-
if (!(children instanceof
|
|
1863
|
+
if (!(children instanceof Y__namespace.Array)) throw new JournalError(`${id} is not attached`);
|
|
1764
1864
|
const index = children.toArray().indexOf(node);
|
|
1765
1865
|
if (index < 0) throw new JournalError(`${id} is not in its parent`);
|
|
1766
1866
|
return { children, index };
|
|
@@ -1787,8 +1887,10 @@ function moveNode(registry, id, destinationId, destinationIndex) {
|
|
|
1787
1887
|
registry.adopt(destination2, [copy]);
|
|
1788
1888
|
return;
|
|
1789
1889
|
}
|
|
1790
|
-
const destination =
|
|
1791
|
-
destination.insert(destinationIndex, [
|
|
1890
|
+
const destination = asLiveElement(destinationEntry.live, destinationId);
|
|
1891
|
+
childrenOf(destination).insert(destinationIndex, [
|
|
1892
|
+
registry.toLive(copy, scopeWithin(destination))
|
|
1893
|
+
]);
|
|
1792
1894
|
}
|
|
1793
1895
|
function renameNode(registry, id, qname) {
|
|
1794
1896
|
const entry = registry.require(id);
|
|
@@ -1803,7 +1905,7 @@ function renameNode(registry, id, qname) {
|
|
|
1803
1905
|
return true;
|
|
1804
1906
|
}
|
|
1805
1907
|
const live = entry.live;
|
|
1806
|
-
if (live instanceof
|
|
1908
|
+
if (live instanceof Y__namespace.Text || isCompact(live)) return false;
|
|
1807
1909
|
if (live.get("ns") !== qname.namespaceUri) live.set("ns", qname.namespaceUri);
|
|
1808
1910
|
if (live.get("local") !== qname.localName) live.set("local", qname.localName);
|
|
1809
1911
|
if (qname.prefix === void 0) {
|
|
@@ -1833,7 +1935,7 @@ function putNode(registry, effect) {
|
|
|
1833
1935
|
}
|
|
1834
1936
|
function rootFor(registry, id) {
|
|
1835
1937
|
const entry = registry.require(id);
|
|
1836
|
-
const live = "live" in entry && entry.live.parent === null ? entry.live : registry.attachable(id);
|
|
1938
|
+
const live = "live" in entry && entry.live.parent === null ? entry.live : registry.attachable(id, /* @__PURE__ */ new Map(), true);
|
|
1837
1939
|
return asLiveElement(live, id);
|
|
1838
1940
|
}
|
|
1839
1941
|
function applyEffect(doc, registry, effect, context) {
|
|
@@ -1877,7 +1979,7 @@ function applyEffect(doc, registry, effect, context) {
|
|
|
1877
1979
|
const rels = doc.getMap("rels");
|
|
1878
1980
|
let byId = rels.get(effect.owner);
|
|
1879
1981
|
if (!byId) {
|
|
1880
|
-
byId = new
|
|
1982
|
+
byId = new Y__namespace.Map();
|
|
1881
1983
|
rels.set(effect.owner, byId);
|
|
1882
1984
|
}
|
|
1883
1985
|
byId.set(effect.record.id, { ...effect.record });
|
|
@@ -2082,7 +2184,7 @@ var DocxCollaborationSession = class {
|
|
|
2082
2184
|
this.doc = options.doc;
|
|
2083
2185
|
this.awareness = options.awareness;
|
|
2084
2186
|
this.offlineEditing = options.offlineEditing ?? false;
|
|
2085
|
-
this.undoManager = new
|
|
2187
|
+
this.undoManager = new Y__namespace.UndoManager(
|
|
2086
2188
|
[
|
|
2087
2189
|
this.doc.getMap("parts"),
|
|
2088
2190
|
this.doc.getMap("rels"),
|
|
@@ -2122,7 +2224,7 @@ var DocxCollaborationSession = class {
|
|
|
2122
2224
|
this.setStatus("error", "not-initialized");
|
|
2123
2225
|
return;
|
|
2124
2226
|
}
|
|
2125
|
-
if (readFormat(this.doc)
|
|
2227
|
+
if (!isReadableFormat(readFormat(this.doc))) {
|
|
2126
2228
|
this.setStatus("error", "collaboration-format-mismatch", readFormat(this.doc));
|
|
2127
2229
|
return;
|
|
2128
2230
|
}
|
|
@@ -2396,7 +2498,7 @@ function resolveAddress(port, address) {
|
|
|
2396
2498
|
};
|
|
2397
2499
|
}
|
|
2398
2500
|
function vectorKey(doc) {
|
|
2399
|
-
return Array.from(
|
|
2501
|
+
return Array.from(Y__namespace.encodeStateVector(doc)).join(",");
|
|
2400
2502
|
}
|
|
2401
2503
|
function randomToken() {
|
|
2402
2504
|
if (typeof crypto.randomUUID === "function") return crypto.randomUUID();
|
|
@@ -2429,7 +2531,7 @@ function assertCompatibleVersions(versions) {
|
|
|
2429
2531
|
function assertRoomFormat(doc) {
|
|
2430
2532
|
if (!isBootstrapped(doc)) throw new CollaborationCompatibilityError("The room holds no document.");
|
|
2431
2533
|
const format = readFormat(doc);
|
|
2432
|
-
if (format
|
|
2534
|
+
if (!isReadableFormat(format)) {
|
|
2433
2535
|
throw new CollaborationCompatibilityError(`Unsupported room format ${String(format)}.`);
|
|
2434
2536
|
}
|
|
2435
2537
|
}
|