@portone/docx-editor 0.2.1 → 0.3.0
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 +109 -0
- package/CONTRIBUTING.md +5 -1
- package/dist/DocxEditor.d.ts +6 -0
- package/dist/DocxEditor.js +12 -29
- package/dist/core.d.ts +23 -8
- package/dist/core.js +9 -4
- package/dist/docx/cloning.d.ts +38 -0
- package/dist/docx/cloning.js +74 -0
- package/dist/docx/commentOnlyChange.d.ts +12 -7
- package/dist/docx/commentOnlyChange.js +9 -156
- package/dist/docx/comments/constants.d.ts +0 -1
- package/dist/docx/comments/constants.js +0 -2
- package/dist/docx/comments/grammar.d.ts +10 -4
- package/dist/docx/comments/grammar.js +12 -2
- package/dist/docx/comments/{verifying.d.ts → parts.d.ts} +26 -18
- package/dist/docx/comments/parts.js +279 -0
- package/dist/docx/comments/people.d.ts +11 -2
- package/dist/docx/comments/people.js +16 -92
- package/dist/docx/comments/policy.d.ts +7 -0
- package/dist/docx/comments/policy.js +43 -0
- package/dist/docx/comments/reading.js +8 -10
- package/dist/docx/comments/writing.d.ts +19 -7
- package/dist/docx/comments/writing.js +52 -111
- package/dist/docx/documentSettings.d.ts +7 -0
- package/dist/docx/documentSettings.js +10 -2
- package/dist/docx/exportDocx.d.ts +40 -5
- package/dist/docx/exportDocx.js +69 -71
- package/dist/docx/exportRefs.d.ts +5 -2
- package/dist/docx/exportRefs.js +3 -1
- package/dist/docx/fidelity.d.ts +43 -0
- package/dist/docx/fidelity.js +64 -0
- package/dist/docx/formatting/attrs.d.ts +27 -0
- package/dist/docx/formatting/attrs.js +31 -0
- package/dist/docx/formatting/context.d.ts +31 -0
- package/dist/docx/formatting/context.js +42 -0
- package/dist/docx/formatting/direct.d.ts +6 -5
- package/dist/docx/formatting/direct.js +52 -78
- package/dist/docx/formatting/resolve.d.ts +45 -0
- package/dist/docx/formatting/resolve.js +140 -0
- package/dist/docx/formatting/runProperties.d.ts +93 -0
- package/dist/docx/formatting/runProperties.js +316 -0
- package/dist/docx/formatting/styles.js +3 -3
- package/dist/docx/formatting/tabStops.js +7 -22
- package/dist/docx/formatting.d.ts +4 -1
- package/dist/docx/formatting.js +4 -1
- package/dist/docx/headersFooters.js +6 -13
- package/dist/docx/identities.d.ts +67 -0
- package/dist/docx/identities.js +174 -0
- package/dist/docx/importDocx.d.ts +12 -1
- package/dist/docx/importDocx.js +72 -79
- package/dist/docx/importParagraph.d.ts +1 -1
- package/dist/docx/importParagraph.js +4 -3
- package/dist/docx/importTable.d.ts +1 -1
- package/dist/docx/importTable.js +17 -1
- package/dist/docx/invariants.d.ts +33 -0
- package/dist/docx/invariants.js +256 -0
- package/dist/docx/media.d.ts +6 -4
- package/dist/docx/media.js +6 -37
- package/dist/docx/newLists.d.ts +20 -0
- package/dist/docx/newLists.js +36 -0
- package/dist/docx/notes.js +3 -7
- package/dist/docx/numberingPlanner.d.ts +8 -0
- package/dist/docx/numberingPlanner.js +19 -0
- package/dist/docx/packageParts.d.ts +42 -0
- package/dist/docx/packageParts.js +135 -0
- package/dist/docx/pageGeometry.d.ts +2 -0
- package/dist/docx/pageGeometry.js +18 -9
- package/dist/docx/paraProps.d.ts +10 -22
- package/dist/docx/paraProps.js +47 -76
- package/dist/docx/partPlan.d.ts +36 -0
- package/dist/docx/partPlan.js +59 -0
- package/dist/docx/protectionPolicy.d.ts +127 -0
- package/dist/docx/protectionPolicy.js +169 -0
- package/dist/docx/relationships.d.ts +1 -1
- package/dist/docx/relationships.js +8 -13
- package/dist/docx/runProps.d.ts +9 -22
- package/dist/docx/runProps.js +15 -168
- package/dist/docx/scan.js +20 -52
- package/dist/docx/sdt.js +9 -34
- package/dist/docx/sdtProps.d.ts +8 -1
- package/dist/docx/sdtProps.js +10 -0
- package/dist/docx/serializeBlock.d.ts +2 -0
- package/dist/docx/serializeBlock.js +8 -5
- package/dist/docx/serializeTable.js +32 -15
- package/dist/docx/session.d.ts +42 -14
- package/dist/docx/session.js +43 -17
- package/dist/docx/tableFormatting/editing.js +108 -139
- package/dist/docx/tableFormatting/reading.d.ts +16 -6
- package/dist/docx/tableFormatting/reading.js +40 -20
- package/dist/docx/tableTemplate.js +18 -7
- package/dist/download.d.ts +8 -5
- package/dist/download.js +2 -0
- package/dist/editor/clipboard/inlineFormatting.js +19 -30
- package/dist/editor/commands/comments/editing.d.ts +6 -2
- package/dist/editor/commands/comments/editing.js +19 -31
- package/dist/editor/commands/exportQueries.d.ts +15 -0
- package/dist/editor/commands/exportQueries.js +14 -0
- package/dist/editor/commands/fidelityQueries.d.ts +12 -0
- package/dist/editor/commands/fidelityQueries.js +8 -0
- package/dist/editor/commands/formatting/editing.d.ts +2 -2
- package/dist/editor/commands/formatting/editing.js +26 -108
- package/dist/editor/commands/formatting/propertyCommands.d.ts +21 -0
- package/dist/editor/commands/formatting/propertyCommands.js +103 -0
- package/dist/editor/commands/formatting/shared.d.ts +3 -3
- package/dist/editor/commands/formatting/shared.js +5 -2
- package/dist/editor/commands/indentCommands.js +5 -4
- package/dist/editor/commands/index.d.ts +11 -0
- package/dist/editor/commands/index.js +5 -0
- package/dist/editor/commands/linkCommands.js +5 -6
- package/dist/editor/commands/listCommands.js +8 -10
- package/dist/editor/commands/lockCommands.d.ts +7 -1
- package/dist/editor/commands/lockCommands.js +35 -46
- package/dist/editor/commands/paragraphCommands.js +28 -31
- package/dist/editor/commands/spacingCommands.js +1 -1
- package/dist/editor/createEditor.d.ts +17 -29
- package/dist/editor/createEditor.js +58 -58
- package/dist/editor/documentStyles.d.ts +11 -35
- package/dist/editor/documentStyles.js +9 -52
- package/dist/editor/editorDocument.d.ts +56 -0
- package/dist/editor/editorDocument.js +74 -0
- package/dist/editor/externalClipboard.js +16 -45
- package/dist/editor/insertTable.js +4 -3
- package/dist/editor/paragraphEdits.d.ts +11 -18
- package/dist/editor/paragraphEdits.js +7 -16
- package/dist/editor/plugins/displayDerivation.d.ts +47 -0
- package/dist/editor/plugins/displayDerivation.js +78 -0
- package/dist/editor/plugins/imagePaste.js +4 -3
- package/dist/editor/plugins/keymap.js +18 -3
- package/dist/editor/plugins/numberingDecorations.d.ts +5 -11
- package/dist/editor/plugins/numberingDecorations.js +7 -17
- package/dist/editor/plugins/paragraphDisplay.d.ts +7 -0
- package/dist/editor/plugins/paragraphDisplay.js +51 -0
- package/dist/editor/plugins/tabLayout.js +1 -1
- package/dist/editor/plugins/tableDisplay.d.ts +6 -0
- package/dist/editor/plugins/tableDisplay.js +16 -0
- package/dist/index.d.ts +2 -0
- package/dist/model/format.d.ts +30 -8
- package/dist/model/format.js +35 -22
- package/dist/model/tabStops.d.ts +9 -0
- package/dist/model/tabStops.js +18 -0
- package/dist/numbering/listTemplate.js +24 -7
- package/dist/numbering/parseNumbering.d.ts +14 -1
- package/dist/numbering/parseNumbering.js +35 -22
- package/dist/numbering/writeNumbering.d.ts +3 -4
- package/dist/numbering/writeNumbering.js +14 -25
- package/dist/ooxml/childOrder.d.ts +34 -0
- package/dist/ooxml/childOrder.js +496 -0
- package/dist/ooxml/element.d.ts +24 -11
- package/dist/ooxml/element.js +31 -12
- package/dist/ooxml/errors.d.ts +3 -2
- package/dist/ooxml/image.d.ts +4 -0
- package/dist/ooxml/image.js +2 -5
- package/dist/ooxml/partSplice.d.ts +67 -0
- package/dist/ooxml/partSplice.js +169 -0
- package/dist/ooxml/props.d.ts +112 -0
- package/dist/{docx/propsXml.js → ooxml/props.js} +72 -200
- package/dist/ooxml/simpleTypes.d.ts +103 -0
- package/dist/ooxml/simpleTypes.js +182 -0
- package/dist/ooxml/tabStops.js +8 -27
- package/dist/ooxml/tagScan.d.ts +34 -0
- package/dist/ooxml/tagScan.js +108 -0
- package/dist/ooxml/units.d.ts +25 -13
- package/dist/ooxml/units.js +65 -31
- package/dist/ooxml/xml.d.ts +27 -6
- package/dist/ooxml/xml.js +37 -5
- package/dist/page/blockKinds.d.ts +61 -0
- package/dist/page/blockKinds.js +11 -0
- package/dist/page/kinds/index.d.ts +6 -0
- package/dist/page/kinds/index.js +10 -0
- package/dist/page/kinds/paragraphKind.d.ts +10 -0
- package/dist/page/kinds/paragraphKind.js +71 -0
- package/dist/page/kinds/tableKind.d.ts +10 -0
- package/dist/page/kinds/tableKind.js +178 -0
- package/dist/page/measureBlocks.d.ts +3 -14
- package/dist/page/measureBlocks.js +24 -45
- package/dist/page/pageDecorations.d.ts +27 -44
- package/dist/page/pageDecorations.js +70 -152
- package/dist/page/pageLayout.d.ts +2 -19
- package/dist/page/pageLayout.js +36 -6
- package/dist/page/usePageLayout.d.ts +2 -17
- package/dist/page/usePageLayout.js +3 -39
- package/dist/schema/attrRoles.d.ts +25 -18
- package/dist/schema/attrRoles.js +102 -67
- package/dist/schema/displayDerivation.d.ts +82 -0
- package/dist/schema/displayDerivation.js +130 -0
- package/dist/schema/docxSchema.d.ts +3 -0
- package/dist/schema/docxSchema.js +26 -14
- package/dist/schema/editGuard.d.ts +1 -1
- package/dist/schema/guards.d.ts +37 -14
- package/dist/schema/guards.js +29 -3
- package/dist/schema/index.d.ts +2 -0
- package/dist/schema/index.js +2 -0
- package/dist/schema/locks.d.ts +11 -44
- package/dist/schema/locks.js +0 -9
- package/dist/schema/preservedGuards.d.ts +26 -6
- package/dist/schema/preservedGuards.js +31 -1
- package/dist/schema/protection.d.ts +7 -1
- package/dist/schema/protection.js +2 -1
- package/dist/schema/sourceEquality.d.ts +1 -9
- package/dist/schema/sourceEquality.js +1 -27
- package/dist/styles/inlineStyle.js +15 -6
- package/dist/table/cellFormatting.d.ts +8 -1
- package/dist/table/cellFormatting.js +10 -18
- package/dist/table/commands.js +20 -18
- package/dist/table/format.d.ts +3 -0
- package/dist/table/format.js +3 -9
- package/dist/table/gridBorders.d.ts +14 -16
- package/dist/table/gridBorders.js +3 -41
- package/dist/table/merge.d.ts +2 -6
- package/dist/table/merge.js +5 -5
- package/package.json +7 -3
- package/dist/docx/comments/contentTypes.d.ts +0 -7
- package/dist/docx/comments/contentTypes.js +0 -38
- package/dist/docx/comments/verifying.js +0 -206
- package/dist/docx/formatting/effectiveParagraph.d.ts +0 -15
- package/dist/docx/formatting/effectiveParagraph.js +0 -81
- package/dist/docx/propsXml.d.ts +0 -67
- package/dist/docx/uniqueControls.d.ts +0 -14
- package/dist/docx/uniqueControls.js +0 -62
- package/dist/editor/plugins/commentReservations.d.ts +0 -5
- package/dist/editor/plugins/commentReservations.js +0 -26
- package/dist/editor/plugins/styledParagraphs.d.ts +0 -15
- package/dist/editor/plugins/styledParagraphs.js +0 -65
- package/dist/page/tableMeasurements.d.ts +0 -18
- package/dist/page/tableMeasurements.js +0 -119
|
@@ -1,161 +1,14 @@
|
|
|
1
1
|
// src/docx/commentOnlyChange.ts
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
COMMENTS_EXTENDED_CONTENT_TYPE,
|
|
12
|
-
COMMENTS_EXTENDED_REL_TYPE,
|
|
13
|
-
COMMENTS_REL_TYPE,
|
|
14
|
-
CONTENT_TYPES_PATH,
|
|
15
|
-
PEOPLE_CONTENT_TYPE,
|
|
16
|
-
PEOPLE_REL_TYPE
|
|
17
|
-
} from "./comments/constants.js";
|
|
18
|
-
import { commentPartsKept } from "./comments/verifying.js";
|
|
19
|
-
import { importDocx } from "./importDocx.js";
|
|
20
|
-
import {
|
|
21
|
-
readRelationships,
|
|
22
|
-
relsPathOf
|
|
23
|
-
} from "./relationships.js";
|
|
24
|
-
import {
|
|
25
|
-
comparableStory,
|
|
26
|
-
isModelledBlock
|
|
27
|
-
} from "./storyProjection.js";
|
|
28
|
-
var COMMENT_REL_TYPES = [
|
|
29
|
-
COMMENTS_REL_TYPE,
|
|
30
|
-
COMMENTS_EXTENDED_REL_TYPE,
|
|
31
|
-
PEOPLE_REL_TYPE
|
|
32
|
-
];
|
|
33
|
-
var COMMENT_CONTENT_TYPES = [
|
|
34
|
-
COMMENTS_CONTENT_TYPE,
|
|
35
|
-
COMMENTS_EXTENDED_CONTENT_TYPE,
|
|
36
|
-
PEOPLE_CONTENT_TYPE
|
|
37
|
-
];
|
|
38
|
-
var refused = (reason) => ({ ok: false, reason });
|
|
39
|
-
function sameBytes(before, after) {
|
|
40
|
-
return before.length === after.length && before.every((byte, index) => byte === after[index]);
|
|
41
|
-
}
|
|
42
|
-
function commentPartsOf(session) {
|
|
43
|
-
const { partPath, extendedPartPath, people } = session.comments;
|
|
44
|
-
return [partPath, extendedPartPath, people.partPath];
|
|
45
|
-
}
|
|
46
|
-
function commentPartPaths(session) {
|
|
47
|
-
return new Set(
|
|
48
|
-
commentPartsOf(session).filter((path) => path !== null)
|
|
49
|
-
);
|
|
50
|
-
}
|
|
51
|
-
function aroundTheStory(session) {
|
|
52
|
-
const preserved = session.blocks.filter((block) => !isModelledBlock(block.node)).map((block) => block.xml).join("");
|
|
53
|
-
return session.documentPrefix + preserved + session.documentSuffix;
|
|
54
|
-
}
|
|
55
|
-
function relationshipsKept(before, after) {
|
|
56
|
-
if (new Set(before.map((entry) => entry.id)).size !== before.length || new Set(after.map((entry) => entry.id)).size !== after.length) {
|
|
57
|
-
return false;
|
|
58
|
-
}
|
|
59
|
-
const now = new Map(after.map((entry) => [entry.id, entry]));
|
|
60
|
-
const kept = before.every((entry) => {
|
|
61
|
-
const current = now.get(entry.id);
|
|
62
|
-
return current !== void 0 && current.type === entry.type && current.target === entry.target && current.external === entry.external;
|
|
2
|
+
import { commentsPolicy } from "./comments/policy.js";
|
|
3
|
+
import { verifyChange } from "./protectionPolicy.js";
|
|
4
|
+
function onlyCommentsChangedBy(original, submitted, authorId, {
|
|
5
|
+
editableComments = "own",
|
|
6
|
+
xmlParser
|
|
7
|
+
} = {}) {
|
|
8
|
+
return verifyChange(commentsPolicy, original, submitted, authorId, {
|
|
9
|
+
editableComments,
|
|
10
|
+
xmlParser
|
|
63
11
|
});
|
|
64
|
-
const ids = new Set(before.map((entry) => entry.id));
|
|
65
|
-
const parts = after.filter((entry) => !entry.external);
|
|
66
|
-
return kept && after.filter((entry) => !ids.has(entry.id)).every(
|
|
67
|
-
(entry) => COMMENT_REL_TYPES.includes(entry.type) && !entry.external && parts.filter((other) => other.type === entry.type).length === 1
|
|
68
|
-
);
|
|
69
|
-
}
|
|
70
|
-
function contentTypes(bytes) {
|
|
71
|
-
if (bytes === void 0) return /* @__PURE__ */ new Map();
|
|
72
|
-
const declared = /* @__PURE__ */ new Map();
|
|
73
|
-
for (const el of elementChildren(
|
|
74
|
-
parseXml(decodeUtf8(bytes).text).documentElement
|
|
75
|
-
)) {
|
|
76
|
-
const key = el.localName === "Default" ? el.getAttribute("Extension") : el.localName === "Override" ? el.getAttribute("PartName") : null;
|
|
77
|
-
if (key !== null) declared.set(key, el.getAttribute("ContentType") ?? "");
|
|
78
|
-
}
|
|
79
|
-
return declared;
|
|
80
|
-
}
|
|
81
|
-
function contentTypesKept(before, after) {
|
|
82
|
-
for (const [key, type] of before) {
|
|
83
|
-
if (after.get(key) !== type) return false;
|
|
84
|
-
}
|
|
85
|
-
for (const [key, type] of after) {
|
|
86
|
-
if (!before.has(key) && !COMMENT_CONTENT_TYPES.includes(type)) return false;
|
|
87
|
-
}
|
|
88
|
-
return true;
|
|
89
|
-
}
|
|
90
|
-
function gainedCommentPartsAreNew(before, after) {
|
|
91
|
-
const had = commentPartsOf(before);
|
|
92
|
-
return commentPartsOf(after).every(
|
|
93
|
-
(path, kind) => path === null || path === had[kind] || !before.parts.has(path)
|
|
94
|
-
);
|
|
95
|
-
}
|
|
96
|
-
function packageKept(before, after) {
|
|
97
|
-
if (before.mainPartPath !== after.mainPartPath) {
|
|
98
|
-
return { ok: false, reason: "part-changed", part: before.mainPartPath };
|
|
99
|
-
}
|
|
100
|
-
const relsPath = relsPathOf(before.mainPartPath);
|
|
101
|
-
const untouched = /* @__PURE__ */ new Set([
|
|
102
|
-
before.mainPartPath,
|
|
103
|
-
relsPath,
|
|
104
|
-
CONTENT_TYPES_PATH,
|
|
105
|
-
...commentPartPaths(before),
|
|
106
|
-
...commentPartPaths(after)
|
|
107
|
-
]);
|
|
108
|
-
for (const path of /* @__PURE__ */ new Set([...before.parts.keys(), ...after.parts.keys()])) {
|
|
109
|
-
if (untouched.has(path)) continue;
|
|
110
|
-
const was = before.parts.get(path);
|
|
111
|
-
const now = after.parts.get(path);
|
|
112
|
-
if (was === void 0 || now === void 0 || !sameBytes(was, now)) {
|
|
113
|
-
return { ok: false, reason: "part-changed", part: path };
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
if (!relationshipsKept(
|
|
117
|
-
readRelationships(before.parts, relsPath),
|
|
118
|
-
readRelationships(after.parts, relsPath)
|
|
119
|
-
) || !gainedCommentPartsAreNew(before, after)) {
|
|
120
|
-
return { ok: false, reason: "relationship-changed", part: relsPath };
|
|
121
|
-
}
|
|
122
|
-
if (!contentTypesKept(
|
|
123
|
-
contentTypes(before.parts.get(CONTENT_TYPES_PATH)),
|
|
124
|
-
contentTypes(after.parts.get(CONTENT_TYPES_PATH))
|
|
125
|
-
)) {
|
|
126
|
-
return { ok: false, reason: "part-changed", part: CONTENT_TYPES_PATH };
|
|
127
|
-
}
|
|
128
|
-
if (aroundTheStory(before) !== aroundTheStory(after)) {
|
|
129
|
-
return { ok: false, reason: "part-changed", part: before.mainPartPath };
|
|
130
|
-
}
|
|
131
|
-
return { ok: true };
|
|
132
|
-
}
|
|
133
|
-
function sameBody(before, after) {
|
|
134
|
-
const was = comparableStory(before, withoutComments);
|
|
135
|
-
const now = comparableStory(after, withoutComments);
|
|
136
|
-
return was !== null && now !== null && was.length === now.length && was.every((block, at) => block === now[at]);
|
|
137
|
-
}
|
|
138
|
-
function storyKept(before, after, authorId, editableComments) {
|
|
139
|
-
if (!sameBody(before, after)) return refused("body-changed");
|
|
140
|
-
if (!commentIdentitiesKept(before.doc, after.doc) || !commentAdditionsBy(before.doc, after.doc, authorId)) {
|
|
141
|
-
return refused("comment-author-forged");
|
|
142
|
-
}
|
|
143
|
-
if (!commentEditsOwned(before.doc, after.doc, {
|
|
144
|
-
protection: "comments",
|
|
145
|
-
authorId,
|
|
146
|
-
editableComments
|
|
147
|
-
})) {
|
|
148
|
-
return refused("comment-not-owned");
|
|
149
|
-
}
|
|
150
|
-
return { ok: true };
|
|
151
|
-
}
|
|
152
|
-
function onlyCommentsChangedBy(original, submitted, authorId, { editableComments = "own" } = {}) {
|
|
153
|
-
const before = importDocx(original);
|
|
154
|
-
const after = importDocx(submitted);
|
|
155
|
-
const packaged = packageKept(before.session, after.session);
|
|
156
|
-
if (!packaged.ok) return packaged;
|
|
157
|
-
const story = storyKept(before, after, authorId, editableComments);
|
|
158
|
-
return story.ok ? commentPartsKept(before, after, authorId, editableComments) : story;
|
|
159
12
|
}
|
|
160
13
|
export {
|
|
161
14
|
onlyCommentsChangedBy
|
|
@@ -2,7 +2,6 @@ export declare const COMMENTS_REL_TYPE = "http://schemas.openxmlformats.org/offi
|
|
|
2
2
|
export declare const COMMENTS_EXTENDED_REL_TYPE = "http://schemas.microsoft.com/office/2011/relationships/commentsExtended";
|
|
3
3
|
export declare const COMMENTS_CONTENT_TYPE = "application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml";
|
|
4
4
|
export declare const COMMENTS_EXTENDED_CONTENT_TYPE = "application/vnd.openxmlformats-officedocument.wordprocessingml.commentsExtended+xml";
|
|
5
|
-
export declare const CONTENT_TYPES_PATH = "[Content_Types].xml";
|
|
6
5
|
export declare const W14_NS: "http://schemas.microsoft.com/office/word/2010/wordml";
|
|
7
6
|
export declare const W15_NS: "http://schemas.microsoft.com/office/word/2012/wordml";
|
|
8
7
|
export declare const MC_NS: "http://schemas.openxmlformats.org/markup-compatibility/2006";
|
|
@@ -5,7 +5,6 @@ var COMMENTS_REL_TYPE = `${R_NS}/comments`;
|
|
|
5
5
|
var COMMENTS_EXTENDED_REL_TYPE = "http://schemas.microsoft.com/office/2011/relationships/commentsExtended";
|
|
6
6
|
var COMMENTS_CONTENT_TYPE = "application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml";
|
|
7
7
|
var COMMENTS_EXTENDED_CONTENT_TYPE = "application/vnd.openxmlformats-officedocument.wordprocessingml.commentsExtended+xml";
|
|
8
|
-
var CONTENT_TYPES_PATH = "[Content_Types].xml";
|
|
9
8
|
var W14_NS = NAMESPACES.w14;
|
|
10
9
|
var W15_NS = NAMESPACES.w15;
|
|
11
10
|
var MC_NS = NAMESPACES.mc;
|
|
@@ -18,7 +17,6 @@ export {
|
|
|
18
17
|
COMMENTS_EXTENDED_REL_TYPE,
|
|
19
18
|
COMMENTS_REL_TYPE,
|
|
20
19
|
COMMENT_AUTHOR_PROVIDER,
|
|
21
|
-
CONTENT_TYPES_PATH,
|
|
22
20
|
MC_NS,
|
|
23
21
|
PEOPLE_CONTENT_TYPE,
|
|
24
22
|
PEOPLE_REL_TYPE,
|
|
@@ -14,11 +14,17 @@ export declare const COMMENT_ATTRIBUTES: ReadonlySet<string>;
|
|
|
14
14
|
/** The attributes this editor writes on a `w15:commentEx` */
|
|
15
15
|
export declare const COMMENT_EX_ATTRIBUTES: ReadonlySet<string>;
|
|
16
16
|
/**
|
|
17
|
-
* Whether the
|
|
17
|
+
* Whether the namespace declaration is one this editor's writer puts out, its value included.
|
|
18
18
|
*
|
|
19
|
-
* A
|
|
20
|
-
*
|
|
21
|
-
*
|
|
19
|
+
* A declaration decides what every name around it means, so one binding a prefix to a namespace
|
|
20
|
+
* this package does not write is markup the writer did not put there however ordinary the names
|
|
21
|
+
* under it look. The default declaration is never one of them: the writer spells out a prefix on
|
|
22
|
+
* everything it writes.
|
|
23
|
+
*/
|
|
24
|
+
export declare function declarationWritten(attr: Attr): boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Whether the element carries no attribute outside this set, and declares no namespace outside
|
|
27
|
+
* what the writer declares.
|
|
22
28
|
*/
|
|
23
29
|
export declare function attributesWithin(el: Element, allowed: ReadonlySet<string>): boolean;
|
|
24
30
|
/** The body of a comment, as a paragraph of one run holding the text and the breaks in it */
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
elementXml,
|
|
5
5
|
xmlnsAttr
|
|
6
6
|
} from "../../ooxml/element.js";
|
|
7
|
-
import { qualify, wName } from "../../ooxml/names.js";
|
|
7
|
+
import { NAMESPACES, qualify, wName } from "../../ooxml/names.js";
|
|
8
8
|
import {
|
|
9
9
|
attributeByLocalName,
|
|
10
10
|
elementChildren,
|
|
@@ -48,9 +48,18 @@ function threadKeyOrNone(el, localName) {
|
|
|
48
48
|
const value = attributeByLocalName(el, localName);
|
|
49
49
|
return value === null || THREAD_KEY.test(value);
|
|
50
50
|
}
|
|
51
|
+
var WRITTEN_NAMESPACES = /* @__PURE__ */ new Map([
|
|
52
|
+
["w", NAMESPACES.w],
|
|
53
|
+
["w14", NAMESPACES.w14],
|
|
54
|
+
["w15", NAMESPACES.w15]
|
|
55
|
+
]);
|
|
56
|
+
function declarationWritten(attr) {
|
|
57
|
+
if (!attr.name.startsWith("xmlns:")) return false;
|
|
58
|
+
return WRITTEN_NAMESPACES.get(attr.name.slice("xmlns:".length)) === attr.value;
|
|
59
|
+
}
|
|
51
60
|
function attributesWithin(el, allowed) {
|
|
52
61
|
return Array.from(el.attributes).every(
|
|
53
|
-
(attr) => attr.namespaceURI === XMLNS_NS
|
|
62
|
+
(attr) => attr.namespaceURI === XMLNS_NS ? declarationWritten(attr) : allowed.has(nameKey(attr.namespaceURI, attr.localName))
|
|
54
63
|
);
|
|
55
64
|
}
|
|
56
65
|
function isNamed(el, namespace, localName) {
|
|
@@ -201,6 +210,7 @@ export {
|
|
|
201
210
|
COMMENT_EX_ATTRIBUTES,
|
|
202
211
|
arrivedEntries,
|
|
203
212
|
attributesWithin,
|
|
213
|
+
declarationWritten,
|
|
204
214
|
lastBodyParagraph,
|
|
205
215
|
readStrictCommentBody,
|
|
206
216
|
recordedIdentity,
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* in
|
|
2
|
+
* The three parts a comment is written across, each declared once: where it sits, what it is
|
|
3
|
+
* declared as in the package, what an entry in it looks like, and who may have written one.
|
|
4
4
|
*
|
|
5
|
-
* The
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* The writer named the relationship and the content type where it added a part and the verifier
|
|
6
|
+
* named them again where it excused one, so the two were free to drift apart. Both read this
|
|
7
|
+
* instead, which is what makes a part the editor writes a part it takes back.
|
|
8
|
+
*
|
|
9
|
+
* What an entry is held to is two separate questions. Grammar asks whether this editor's writer
|
|
9
10
|
* could have put the entry out, whoever it belongs to. Permission asks whether this author could
|
|
10
11
|
* have made the change. Asking them as one would refuse a moderator rewriting somebody else's
|
|
11
12
|
* comment under `editableComments: "all"`, which is a thing the editor lets them do.
|
|
12
13
|
*/
|
|
13
14
|
import type { EditableComments } from "../../schema/protection";
|
|
14
|
-
import type {
|
|
15
|
-
import type { Story } from "../storyProjection";
|
|
15
|
+
import type { StoryPartKind } from "../protectionPolicy";
|
|
16
16
|
import { type ImportedPeople } from "./people";
|
|
17
17
|
/**
|
|
18
18
|
* Whether this editor's writer could have put the entry out, whoever it belongs to.
|
|
@@ -21,6 +21,15 @@ import { type ImportedPeople } from "./people";
|
|
|
21
21
|
* `entryAllowed`'s question. Each kind is read where it is written (`./grammar`).
|
|
22
22
|
*/
|
|
23
23
|
export declare function wellFormedEntry(entry: Element): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Whether the only thing between the two is that a thread gained its key.
|
|
26
|
+
*
|
|
27
|
+
* Settling a thread or replying to it belongs to everyone and leaves what the comment says alone,
|
|
28
|
+
* and the writer answers by putting the key on the entry that arrived rather than writing one of
|
|
29
|
+
* its own (`./grammar`). Such an entry is not a rewrite, so it is neither held to the grammar this
|
|
30
|
+
* editor writes bodies in nor to who owns the comment.
|
|
31
|
+
*/
|
|
32
|
+
export declare function threadKeyAlone(entry: Element, original: Element): boolean;
|
|
24
33
|
/**
|
|
25
34
|
* Whether `authorId` could have written or rewritten this entry.
|
|
26
35
|
*
|
|
@@ -32,13 +41,12 @@ export declare function wellFormedEntry(entry: Element): boolean;
|
|
|
32
41
|
* have to answer alike or a file the editor wrote would be turned down here.
|
|
33
42
|
*/
|
|
34
43
|
export declare function entryAllowed(entry: Element, original: Element | null, authorId: string, editableComments: EditableComments, people: ImportedPeople): boolean;
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
export declare function commentPartsKept(before: Story, after: Story, authorId: string, editableComments: EditableComments): CommentOnlyVerdict;
|
|
44
|
+
export declare const commentsPart: StoryPartKind;
|
|
45
|
+
export declare const commentsExtendedPart: StoryPartKind;
|
|
46
|
+
export declare const peoplePart: StoryPartKind;
|
|
47
|
+
/** The parts a comment protection lets an edit rewrite, in the order an export writes them */
|
|
48
|
+
export declare const COMMENT_STORY_PARTS: readonly [
|
|
49
|
+
StoryPartKind,
|
|
50
|
+
StoryPartKind,
|
|
51
|
+
StoryPartKind
|
|
52
|
+
];
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
// src/docx/comments/parts.ts
|
|
2
|
+
import { NAMESPACES } from "../../ooxml/names.js";
|
|
3
|
+
import {
|
|
4
|
+
attributeByLocalName,
|
|
5
|
+
isElement,
|
|
6
|
+
parseXml,
|
|
7
|
+
serializeXml,
|
|
8
|
+
W_NS
|
|
9
|
+
} from "../../ooxml/xml.js";
|
|
10
|
+
import { availablePartPath } from "../packageParts.js";
|
|
11
|
+
import {
|
|
12
|
+
COMMENTS_CONTENT_TYPE,
|
|
13
|
+
COMMENTS_EXTENDED_CONTENT_TYPE,
|
|
14
|
+
COMMENTS_EXTENDED_REL_TYPE,
|
|
15
|
+
COMMENTS_REL_TYPE,
|
|
16
|
+
PEOPLE_CONTENT_TYPE,
|
|
17
|
+
PEOPLE_REL_TYPE,
|
|
18
|
+
W14_NS,
|
|
19
|
+
W15_NS
|
|
20
|
+
} from "./constants.js";
|
|
21
|
+
import {
|
|
22
|
+
attributesWithin,
|
|
23
|
+
COMMENT_ATTRIBUTES,
|
|
24
|
+
declarationWritten,
|
|
25
|
+
lastBodyParagraph,
|
|
26
|
+
readStrictCommentBody,
|
|
27
|
+
recordedIdentity,
|
|
28
|
+
wellFormedCommentExtension,
|
|
29
|
+
wellFormedPerson
|
|
30
|
+
} from "./grammar.js";
|
|
31
|
+
import { commentReferencesIn } from "./model.js";
|
|
32
|
+
import { commentAuthorId } from "./people.js";
|
|
33
|
+
import { lastParagraphId } from "./reading.js";
|
|
34
|
+
var COMMENT_IDENTITY = [
|
|
35
|
+
"id",
|
|
36
|
+
"author",
|
|
37
|
+
"date",
|
|
38
|
+
"initials"
|
|
39
|
+
];
|
|
40
|
+
function sameAttributes(entry, original, names) {
|
|
41
|
+
return names.every(
|
|
42
|
+
(name) => attributeByLocalName(entry, name) === attributeByLocalName(original, name)
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
function wellFormedEntry(entry) {
|
|
46
|
+
if (entry.namespaceURI === W_NS && entry.localName === "comment") {
|
|
47
|
+
return attributesWithin(entry, COMMENT_ATTRIBUTES) && readStrictCommentBody(entry) !== null;
|
|
48
|
+
}
|
|
49
|
+
if (entry.namespaceURI === W15_NS && entry.localName === "commentEx") {
|
|
50
|
+
return wellFormedCommentExtension(entry);
|
|
51
|
+
}
|
|
52
|
+
if (entry.namespaceURI === W15_NS && entry.localName === "person") {
|
|
53
|
+
return wellFormedPerson(entry);
|
|
54
|
+
}
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
function withoutThreadKey(entry) {
|
|
58
|
+
const copy = entry.cloneNode(true);
|
|
59
|
+
if (!isElement(copy)) return serializeXml(entry);
|
|
60
|
+
const last = lastBodyParagraph(copy);
|
|
61
|
+
last?.removeAttributeNS(W14_NS, "paraId");
|
|
62
|
+
return serializeXml(copy);
|
|
63
|
+
}
|
|
64
|
+
function threadKeyAlone(entry, original) {
|
|
65
|
+
const before = lastParagraphId(original);
|
|
66
|
+
const after = lastParagraphId(entry);
|
|
67
|
+
const kept = before === null || after === before;
|
|
68
|
+
return kept && withoutThreadKey(entry) === withoutThreadKey(original);
|
|
69
|
+
}
|
|
70
|
+
function entryAllowed(entry, original, authorId, editableComments, people) {
|
|
71
|
+
if (entry.namespaceURI === W_NS && entry.localName === "comment") {
|
|
72
|
+
const author = attributeByLocalName(entry, "author");
|
|
73
|
+
const recorded = author === null ? null : commentAuthorId(people, author);
|
|
74
|
+
if (original === null) return recorded === authorId;
|
|
75
|
+
const paraId = lastParagraphId(original);
|
|
76
|
+
if (!sameAttributes(entry, original, COMMENT_IDENTITY) || paraId !== null && lastParagraphId(entry) !== paraId) {
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
return editableComments === "all" || recorded === null || recorded === authorId;
|
|
80
|
+
}
|
|
81
|
+
if (entry.namespaceURI === W15_NS && entry.localName === "commentEx") {
|
|
82
|
+
if (original === null) return true;
|
|
83
|
+
return sameAttributes(entry, original, ["paraId", "paraIdParent"]);
|
|
84
|
+
}
|
|
85
|
+
if (entry.namespaceURI === W15_NS && entry.localName === "person") {
|
|
86
|
+
return original === null && recordedIdentity(entry) === authorId;
|
|
87
|
+
}
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
var TEXT_NODE = 3;
|
|
91
|
+
var COMPATIBILITY = /* @__PURE__ */ new Map([
|
|
92
|
+
["xmlns:w14", NAMESPACES.w14],
|
|
93
|
+
["xmlns:mc", NAMESPACES.mc]
|
|
94
|
+
]);
|
|
95
|
+
var IGNORABLE = "mc:Ignorable";
|
|
96
|
+
var IGNORED = "w14";
|
|
97
|
+
function isLayout(node) {
|
|
98
|
+
return node.nodeType === TEXT_NODE && /^[ \t\r\n]*$/.test(node.nodeValue ?? "");
|
|
99
|
+
}
|
|
100
|
+
function surroundingNodes(parent) {
|
|
101
|
+
return parent === null ? [] : Array.from(parent.childNodes).filter(
|
|
102
|
+
(node) => !isElement(node) && !isLayout(node)
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
function sameNodes(now, was) {
|
|
106
|
+
return now.length === was.length && now.every((node, at) => {
|
|
107
|
+
const original = was[at];
|
|
108
|
+
return node.nodeType === original.nodeType && node.nodeName === original.nodeName && node.nodeValue === original.nodeValue;
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
function interEntryContentKept(now, was, rewritesContents) {
|
|
112
|
+
const current = surroundingNodes(now);
|
|
113
|
+
if (sameNodes(current, surroundingNodes(was))) return true;
|
|
114
|
+
return rewritesContents && current.length === 0 && was !== null && Array.from(now.children, serializeXml).join("") !== Array.from(was.children, serializeXml).join("");
|
|
115
|
+
}
|
|
116
|
+
function ignorableTokens(value) {
|
|
117
|
+
return new Set(value.split(/\s+/).filter(Boolean));
|
|
118
|
+
}
|
|
119
|
+
function ignorableKept(now, was) {
|
|
120
|
+
const gained = ignorableTokens(now);
|
|
121
|
+
const had = was === null ? /* @__PURE__ */ new Set() : ignorableTokens(was);
|
|
122
|
+
return Array.from(had).every((token) => gained.has(token)) && Array.from(gained).every((token) => had.has(token) || token === IGNORED);
|
|
123
|
+
}
|
|
124
|
+
function writtenRoot(root, shape) {
|
|
125
|
+
if (root.namespaceURI !== shape.namespace) return false;
|
|
126
|
+
if (root.localName !== shape.rootName) return false;
|
|
127
|
+
return Array.from(root.attributes).every(
|
|
128
|
+
(attr) => attr.name === IGNORABLE ? ignorableKept(attr.value, null) : declarationWritten(attr) || COMPATIBILITY.get(attr.name) === attr.value
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
function rootKeptAgainst(now, was, shape) {
|
|
132
|
+
if (was === null) return writtenRoot(now, shape);
|
|
133
|
+
if (now.nodeName !== was.nodeName) return false;
|
|
134
|
+
const had = new Map(
|
|
135
|
+
Array.from(was.attributes, (attr) => [attr.name, attr.value])
|
|
136
|
+
);
|
|
137
|
+
const kept = Array.from(now.attributes).every((attr) => {
|
|
138
|
+
const before = had.get(attr.name) ?? null;
|
|
139
|
+
if (attr.name === IGNORABLE) return ignorableKept(attr.value, before);
|
|
140
|
+
if (before === null) return COMPATIBILITY.get(attr.name) === attr.value;
|
|
141
|
+
return before === attr.value;
|
|
142
|
+
});
|
|
143
|
+
return kept && Array.from(had.keys()).every((name) => now.hasAttribute(name));
|
|
144
|
+
}
|
|
145
|
+
function entriesOf(shape, xml, reading) {
|
|
146
|
+
const entries = /* @__PURE__ */ new Map();
|
|
147
|
+
if (xml === null) return entries;
|
|
148
|
+
const strict = reading === "submitted";
|
|
149
|
+
for (const node of Array.from(parseXml(xml).documentElement.childNodes)) {
|
|
150
|
+
if (!isElement(node)) continue;
|
|
151
|
+
const el = node;
|
|
152
|
+
const named = strict ? el.namespaceURI === shape.namespace && el.localName === shape.localName : el.localName === shape.localName;
|
|
153
|
+
if (!named) {
|
|
154
|
+
if (strict) return null;
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
const id = attributeByLocalName(el, shape.idAttr);
|
|
158
|
+
if (id === null || entries.has(id)) {
|
|
159
|
+
if (strict) return null;
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
entries.set(id, { el, xml: serializeXml(el) });
|
|
163
|
+
}
|
|
164
|
+
return entries;
|
|
165
|
+
}
|
|
166
|
+
function arrivedIn(shape, session) {
|
|
167
|
+
return entriesOf(shape, shape.xmlIn(session), "arrived") ?? /* @__PURE__ */ new Map();
|
|
168
|
+
}
|
|
169
|
+
function storyPart(shape) {
|
|
170
|
+
return {
|
|
171
|
+
relType: shape.relType,
|
|
172
|
+
contentType: shape.contentType,
|
|
173
|
+
pathIn: shape.pathIn,
|
|
174
|
+
writePathIn: (session) => shape.pathIn(session) ?? availablePartPath(session.parts, session.mainPartPath, shape.baseName),
|
|
175
|
+
entriesIn: (session, reading) => entriesOf(shape, shape.xmlIn(session), reading),
|
|
176
|
+
rootKept: (before, after) => {
|
|
177
|
+
const submitted = shape.xmlIn(after);
|
|
178
|
+
if (submitted === null) return true;
|
|
179
|
+
const arrived = shape.xmlIn(before);
|
|
180
|
+
const now = parseXml(submitted);
|
|
181
|
+
const was = arrived === null ? null : parseXml(arrived);
|
|
182
|
+
return rootKeptAgainst(
|
|
183
|
+
now.documentElement,
|
|
184
|
+
was?.documentElement ?? null,
|
|
185
|
+
shape
|
|
186
|
+
) && sameNodes(surroundingNodes(now), surroundingNodes(was)) && interEntryContentKept(
|
|
187
|
+
now.documentElement,
|
|
188
|
+
was?.documentElement ?? null,
|
|
189
|
+
shape.rewritesContents
|
|
190
|
+
);
|
|
191
|
+
},
|
|
192
|
+
referents: shape.referents,
|
|
193
|
+
wellFormed: wellFormedEntry,
|
|
194
|
+
anyonesChange: threadKeyAlone,
|
|
195
|
+
allowed: (entry, original, authorId, options, session) => entryAllowed(
|
|
196
|
+
entry,
|
|
197
|
+
original,
|
|
198
|
+
authorId,
|
|
199
|
+
options.editableComments,
|
|
200
|
+
session.comments.people
|
|
201
|
+
)
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
function referencedCommentIds(doc) {
|
|
205
|
+
const ids = /* @__PURE__ */ new Set();
|
|
206
|
+
for (const [id, comment] of commentReferencesIn(doc)) {
|
|
207
|
+
ids.add(id);
|
|
208
|
+
for (const reply of comment.replies) ids.add(reply.id);
|
|
209
|
+
}
|
|
210
|
+
return ids;
|
|
211
|
+
}
|
|
212
|
+
var commentsShape = {
|
|
213
|
+
relType: COMMENTS_REL_TYPE,
|
|
214
|
+
contentType: COMMENTS_CONTENT_TYPE,
|
|
215
|
+
baseName: "comments",
|
|
216
|
+
namespace: W_NS,
|
|
217
|
+
rootName: "comments",
|
|
218
|
+
rewritesContents: true,
|
|
219
|
+
localName: "comment",
|
|
220
|
+
idAttr: "id",
|
|
221
|
+
xmlIn: (session) => session.comments.xml,
|
|
222
|
+
pathIn: (session) => session.comments.partPath,
|
|
223
|
+
referents: (story) => referencedCommentIds(story.doc)
|
|
224
|
+
};
|
|
225
|
+
function commentEntries(story) {
|
|
226
|
+
return Array.from(
|
|
227
|
+
arrivedIn(commentsShape, story.session).values(),
|
|
228
|
+
(entry) => entry.el
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
var commentsPart = storyPart(commentsShape);
|
|
232
|
+
var commentsExtendedPart = storyPart({
|
|
233
|
+
relType: COMMENTS_EXTENDED_REL_TYPE,
|
|
234
|
+
contentType: COMMENTS_EXTENDED_CONTENT_TYPE,
|
|
235
|
+
baseName: "commentsExtended",
|
|
236
|
+
namespace: W15_NS,
|
|
237
|
+
rootName: "commentsEx",
|
|
238
|
+
rewritesContents: true,
|
|
239
|
+
localName: "commentEx",
|
|
240
|
+
idAttr: "paraId",
|
|
241
|
+
xmlIn: (session) => session.comments.extendedXml,
|
|
242
|
+
pathIn: (session) => session.comments.extendedPartPath,
|
|
243
|
+
// Thread state stands for a comment, and it is keyed by the comment's own thread key
|
|
244
|
+
referents: (story) => new Set(
|
|
245
|
+
commentEntries(story).flatMap((el) => {
|
|
246
|
+
const key = lastParagraphId(el);
|
|
247
|
+
return key === null ? [] : [key];
|
|
248
|
+
})
|
|
249
|
+
)
|
|
250
|
+
});
|
|
251
|
+
var peoplePart = storyPart({
|
|
252
|
+
relType: PEOPLE_REL_TYPE,
|
|
253
|
+
contentType: PEOPLE_CONTENT_TYPE,
|
|
254
|
+
baseName: "people",
|
|
255
|
+
namespace: W15_NS,
|
|
256
|
+
rootName: "people",
|
|
257
|
+
rewritesContents: false,
|
|
258
|
+
localName: "person",
|
|
259
|
+
idAttr: "author",
|
|
260
|
+
xmlIn: (session) => session.comments.people.xml,
|
|
261
|
+
pathIn: (session) => session.comments.people.partPath,
|
|
262
|
+
// An identity stands for a name somebody writes comments under
|
|
263
|
+
referents: (story) => new Set(
|
|
264
|
+
commentEntries(story).flatMap((el) => {
|
|
265
|
+
const author = attributeByLocalName(el, "author");
|
|
266
|
+
return author === null ? [] : [author];
|
|
267
|
+
})
|
|
268
|
+
)
|
|
269
|
+
});
|
|
270
|
+
var COMMENT_STORY_PARTS = [commentsPart, commentsExtendedPart, peoplePart];
|
|
271
|
+
export {
|
|
272
|
+
COMMENT_STORY_PARTS,
|
|
273
|
+
commentsExtendedPart,
|
|
274
|
+
commentsPart,
|
|
275
|
+
entryAllowed,
|
|
276
|
+
peoplePart,
|
|
277
|
+
threadKeyAlone,
|
|
278
|
+
wellFormedEntry
|
|
279
|
+
};
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
* it stands and never appended to. Appending a second person for it would leave a file naming two
|
|
10
10
|
* identities for one name, where a reader keying by name hands one author's comments to the other.
|
|
11
11
|
*/
|
|
12
|
-
import {
|
|
12
|
+
import type { PartPlanContext } from "../partPlan";
|
|
13
|
+
import type { StoryPartKind } from "../protectionPolicy";
|
|
13
14
|
import type { SessionStore } from "../session";
|
|
14
15
|
import type { CommentReferenceData, CommentReplyData } from "./model";
|
|
15
16
|
export interface ImportedPeople {
|
|
@@ -31,9 +32,17 @@ export declare function readPeople(parts: Map<string, Uint8Array>, mainPartPath:
|
|
|
31
32
|
* record, and for one the part records under more than one identity.
|
|
32
33
|
*/
|
|
33
34
|
export declare function commentAuthorId(people: ImportedPeople, author: string): string | null;
|
|
35
|
+
/**
|
|
36
|
+
* The authors the part records no person for at all, each under the name they write as. A name it
|
|
37
|
+
* already records is left as it stands, whichever provider recorded it and whatever it resolves to.
|
|
38
|
+
*/
|
|
39
|
+
export declare function unrecordedAuthors(bodies: Iterable<CommentReferenceData | CommentReplyData>, people: ImportedPeople): Map<string, string>;
|
|
34
40
|
/**
|
|
35
41
|
* Plans the people part, its relationship and its content type for every identity the current
|
|
36
42
|
* comments carry that the document has not recorded. Null when it has recorded them all, which
|
|
37
43
|
* leaves the part as it arrived.
|
|
44
|
+
*
|
|
45
|
+
* `part` is the description the verifier reads the part back through (`./parts`), so where this
|
|
46
|
+
* writes it and what it declares it as are the same facts on both sides.
|
|
38
47
|
*/
|
|
39
|
-
export declare function planPeoplePart(bodies: Iterable<CommentReferenceData | CommentReplyData>, session: SessionStore,
|
|
48
|
+
export declare function planPeoplePart(part: StoryPartKind, bodies: Iterable<CommentReferenceData | CommentReplyData>, session: SessionStore, context: PartPlanContext): ReadonlyMap<string, Uint8Array> | null;
|