@arbidocs/coedit 0.5.21 → 0.5.23
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/encoding.d.cts
CHANGED
|
@@ -2,6 +2,28 @@ import * as _docx_editor_dev_core_store from '@docx-editor.dev/core/store';
|
|
|
2
2
|
import { OoxmlPackage } from '@docx-editor.dev/core/store';
|
|
3
3
|
import * as Y from 'yjs';
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Elements of the mirror, in both directions: plain `XmlEl` objects to Yjs types and back, and
|
|
7
|
+
* `XmlEl` to XML text.
|
|
8
|
+
*
|
|
9
|
+
* Three forms:
|
|
10
|
+
*
|
|
11
|
+
* - A paragraph is held as a rich paragraph (see rich.ts) whenever it can be represented exactly:
|
|
12
|
+
* its properties stay in `children`, and its inline content is the single Y.Text `inline`.
|
|
13
|
+
* - An element with no editable text anywhere below it (a style, a numbering definition, a font, a
|
|
14
|
+
* setting, a theme, paragraph or table properties, a section's setup) is packed: the map holds
|
|
15
|
+
* its whole subtree as one XML string under `xml`. It is opened into a plain tree when an edit
|
|
16
|
+
* touches it and written back whole, so concurrent edits to the same packed element are last
|
|
17
|
+
* writer wins, while different elements (two styles) still merge. Held as a tree, every element,
|
|
18
|
+
* attribute and namespace URI was its own CRDT item: a 350 KB styles part took 3.2 MB of room
|
|
19
|
+
* state and over 100 MB of heap to load.
|
|
20
|
+
* - Every other element (the body, a table, a cell, a footnote: the path to editable text) is a
|
|
21
|
+
* generic map with a `children` array.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
/** Prefixes in scope for an element; innermost binding wins. */
|
|
25
|
+
type Scope = ReadonlyMap<string, string>;
|
|
26
|
+
|
|
5
27
|
/**
|
|
6
28
|
* Identity registry between core's logical node ids and the Yjs mirror.
|
|
7
29
|
*
|
|
@@ -14,10 +36,12 @@ import * as Y from 'yjs';
|
|
|
14
36
|
* under construction, detached, or about to move are therefore held as plain objects and converted
|
|
15
37
|
* to Yjs types when they are attached to a live parent. `snapshot` is the live to plain direction.
|
|
16
38
|
*
|
|
17
|
-
* Rich paragraphs (see rich.ts) hold their runs as attributes on one Y.Text,
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
39
|
+
* Rich paragraphs (see rich.ts) hold their runs as attributes on one Y.Text, and packed elements
|
|
40
|
+
* (see mirror.ts) hold their subtree as one XML string, so their inner nodes have no Yjs type of
|
|
41
|
+
* their own. The first effect that touches one opens it: it is read into a plain tree, the journal's
|
|
42
|
+
* effects change that tree, and `flushRich` writes the result back (a minimal edit of the text, or
|
|
43
|
+
* the packed element's new XML). The tree stays open, mirroring the editor's own, until a remote
|
|
44
|
+
* change re-reads it.
|
|
21
45
|
*/
|
|
22
46
|
|
|
23
47
|
interface PlainElement {
|
|
@@ -69,7 +93,7 @@ declare class NodeRegistry {
|
|
|
69
93
|
/**
|
|
70
94
|
* Walk a mirror root and register every node under its positional id, `${part}#0` for the root and
|
|
71
95
|
* `${parent}.${index}` below it. This is the id scheme core assigns when it reads a part. A rich
|
|
72
|
-
* paragraph is registered as one node; its inner nodes appear when it is opened.
|
|
96
|
+
* paragraph or a packed element is registered as one node; its inner nodes appear when it is opened.
|
|
73
97
|
*/
|
|
74
98
|
registerTree(partName: string, root: Y.Map<unknown>): void;
|
|
75
99
|
private own;
|
|
@@ -85,10 +109,10 @@ declare class NodeRegistry {
|
|
|
85
109
|
touch(node: PlainNode): void;
|
|
86
110
|
/** Nodes just placed under `parent` belong to the same paragraph as it, if any. */
|
|
87
111
|
adopt(parent: PlainElement, children: readonly PlainNode[]): void;
|
|
88
|
-
/** Write every changed open paragraph back into the mirror. Call at the end of a journal. */
|
|
112
|
+
/** Write every changed open paragraph or packed element back into the mirror. Call at the end of a journal. */
|
|
89
113
|
flushRich(): void;
|
|
90
114
|
private writeBack;
|
|
91
|
-
/** The paragraph can no longer be held as rich text: store it as
|
|
115
|
+
/** The paragraph can no longer be held as rich text, or the element packed: store it as a tree. */
|
|
92
116
|
private degrade;
|
|
93
117
|
/** Deep copy of a node into plain objects carrying the same ids. */
|
|
94
118
|
snapshot(id: string): PlainNode;
|
|
@@ -99,17 +123,28 @@ declare class NodeRegistry {
|
|
|
99
123
|
*/
|
|
100
124
|
detach(node: LiveNode): void;
|
|
101
125
|
private detachInto;
|
|
102
|
-
/**
|
|
103
|
-
|
|
126
|
+
/**
|
|
127
|
+
* Build Yjs types for a plain subtree placed where `scope` is in force, and register every node as
|
|
128
|
+
* live. A rich paragraph or packed element stays open on the plain tree, which is already current.
|
|
129
|
+
* A part's `root` is never packed.
|
|
130
|
+
*/
|
|
131
|
+
toLive(plain: PlainNode, scope?: Scope, root?: boolean): LiveNode;
|
|
104
132
|
private toGenericLive;
|
|
105
133
|
/**
|
|
106
|
-
* A live node that can be inserted into a parent
|
|
107
|
-
* attached node is copied, because a Yjs type cannot
|
|
134
|
+
* A live node that can be inserted into a parent (`scope` is in force there), or a part's `root`.
|
|
135
|
+
* Anything not yet attached is built fresh; an attached node is copied, because a Yjs type cannot
|
|
136
|
+
* have two parents.
|
|
108
137
|
*/
|
|
109
|
-
attachable(id: string): LiveNode;
|
|
138
|
+
attachable(id: string, scope?: Scope, root?: boolean): LiveNode;
|
|
110
139
|
}
|
|
111
140
|
|
|
112
|
-
|
|
141
|
+
/**
|
|
142
|
+
* The room format this build writes. `arbi-docx/2` holds elements without editable text packed (see
|
|
143
|
+
* mirror.ts); it reads `arbi-docx/1` rooms, whose elements are all trees, unchanged. A build that
|
|
144
|
+
* only knows `/1` cannot read a packed element, so the client handshake requires this exact format.
|
|
145
|
+
*/
|
|
146
|
+
declare const COLLAB_FORMAT = "arbi-docx/2";
|
|
147
|
+
declare function isReadableFormat(format: string | undefined): boolean;
|
|
113
148
|
interface AttrJson {
|
|
114
149
|
ns: string;
|
|
115
150
|
local: string;
|
|
@@ -150,6 +185,7 @@ interface CanonicalText {
|
|
|
150
185
|
readonly kind: 'textValue';
|
|
151
186
|
readonly value: string;
|
|
152
187
|
}
|
|
188
|
+
/** The Yjs form of a part's root element. */
|
|
153
189
|
declare function encodeElement(el: CanonicalElement): Y.Map<unknown>;
|
|
154
190
|
declare function encodeText(value: string): Y.Text;
|
|
155
191
|
/** Seed an empty Yjs document from a loaded package. Call once, inside a transaction. */
|
|
@@ -191,4 +227,4 @@ declare function materializeBytes(doc: Y.Doc): Uint8Array;
|
|
|
191
227
|
/** Load DOCX bytes and seed an empty room from them. */
|
|
192
228
|
declare function bootstrapFromBytes(doc: Y.Doc, bytes: Uint8Array): OoxmlPackage;
|
|
193
229
|
|
|
194
|
-
export { type AttrJson, type BindingJson, COLLAB_FORMAT, MaterializeCache, MaterializeError, type RelationshipJson, bootstrap, bootstrapFromBytes, contentTypeOf, encodeElement, encodeText, isBootstrapped, materialize, materializeBytes, readFormat, registerMirror, serializePart };
|
|
230
|
+
export { type AttrJson, type BindingJson, COLLAB_FORMAT, MaterializeCache, MaterializeError, type RelationshipJson, bootstrap, bootstrapFromBytes, contentTypeOf, encodeElement, encodeText, isBootstrapped, isReadableFormat, materialize, materializeBytes, readFormat, registerMirror, serializePart };
|
package/dist/encoding.d.ts
CHANGED
|
@@ -2,6 +2,28 @@ import * as _docx_editor_dev_core_store from '@docx-editor.dev/core/store';
|
|
|
2
2
|
import { OoxmlPackage } from '@docx-editor.dev/core/store';
|
|
3
3
|
import * as Y from 'yjs';
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Elements of the mirror, in both directions: plain `XmlEl` objects to Yjs types and back, and
|
|
7
|
+
* `XmlEl` to XML text.
|
|
8
|
+
*
|
|
9
|
+
* Three forms:
|
|
10
|
+
*
|
|
11
|
+
* - A paragraph is held as a rich paragraph (see rich.ts) whenever it can be represented exactly:
|
|
12
|
+
* its properties stay in `children`, and its inline content is the single Y.Text `inline`.
|
|
13
|
+
* - An element with no editable text anywhere below it (a style, a numbering definition, a font, a
|
|
14
|
+
* setting, a theme, paragraph or table properties, a section's setup) is packed: the map holds
|
|
15
|
+
* its whole subtree as one XML string under `xml`. It is opened into a plain tree when an edit
|
|
16
|
+
* touches it and written back whole, so concurrent edits to the same packed element are last
|
|
17
|
+
* writer wins, while different elements (two styles) still merge. Held as a tree, every element,
|
|
18
|
+
* attribute and namespace URI was its own CRDT item: a 350 KB styles part took 3.2 MB of room
|
|
19
|
+
* state and over 100 MB of heap to load.
|
|
20
|
+
* - Every other element (the body, a table, a cell, a footnote: the path to editable text) is a
|
|
21
|
+
* generic map with a `children` array.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
/** Prefixes in scope for an element; innermost binding wins. */
|
|
25
|
+
type Scope = ReadonlyMap<string, string>;
|
|
26
|
+
|
|
5
27
|
/**
|
|
6
28
|
* Identity registry between core's logical node ids and the Yjs mirror.
|
|
7
29
|
*
|
|
@@ -14,10 +36,12 @@ import * as Y from 'yjs';
|
|
|
14
36
|
* under construction, detached, or about to move are therefore held as plain objects and converted
|
|
15
37
|
* to Yjs types when they are attached to a live parent. `snapshot` is the live to plain direction.
|
|
16
38
|
*
|
|
17
|
-
* Rich paragraphs (see rich.ts) hold their runs as attributes on one Y.Text,
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
39
|
+
* Rich paragraphs (see rich.ts) hold their runs as attributes on one Y.Text, and packed elements
|
|
40
|
+
* (see mirror.ts) hold their subtree as one XML string, so their inner nodes have no Yjs type of
|
|
41
|
+
* their own. The first effect that touches one opens it: it is read into a plain tree, the journal's
|
|
42
|
+
* effects change that tree, and `flushRich` writes the result back (a minimal edit of the text, or
|
|
43
|
+
* the packed element's new XML). The tree stays open, mirroring the editor's own, until a remote
|
|
44
|
+
* change re-reads it.
|
|
21
45
|
*/
|
|
22
46
|
|
|
23
47
|
interface PlainElement {
|
|
@@ -69,7 +93,7 @@ declare class NodeRegistry {
|
|
|
69
93
|
/**
|
|
70
94
|
* Walk a mirror root and register every node under its positional id, `${part}#0` for the root and
|
|
71
95
|
* `${parent}.${index}` below it. This is the id scheme core assigns when it reads a part. A rich
|
|
72
|
-
* paragraph is registered as one node; its inner nodes appear when it is opened.
|
|
96
|
+
* paragraph or a packed element is registered as one node; its inner nodes appear when it is opened.
|
|
73
97
|
*/
|
|
74
98
|
registerTree(partName: string, root: Y.Map<unknown>): void;
|
|
75
99
|
private own;
|
|
@@ -85,10 +109,10 @@ declare class NodeRegistry {
|
|
|
85
109
|
touch(node: PlainNode): void;
|
|
86
110
|
/** Nodes just placed under `parent` belong to the same paragraph as it, if any. */
|
|
87
111
|
adopt(parent: PlainElement, children: readonly PlainNode[]): void;
|
|
88
|
-
/** Write every changed open paragraph back into the mirror. Call at the end of a journal. */
|
|
112
|
+
/** Write every changed open paragraph or packed element back into the mirror. Call at the end of a journal. */
|
|
89
113
|
flushRich(): void;
|
|
90
114
|
private writeBack;
|
|
91
|
-
/** The paragraph can no longer be held as rich text: store it as
|
|
115
|
+
/** The paragraph can no longer be held as rich text, or the element packed: store it as a tree. */
|
|
92
116
|
private degrade;
|
|
93
117
|
/** Deep copy of a node into plain objects carrying the same ids. */
|
|
94
118
|
snapshot(id: string): PlainNode;
|
|
@@ -99,17 +123,28 @@ declare class NodeRegistry {
|
|
|
99
123
|
*/
|
|
100
124
|
detach(node: LiveNode): void;
|
|
101
125
|
private detachInto;
|
|
102
|
-
/**
|
|
103
|
-
|
|
126
|
+
/**
|
|
127
|
+
* Build Yjs types for a plain subtree placed where `scope` is in force, and register every node as
|
|
128
|
+
* live. A rich paragraph or packed element stays open on the plain tree, which is already current.
|
|
129
|
+
* A part's `root` is never packed.
|
|
130
|
+
*/
|
|
131
|
+
toLive(plain: PlainNode, scope?: Scope, root?: boolean): LiveNode;
|
|
104
132
|
private toGenericLive;
|
|
105
133
|
/**
|
|
106
|
-
* A live node that can be inserted into a parent
|
|
107
|
-
* attached node is copied, because a Yjs type cannot
|
|
134
|
+
* A live node that can be inserted into a parent (`scope` is in force there), or a part's `root`.
|
|
135
|
+
* Anything not yet attached is built fresh; an attached node is copied, because a Yjs type cannot
|
|
136
|
+
* have two parents.
|
|
108
137
|
*/
|
|
109
|
-
attachable(id: string): LiveNode;
|
|
138
|
+
attachable(id: string, scope?: Scope, root?: boolean): LiveNode;
|
|
110
139
|
}
|
|
111
140
|
|
|
112
|
-
|
|
141
|
+
/**
|
|
142
|
+
* The room format this build writes. `arbi-docx/2` holds elements without editable text packed (see
|
|
143
|
+
* mirror.ts); it reads `arbi-docx/1` rooms, whose elements are all trees, unchanged. A build that
|
|
144
|
+
* only knows `/1` cannot read a packed element, so the client handshake requires this exact format.
|
|
145
|
+
*/
|
|
146
|
+
declare const COLLAB_FORMAT = "arbi-docx/2";
|
|
147
|
+
declare function isReadableFormat(format: string | undefined): boolean;
|
|
113
148
|
interface AttrJson {
|
|
114
149
|
ns: string;
|
|
115
150
|
local: string;
|
|
@@ -150,6 +185,7 @@ interface CanonicalText {
|
|
|
150
185
|
readonly kind: 'textValue';
|
|
151
186
|
readonly value: string;
|
|
152
187
|
}
|
|
188
|
+
/** The Yjs form of a part's root element. */
|
|
153
189
|
declare function encodeElement(el: CanonicalElement): Y.Map<unknown>;
|
|
154
190
|
declare function encodeText(value: string): Y.Text;
|
|
155
191
|
/** Seed an empty Yjs document from a loaded package. Call once, inside a transaction. */
|
|
@@ -191,4 +227,4 @@ declare function materializeBytes(doc: Y.Doc): Uint8Array;
|
|
|
191
227
|
/** Load DOCX bytes and seed an empty room from them. */
|
|
192
228
|
declare function bootstrapFromBytes(doc: Y.Doc, bytes: Uint8Array): OoxmlPackage;
|
|
193
229
|
|
|
194
|
-
export { type AttrJson, type BindingJson, COLLAB_FORMAT, MaterializeCache, MaterializeError, type RelationshipJson, bootstrap, bootstrapFromBytes, contentTypeOf, encodeElement, encodeText, isBootstrapped, materialize, materializeBytes, readFormat, registerMirror, serializePart };
|
|
230
|
+
export { type AttrJson, type BindingJson, COLLAB_FORMAT, MaterializeCache, MaterializeError, type RelationshipJson, bootstrap, bootstrapFromBytes, contentTypeOf, encodeElement, encodeText, isBootstrapped, isReadableFormat, materialize, materializeBytes, readFormat, registerMirror, serializePart };
|
package/dist/encoding.js
CHANGED
|
@@ -312,6 +312,20 @@ function writeUnits(text, units) {
|
|
|
312
312
|
function isRichParagraph(map) {
|
|
313
313
|
return map.has("inline");
|
|
314
314
|
}
|
|
315
|
+
var PACKED = "xml";
|
|
316
|
+
function isPackedElement(map) {
|
|
317
|
+
return map.has(PACKED);
|
|
318
|
+
}
|
|
319
|
+
var TEXT_BEARING = /* @__PURE__ */ new Set(["p", "t", "delText", "instrText", "delInstrText"]);
|
|
320
|
+
function packable(xml) {
|
|
321
|
+
if (xml.ns === WML && TEXT_BEARING.has(xml.local)) return false;
|
|
322
|
+
return xml.children.every((c) => typeof c === "string" || packable(c));
|
|
323
|
+
}
|
|
324
|
+
function createPacked(xml, scope) {
|
|
325
|
+
const map = new Y.Map();
|
|
326
|
+
map.set(PACKED, serializeXml(xml, scope));
|
|
327
|
+
return map;
|
|
328
|
+
}
|
|
315
329
|
function isParagraphEl(el) {
|
|
316
330
|
return el.ns === WML && el.local === "p";
|
|
317
331
|
}
|
|
@@ -331,57 +345,47 @@ function newText(value) {
|
|
|
331
345
|
text.insert(0, value);
|
|
332
346
|
return text;
|
|
333
347
|
}
|
|
334
|
-
function createRichParagraph(xml, encoded) {
|
|
348
|
+
function createRichParagraph(xml, encoded, scope = /* @__PURE__ */ new Map()) {
|
|
335
349
|
const map = new Y.Map();
|
|
336
350
|
fieldsOf(map, xml);
|
|
351
|
+
const inner = withBindings(scope, xml.bindings);
|
|
337
352
|
const children = new Y.Array();
|
|
338
|
-
children.push(encoded.head.map((el) => xmlToLive(el)));
|
|
353
|
+
children.push(encoded.head.map((el) => xmlToLive(el, inner)));
|
|
339
354
|
map.set("children", children);
|
|
340
355
|
const inline = new Y.Text();
|
|
341
356
|
writeUnits(inline, encoded.units);
|
|
342
357
|
map.set("inline", inline);
|
|
343
358
|
return map;
|
|
344
359
|
}
|
|
345
|
-
function
|
|
360
|
+
function withBindings(scope, bindings) {
|
|
361
|
+
const inner = new Map(scope);
|
|
362
|
+
for (const b of bindings) inner.set(b.prefix, b.ns);
|
|
363
|
+
return inner;
|
|
364
|
+
}
|
|
365
|
+
function xmlToLive(xml, scope = /* @__PURE__ */ new Map(), root = false) {
|
|
346
366
|
if (isParagraphEl(xml)) {
|
|
347
367
|
const encoded = encodeParagraph(xml.children);
|
|
348
|
-
if (encoded) return createRichParagraph(xml, encoded);
|
|
368
|
+
if (encoded) return createRichParagraph(xml, encoded, scope);
|
|
349
369
|
}
|
|
350
|
-
return
|
|
351
|
-
}
|
|
352
|
-
function xmlToGenericLive(xml) {
|
|
370
|
+
if (!root && packable(xml)) return createPacked(xml, scope);
|
|
353
371
|
const map = new Y.Map();
|
|
354
372
|
fieldsOf(map, xml);
|
|
373
|
+
const inner = withBindings(scope, xml.bindings);
|
|
355
374
|
const children = new Y.Array();
|
|
356
|
-
children.push(xml.children.map((c) => typeof c === "string" ? newText(c) : xmlToLive(c)));
|
|
375
|
+
children.push(xml.children.map((c) => typeof c === "string" ? newText(c) : xmlToLive(c, inner)));
|
|
357
376
|
map.set("children", children);
|
|
358
377
|
return map;
|
|
359
378
|
}
|
|
360
|
-
function liveToXml(map) {
|
|
361
|
-
const prefix = map.get("prefix");
|
|
362
|
-
const stored = map.get("children").toArray().map((child) => child instanceof Y.Text ? child.toString() : liveToXml(child));
|
|
363
|
-
const children = isRichParagraph(map) ? [...stored, ...decodeInline(readUnits(map.get("inline")))] : stored;
|
|
364
|
-
const xml = {
|
|
365
|
-
ns: map.get("ns"),
|
|
366
|
-
local: map.get("local"),
|
|
367
|
-
attrs: map.get("attrs").toArray().map((a) => ({ ...a })),
|
|
368
|
-
bindings: map.get("bindings").toArray().map((b) => ({ ...b })),
|
|
369
|
-
children
|
|
370
|
-
};
|
|
371
|
-
if (prefix !== void 0) xml.prefix = prefix;
|
|
372
|
-
return xml;
|
|
373
|
-
}
|
|
374
379
|
var escapeText = (value) => value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
375
380
|
var escapeAttr = (value) => value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/\t/g, "	").replace(/\n/g, " ").replace(/\r/g, " ");
|
|
376
381
|
var qualified = (prefix, local) => prefix ? `${prefix}:${local}` : local;
|
|
377
|
-
function
|
|
378
|
-
const inScope =
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
for (const b of el.bindings) {
|
|
382
|
+
function startTag(prefix, local, bindings, attrs, scope) {
|
|
383
|
+
const inScope = withBindings(scope, bindings);
|
|
384
|
+
let out = `<${qualified(prefix, local)}`;
|
|
385
|
+
for (const b of bindings) {
|
|
382
386
|
out += b.prefix === "" ? ` xmlns="${escapeAttr(b.ns)}"` : ` xmlns:${b.prefix}="${escapeAttr(b.ns)}"`;
|
|
383
387
|
}
|
|
384
|
-
for (const a of
|
|
388
|
+
for (const a of attrs) {
|
|
385
389
|
let p = a.prefix;
|
|
386
390
|
if (a.ns !== "" && !p) {
|
|
387
391
|
for (const [candidate, uri] of inScope) {
|
|
@@ -393,48 +397,41 @@ function serializeXml(el, scope) {
|
|
|
393
397
|
}
|
|
394
398
|
out += ` ${qualified(p, a.local)}="${escapeAttr(a.value)}"`;
|
|
395
399
|
}
|
|
400
|
+
return [out, inScope];
|
|
401
|
+
}
|
|
402
|
+
function serializeXml(el, scope) {
|
|
403
|
+
const [out, inScope] = startTag(el.prefix, el.local, el.bindings, el.attrs, scope);
|
|
396
404
|
if (el.children.length === 0) return `${out}/>`;
|
|
397
|
-
|
|
405
|
+
let body = "";
|
|
398
406
|
for (const child of el.children) {
|
|
399
|
-
|
|
407
|
+
body += typeof child === "string" ? escapeText(child) : serializeXml(child, inScope);
|
|
400
408
|
}
|
|
401
|
-
return `${out}</${qualified(el.prefix, el.local)}>`;
|
|
409
|
+
return `${out}>${body}</${qualified(el.prefix, el.local)}>`;
|
|
402
410
|
}
|
|
403
411
|
function serializeLive(el, scope) {
|
|
404
|
-
if (
|
|
412
|
+
if (isPackedElement(el)) return el.get(PACKED);
|
|
405
413
|
const prefix = el.get("prefix");
|
|
406
414
|
const local = el.get("local");
|
|
407
415
|
const bindings = el.get("bindings").toArray();
|
|
408
416
|
const attrs = el.get("attrs").toArray();
|
|
409
417
|
const children = el.get("children").toArray();
|
|
410
|
-
const inScope =
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
out += b.prefix === "" ? ` xmlns="${escapeAttr(b.ns)}"` : ` xmlns:${b.prefix}="${escapeAttr(b.ns)}"`;
|
|
415
|
-
}
|
|
416
|
-
for (const a of attrs) {
|
|
417
|
-
let p = a.prefix;
|
|
418
|
-
if (a.ns !== "" && !p) {
|
|
419
|
-
for (const [candidate, uri] of inScope) {
|
|
420
|
-
if (candidate !== "" && uri === a.ns) {
|
|
421
|
-
p = candidate;
|
|
422
|
-
break;
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
}
|
|
426
|
-
out += ` ${qualified(p, a.local)}="${escapeAttr(a.value)}"`;
|
|
427
|
-
}
|
|
428
|
-
if (children.length === 0) return `${out}/>`;
|
|
429
|
-
out += ">";
|
|
418
|
+
const [out, inScope] = startTag(prefix, local, bindings, attrs, scope);
|
|
419
|
+
const inline = isRichParagraph(el) ? decodeInline(readUnits(el.get("inline"))) : [];
|
|
420
|
+
if (children.length === 0 && inline.length === 0) return `${out}/>`;
|
|
421
|
+
let body = "";
|
|
430
422
|
for (const child of children) {
|
|
431
|
-
|
|
423
|
+
body += child instanceof Y.Text ? escapeText(child.toString()) : serializeLive(child, inScope);
|
|
432
424
|
}
|
|
433
|
-
|
|
425
|
+
for (const child of inline) body += serializeXml(child, inScope);
|
|
426
|
+
return `${out}>${body}</${qualified(prefix, local)}>`;
|
|
434
427
|
}
|
|
435
428
|
|
|
436
429
|
// src/encoding.ts
|
|
437
|
-
var COLLAB_FORMAT = "arbi-docx/
|
|
430
|
+
var COLLAB_FORMAT = "arbi-docx/2";
|
|
431
|
+
var READABLE_FORMATS = /* @__PURE__ */ new Set(["arbi-docx/1", COLLAB_FORMAT]);
|
|
432
|
+
function isReadableFormat(format) {
|
|
433
|
+
return format !== void 0 && READABLE_FORMATS.has(format);
|
|
434
|
+
}
|
|
438
435
|
function isText(node) {
|
|
439
436
|
return node.kind === "textValue";
|
|
440
437
|
}
|
|
@@ -455,7 +452,7 @@ function canonicalToXml(node) {
|
|
|
455
452
|
return xml;
|
|
456
453
|
}
|
|
457
454
|
function encodeElement(el) {
|
|
458
|
-
return xmlToLive(canonicalToXml(el));
|
|
455
|
+
return xmlToLive(canonicalToXml(el), /* @__PURE__ */ new Map(), true);
|
|
459
456
|
}
|
|
460
457
|
function encodeText(value) {
|
|
461
458
|
return newText(value);
|
|
@@ -711,6 +708,6 @@ function bootstrapFromBytes(doc, bytes) {
|
|
|
711
708
|
return result.package;
|
|
712
709
|
}
|
|
713
710
|
|
|
714
|
-
export { COLLAB_FORMAT, MaterializeCache, MaterializeError, bootstrap, bootstrapFromBytes, contentTypeOf, encodeElement, encodeText, isBootstrapped, materialize, materializeBytes, readFormat, registerMirror, serializePart };
|
|
711
|
+
export { COLLAB_FORMAT, MaterializeCache, MaterializeError, bootstrap, bootstrapFromBytes, contentTypeOf, encodeElement, encodeText, isBootstrapped, isReadableFormat, materialize, materializeBytes, readFormat, registerMirror, serializePart };
|
|
715
712
|
//# sourceMappingURL=encoding.js.map
|
|
716
713
|
//# sourceMappingURL=encoding.js.map
|