@portone/docx-editor 0.2.0 → 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 +174 -0
- package/CONTRIBUTING.md +9 -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 +14 -7
- package/dist/docx/commentOnlyChange.js +9 -139
- package/dist/docx/comments/constants.d.ts +3 -4
- package/dist/docx/comments/constants.js +4 -5
- package/dist/docx/comments/grammar.d.ts +86 -0
- package/dist/docx/comments/grammar.js +223 -0
- package/dist/docx/comments/parts.d.ts +52 -0
- package/dist/docx/comments/parts.js +279 -0
- package/dist/docx/comments/people.d.ts +11 -2
- package/dist/docx/comments/people.js +28 -106
- package/dist/docx/comments/policy.d.ts +7 -0
- package/dist/docx/comments/policy.js +43 -0
- package/dist/docx/comments/reading.d.ts +5 -3
- package/dist/docx/comments/reading.js +30 -29
- package/dist/docx/comments/writing.d.ts +19 -7
- package/dist/docx/comments/writing.js +105 -137
- 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 +71 -72
- 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 -81
- 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 +13 -22
- 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 +6 -12
- 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 +75 -99
- 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 +15 -15
- 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 +14 -37
- 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 +9 -7
- package/dist/docx/serializeParagraph.d.ts +2 -1
- package/dist/docx/serializeParagraph.js +25 -14
- package/dist/docx/serializeTable.js +63 -32
- package/dist/docx/session.d.ts +42 -14
- package/dist/docx/session.js +43 -17
- package/dist/docx/storyProjection.d.ts +36 -0
- package/dist/docx/storyProjection.js +23 -0
- package/dist/docx/tableFormatting/editing.js +130 -185
- package/dist/docx/tableFormatting/reading.d.ts +16 -6
- package/dist/docx/tableFormatting/reading.js +40 -20
- package/dist/docx/tableTemplate.js +37 -5
- package/dist/docx/theme.d.ts +0 -6
- package/dist/docx/theme.js +0 -8
- package/dist/download.d.ts +8 -5
- package/dist/download.js +2 -0
- package/dist/editor/clipboard/images.js +17 -3
- package/dist/editor/clipboard/inlineFormatting.d.ts +7 -0
- package/dist/editor/clipboard/inlineFormatting.js +20 -30
- package/dist/editor/commands/breakCommands.js +4 -3
- package/dist/editor/commands/canRunCommand.d.ts +2 -2
- package/dist/editor/commands/canRunCommand.js +1 -1
- package/dist/editor/commands/comments/editing.d.ts +6 -2
- package/dist/editor/commands/comments/editing.js +21 -36
- 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/historyCommands.js +2 -1
- 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 -37
- package/dist/editor/commands/paragraphCommands.js +28 -31
- package/dist/editor/commands/spacingCommands.js +1 -1
- package/dist/editor/commands/tabCommands.js +4 -3
- package/dist/editor/createEditor.d.ts +17 -29
- package/dist/editor/createEditor.js +61 -67
- 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 +166 -33
- package/dist/editor/insertImage.js +4 -3
- 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/documentProtection.d.ts +3 -3
- package/dist/editor/plugins/imagePaste.js +4 -3
- package/dist/editor/plugins/keymap.js +18 -3
- package/dist/editor/plugins/lockedContent.d.ts +4 -4
- package/dist/editor/plugins/lockedContent.js +1 -1
- 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 +49 -10
- 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 +65 -0
- package/dist/ooxml/element.js +68 -0
- package/dist/ooxml/errors.d.ts +3 -2
- package/dist/ooxml/fragment.d.ts +53 -0
- package/dist/ooxml/fragment.js +76 -0
- package/dist/ooxml/image.d.ts +4 -0
- package/dist/ooxml/image.js +3 -5
- package/dist/ooxml/names.d.ts +27 -0
- package/dist/ooxml/names.js +29 -0
- package/dist/ooxml/partSplice.d.ts +67 -0
- package/dist/ooxml/partSplice.js +169 -0
- package/dist/ooxml/precedence.d.ts +31 -0
- package/dist/ooxml/precedence.js +51 -0
- package/dist/ooxml/props.d.ts +112 -0
- package/dist/ooxml/props.js +214 -0
- 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 +52 -0
- package/dist/ooxml/xml.js +64 -5
- package/dist/page/blockKinds.d.ts +103 -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 -1
- package/dist/page/measureBlocks.js +24 -25
- package/dist/page/pageDecorations.d.ts +27 -28
- package/dist/page/pageDecorations.js +70 -151
- package/dist/page/pageLayout.d.ts +10 -62
- package/dist/page/pageLayout.js +60 -53
- package/dist/page/usePageLayout.d.ts +2 -2
- package/dist/page/usePageLayout.js +3 -11
- package/dist/schema/attrRoles.d.ts +42 -0
- package/dist/schema/attrRoles.js +141 -0
- package/dist/schema/displayDerivation.d.ts +82 -0
- package/dist/schema/displayDerivation.js +130 -0
- package/dist/schema/docxSchema.d.ts +9 -0
- package/dist/schema/docxSchema.js +237 -114
- package/dist/schema/editGuard.d.ts +99 -0
- package/dist/schema/editGuard.js +43 -0
- package/dist/schema/guards.d.ts +91 -0
- package/dist/schema/guards.js +108 -0
- package/dist/schema/index.d.ts +2 -0
- package/dist/schema/index.js +2 -0
- package/dist/schema/locks.d.ts +17 -77
- package/dist/schema/locks.js +26 -70
- package/dist/schema/preservedGuards.d.ts +50 -0
- package/dist/schema/preservedGuards.js +80 -0
- package/dist/schema/protection.d.ts +17 -4
- package/dist/schema/protection.js +4 -2
- package/dist/schema/sourceEquality.d.ts +19 -0
- package/dist/schema/sourceEquality.js +39 -0
- package/dist/styles/inlineStyle.js +15 -6
- package/dist/table/cellFormatting.d.ts +8 -1
- package/dist/table/cellFormatting.js +10 -17
- package/dist/table/commands.d.ts +2 -2
- 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/index.d.ts +2 -2
- package/dist/table/merge.d.ts +4 -8
- package/dist/table/merge.js +5 -5
- package/package.json +10 -3
- package/dist/docx/comments/contentTypes.d.ts +0 -7
- package/dist/docx/comments/contentTypes.js +0 -38
- package/dist/docx/formatting/effectiveParagraph.d.ts +0 -15
- package/dist/docx/formatting/effectiveParagraph.js +0 -81
- package/dist/docx/propsXml.d.ts +0 -49
- package/dist/docx/propsXml.js +0 -302
- package/dist/docx/uniqueControls.d.ts +0 -14
- package/dist/docx/uniqueControls.js +0 -62
- package/dist/editor/plugins/bookmarkProtection.d.ts +0 -3
- package/dist/editor/plugins/bookmarkProtection.js +0 -28
- package/dist/editor/plugins/commentReservations.d.ts +0 -5
- package/dist/editor/plugins/commentReservations.js +0 -26
- package/dist/editor/plugins/noteProtection.d.ts +0 -3
- package/dist/editor/plugins/noteProtection.js +0 -25
- package/dist/editor/plugins/styledParagraphs.d.ts +0 -15
- package/dist/editor/plugins/styledParagraphs.js +0 -65
- package/dist/page/tableMeasurements.d.ts +0 -10
- package/dist/page/tableMeasurements.js +0 -115
|
@@ -1,144 +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 { importDocx } from "./importDocx.js";
|
|
19
|
-
import {
|
|
20
|
-
readRelationships,
|
|
21
|
-
relsPathOf,
|
|
22
|
-
resolveTarget
|
|
23
|
-
} from "./relationships.js";
|
|
24
|
-
var COMMENT_REL_TYPES = [
|
|
25
|
-
COMMENTS_REL_TYPE,
|
|
26
|
-
COMMENTS_EXTENDED_REL_TYPE,
|
|
27
|
-
PEOPLE_REL_TYPE
|
|
28
|
-
];
|
|
29
|
-
var COMMENT_CONTENT_TYPES = [
|
|
30
|
-
COMMENTS_CONTENT_TYPE,
|
|
31
|
-
COMMENTS_EXTENDED_CONTENT_TYPE,
|
|
32
|
-
PEOPLE_CONTENT_TYPE
|
|
33
|
-
];
|
|
34
|
-
var refused = (reason) => ({ ok: false, reason });
|
|
35
|
-
function sameBytes(before, after) {
|
|
36
|
-
return before.length === after.length && before.every((byte, index) => byte === after[index]);
|
|
37
|
-
}
|
|
38
|
-
function commentPartPaths(session) {
|
|
39
|
-
const related = readRelationships(
|
|
40
|
-
session.parts,
|
|
41
|
-
relsPathOf(session.mainPartPath)
|
|
42
|
-
).filter(
|
|
43
|
-
(entry) => !entry.external && COMMENT_REL_TYPES.includes(entry.type)
|
|
44
|
-
);
|
|
45
|
-
return new Set(
|
|
46
|
-
related.map((entry) => resolveTarget(session.mainPartPath, entry.target))
|
|
47
|
-
);
|
|
48
|
-
}
|
|
49
|
-
function aroundTheStory(session) {
|
|
50
|
-
const preserved = session.blocks.filter(
|
|
51
|
-
(block) => block.node.type.name !== "paragraph" && block.node.type.name !== "table"
|
|
52
|
-
).map((block) => block.xml).join("");
|
|
53
|
-
return session.documentPrefix + preserved + session.documentSuffix;
|
|
54
|
-
}
|
|
55
|
-
function relationshipsKept(before, after) {
|
|
56
|
-
const now = new Map(after.map((entry) => [entry.id, entry]));
|
|
57
|
-
const kept = before.every((entry) => {
|
|
58
|
-
const current = now.get(entry.id);
|
|
59
|
-
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
|
|
60
11
|
});
|
|
61
|
-
const ids = new Set(before.map((entry) => entry.id));
|
|
62
|
-
return kept && after.every(
|
|
63
|
-
(entry) => ids.has(entry.id) || COMMENT_REL_TYPES.includes(entry.type)
|
|
64
|
-
);
|
|
65
|
-
}
|
|
66
|
-
function contentTypes(bytes) {
|
|
67
|
-
if (bytes === void 0) return /* @__PURE__ */ new Map();
|
|
68
|
-
const declared = /* @__PURE__ */ new Map();
|
|
69
|
-
for (const el of elementChildren(
|
|
70
|
-
parseXml(decodeUtf8(bytes).text).documentElement
|
|
71
|
-
)) {
|
|
72
|
-
const key = el.localName === "Default" ? el.getAttribute("Extension") : el.localName === "Override" ? el.getAttribute("PartName") : null;
|
|
73
|
-
if (key !== null) declared.set(key, el.getAttribute("ContentType") ?? "");
|
|
74
|
-
}
|
|
75
|
-
return declared;
|
|
76
|
-
}
|
|
77
|
-
function contentTypesKept(before, after) {
|
|
78
|
-
for (const [key, type] of before) {
|
|
79
|
-
if (after.get(key) !== type) return false;
|
|
80
|
-
}
|
|
81
|
-
for (const [key, type] of after) {
|
|
82
|
-
if (!before.has(key) && !COMMENT_CONTENT_TYPES.includes(type)) return false;
|
|
83
|
-
}
|
|
84
|
-
return true;
|
|
85
|
-
}
|
|
86
|
-
function packageKept(before, after) {
|
|
87
|
-
if (before.mainPartPath !== after.mainPartPath) {
|
|
88
|
-
return { ok: false, reason: "part-changed", part: before.mainPartPath };
|
|
89
|
-
}
|
|
90
|
-
const relsPath = relsPathOf(before.mainPartPath);
|
|
91
|
-
const untouched = /* @__PURE__ */ new Set([
|
|
92
|
-
before.mainPartPath,
|
|
93
|
-
relsPath,
|
|
94
|
-
CONTENT_TYPES_PATH,
|
|
95
|
-
...commentPartPaths(before),
|
|
96
|
-
...commentPartPaths(after)
|
|
97
|
-
]);
|
|
98
|
-
for (const path of /* @__PURE__ */ new Set([...before.parts.keys(), ...after.parts.keys()])) {
|
|
99
|
-
if (untouched.has(path)) continue;
|
|
100
|
-
const was = before.parts.get(path);
|
|
101
|
-
const now = after.parts.get(path);
|
|
102
|
-
if (was === void 0 || now === void 0 || !sameBytes(was, now)) {
|
|
103
|
-
return { ok: false, reason: "part-changed", part: path };
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
if (!relationshipsKept(
|
|
107
|
-
readRelationships(before.parts, relsPath),
|
|
108
|
-
readRelationships(after.parts, relsPath)
|
|
109
|
-
)) {
|
|
110
|
-
return { ok: false, reason: "relationship-changed", part: relsPath };
|
|
111
|
-
}
|
|
112
|
-
if (!contentTypesKept(
|
|
113
|
-
contentTypes(before.parts.get(CONTENT_TYPES_PATH)),
|
|
114
|
-
contentTypes(after.parts.get(CONTENT_TYPES_PATH))
|
|
115
|
-
)) {
|
|
116
|
-
return { ok: false, reason: "part-changed", part: CONTENT_TYPES_PATH };
|
|
117
|
-
}
|
|
118
|
-
if (aroundTheStory(before) !== aroundTheStory(after)) {
|
|
119
|
-
return { ok: false, reason: "part-changed", part: before.mainPartPath };
|
|
120
|
-
}
|
|
121
|
-
return { ok: true };
|
|
122
|
-
}
|
|
123
|
-
function storyKept(before, after, authorId, editableComments) {
|
|
124
|
-
if (!changesOnlyComments(before, after)) return refused("body-changed");
|
|
125
|
-
if (!commentIdentitiesKept(before, after) || !commentAdditionsBy(before, after, authorId)) {
|
|
126
|
-
return refused("comment-author-forged");
|
|
127
|
-
}
|
|
128
|
-
if (!commentEditsOwned(before, after, {
|
|
129
|
-
protection: "comments",
|
|
130
|
-
authorId,
|
|
131
|
-
editableComments
|
|
132
|
-
})) {
|
|
133
|
-
return refused("comment-not-owned");
|
|
134
|
-
}
|
|
135
|
-
return { ok: true };
|
|
136
|
-
}
|
|
137
|
-
function onlyCommentsChangedBy(original, submitted, authorId, { editableComments = "own" } = {}) {
|
|
138
|
-
const before = importDocx(original);
|
|
139
|
-
const after = importDocx(submitted);
|
|
140
|
-
const packaged = packageKept(before.session, after.session);
|
|
141
|
-
return packaged.ok ? storyKept(before.doc, after.doc, authorId, editableComments) : packaged;
|
|
142
12
|
}
|
|
143
13
|
export {
|
|
144
14
|
onlyCommentsChangedBy
|
|
@@ -2,10 +2,9 @@ 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
|
|
6
|
-
export declare const
|
|
7
|
-
export declare const
|
|
8
|
-
export declare const MC_NS = "http://schemas.openxmlformats.org/markup-compatibility/2006";
|
|
5
|
+
export declare const W14_NS: "http://schemas.microsoft.com/office/word/2010/wordml";
|
|
6
|
+
export declare const W15_NS: "http://schemas.microsoft.com/office/word/2012/wordml";
|
|
7
|
+
export declare const MC_NS: "http://schemas.openxmlformats.org/markup-compatibility/2006";
|
|
9
8
|
export declare const PEOPLE_REL_TYPE = "http://schemas.microsoft.com/office/2011/relationships/people";
|
|
10
9
|
export declare const PEOPLE_CONTENT_TYPE = "application/vnd.openxmlformats-officedocument.wordprocessingml.people+xml";
|
|
11
10
|
/**
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
// src/docx/comments/constants.ts
|
|
2
|
+
import { NAMESPACES } from "../../ooxml/names.js";
|
|
2
3
|
import { R_NS } from "../../ooxml/xml.js";
|
|
3
4
|
var COMMENTS_REL_TYPE = `${R_NS}/comments`;
|
|
4
5
|
var COMMENTS_EXTENDED_REL_TYPE = "http://schemas.microsoft.com/office/2011/relationships/commentsExtended";
|
|
5
6
|
var COMMENTS_CONTENT_TYPE = "application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml";
|
|
6
7
|
var COMMENTS_EXTENDED_CONTENT_TYPE = "application/vnd.openxmlformats-officedocument.wordprocessingml.commentsExtended+xml";
|
|
7
|
-
var
|
|
8
|
-
var
|
|
9
|
-
var
|
|
10
|
-
var MC_NS = "http://schemas.openxmlformats.org/markup-compatibility/2006";
|
|
8
|
+
var W14_NS = NAMESPACES.w14;
|
|
9
|
+
var W15_NS = NAMESPACES.w15;
|
|
10
|
+
var MC_NS = NAMESPACES.mc;
|
|
11
11
|
var PEOPLE_REL_TYPE = "http://schemas.microsoft.com/office/2011/relationships/people";
|
|
12
12
|
var PEOPLE_CONTENT_TYPE = "application/vnd.openxmlformats-officedocument.wordprocessingml.people+xml";
|
|
13
13
|
var COMMENT_AUTHOR_PROVIDER = "portone-docx-editor";
|
|
@@ -17,7 +17,6 @@ export {
|
|
|
17
17
|
COMMENTS_EXTENDED_REL_TYPE,
|
|
18
18
|
COMMENTS_REL_TYPE,
|
|
19
19
|
COMMENT_AUTHOR_PROVIDER,
|
|
20
|
-
CONTENT_TYPES_PATH,
|
|
21
20
|
MC_NS,
|
|
22
21
|
PEOPLE_CONTENT_TYPE,
|
|
23
22
|
PEOPLE_REL_TYPE,
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The shapes this editor writes the three comment parts in, and the reading of those shapes.
|
|
3
|
+
*
|
|
4
|
+
* Each entry is written here and judged here, so the two halves cannot drift apart: a body written
|
|
5
|
+
* by hand can be told from one this editor put out only where the writer and the reader agree on
|
|
6
|
+
* what it puts out. `./reading` keeps a lenient flattener for display, which takes whatever a
|
|
7
|
+
* producer wrote and shows what it can; this one judges an entry that came back and says no to
|
|
8
|
+
* everything else.
|
|
9
|
+
*/
|
|
10
|
+
import { type XmlAttr } from "../../ooxml/element";
|
|
11
|
+
import type { CommentReferenceData, CommentReplyData } from "./model";
|
|
12
|
+
/** The attributes this editor writes on a `w:comment`. The thread key goes on the body's paragraph */
|
|
13
|
+
export declare const COMMENT_ATTRIBUTES: ReadonlySet<string>;
|
|
14
|
+
/** The attributes this editor writes on a `w15:commentEx` */
|
|
15
|
+
export declare const COMMENT_EX_ATTRIBUTES: ReadonlySet<string>;
|
|
16
|
+
/**
|
|
17
|
+
* Whether the namespace declaration is one this editor's writer puts out, its value included.
|
|
18
|
+
*
|
|
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.
|
|
28
|
+
*/
|
|
29
|
+
export declare function attributesWithin(el: Element, allowed: ReadonlySet<string>): boolean;
|
|
30
|
+
/** The body of a comment, as a paragraph of one run holding the text and the breaks in it */
|
|
31
|
+
export declare function renderCommentBody(text: string, paraId: string | null): string;
|
|
32
|
+
/**
|
|
33
|
+
* The paragraph a thread key belongs on, which is the last one of the body.
|
|
34
|
+
*
|
|
35
|
+
* A body may hold a paragraph of another vocabulary, a picture's DrawingML `a:p` among them, and a
|
|
36
|
+
* key put on that says nothing about the thread. The namespace decides, since a prefix means only
|
|
37
|
+
* what the element it sits on binds it to, and a document may bind the same prefix twice over.
|
|
38
|
+
*/
|
|
39
|
+
export declare function lastBodyParagraph(comment: Element): Element | null;
|
|
40
|
+
/**
|
|
41
|
+
* The entries a part arrived holding, under the id each carries.
|
|
42
|
+
*
|
|
43
|
+
* The writer asks the document which paragraph a key goes on rather than asking the text, because
|
|
44
|
+
* only the document knows what a prefix means where it is written.
|
|
45
|
+
*/
|
|
46
|
+
export declare function arrivedEntries(partXml: string | null): ReadonlyMap<string, Element>;
|
|
47
|
+
/**
|
|
48
|
+
* The entry with the thread key on its body's last paragraph, and unchanged where it has one.
|
|
49
|
+
*
|
|
50
|
+
* Settling a thread or replying to it hangs the state off that key, and an entry that arrived
|
|
51
|
+
* without one has to gain it. Writing the entry afresh instead would put back only what this
|
|
52
|
+
* editor models, so a body holding more than plain text would lose it to a change nobody asked
|
|
53
|
+
* for and nobody made.
|
|
54
|
+
*
|
|
55
|
+
* `arrived` is that entry as the document has it, which is what says which paragraph is a
|
|
56
|
+
* WordprocessingML one and whether it already carries a key under some prefix. The text is only
|
|
57
|
+
* asked where that paragraph is: its opening tag is the one at the same place among the tags named
|
|
58
|
+
* `p`, counted the same way in both.
|
|
59
|
+
*
|
|
60
|
+
* The `w14` prefix is declared on the part rather than here: a part holding any thread state
|
|
61
|
+
* declares it on its root along with the compatibility markup that goes with it (`./writing`).
|
|
62
|
+
*/
|
|
63
|
+
export declare function withThreadKey(commentXml: string, paraId: string, arrived: Element | null): string;
|
|
64
|
+
/**
|
|
65
|
+
* The text of a comment written in that shape, and null for an entry holding anything else: a
|
|
66
|
+
* field, a second run, markup a producer wrapped it in, an attribute this editor does not write.
|
|
67
|
+
*
|
|
68
|
+
* An entry that arrived and was not edited is compared as it stands rather than read here, so
|
|
69
|
+
* saying no to a shape this editor would not have written turns down only a rewrite.
|
|
70
|
+
*/
|
|
71
|
+
/** Whether this editor's writer could have put out this thread state */
|
|
72
|
+
export declare function wellFormedCommentExtension(entry: Element): boolean;
|
|
73
|
+
/** Whether this editor's writer could have put out this recorded identity */
|
|
74
|
+
export declare function wellFormedPerson(entry: Element): boolean;
|
|
75
|
+
/** The identity a recorded person stands for, and null for an entry recording none */
|
|
76
|
+
export declare function recordedIdentity(person: Element): string | null;
|
|
77
|
+
export declare function readStrictCommentBody(comment: Element): string | null;
|
|
78
|
+
/** The thread state of one comment, as this editor writes it into the extended part */
|
|
79
|
+
export declare function renderCommentExtension(comment: CommentReferenceData | CommentReplyData): string;
|
|
80
|
+
/**
|
|
81
|
+
* The identity this editor records for an author, as it writes it into the people part.
|
|
82
|
+
*
|
|
83
|
+
* The prefix and the declaration come from the caller, which is writing into a part whose root
|
|
84
|
+
* already binds them or is being written from nothing.
|
|
85
|
+
*/
|
|
86
|
+
export declare function renderPerson(author: string, userId: string, prefix: string, declaration: XmlAttr | null): string;
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
// src/docx/comments/grammar.ts
|
|
2
|
+
import {
|
|
3
|
+
attrsText,
|
|
4
|
+
elementXml,
|
|
5
|
+
xmlnsAttr
|
|
6
|
+
} from "../../ooxml/element.js";
|
|
7
|
+
import { NAMESPACES, qualify, wName } from "../../ooxml/names.js";
|
|
8
|
+
import {
|
|
9
|
+
attributeByLocalName,
|
|
10
|
+
elementChildren,
|
|
11
|
+
escapeXml,
|
|
12
|
+
parseXml,
|
|
13
|
+
W_NS
|
|
14
|
+
} from "../../ooxml/xml.js";
|
|
15
|
+
import { COMMENT_AUTHOR_PROVIDER, W14_NS, W15_NS } from "./constants.js";
|
|
16
|
+
var ELEMENT_NODE = 1;
|
|
17
|
+
var TEXT_NODE = 3;
|
|
18
|
+
var XMLNS_NS = "http://www.w3.org/2000/xmlns/";
|
|
19
|
+
var XML_NS = "http://www.w3.org/XML/1998/namespace";
|
|
20
|
+
var nameKey = (namespace, localName) => `${namespace ?? ""} ${localName}`;
|
|
21
|
+
var COMMENT_ATTRIBUTES = /* @__PURE__ */ new Set([
|
|
22
|
+
nameKey(W_NS, "id"),
|
|
23
|
+
nameKey(W_NS, "author"),
|
|
24
|
+
nameKey(W_NS, "date"),
|
|
25
|
+
nameKey(W_NS, "initials")
|
|
26
|
+
]);
|
|
27
|
+
var COMMENT_EX_ATTRIBUTES = /* @__PURE__ */ new Set([
|
|
28
|
+
nameKey(W15_NS, "paraId"),
|
|
29
|
+
nameKey(W15_NS, "paraIdParent"),
|
|
30
|
+
nameKey(W15_NS, "done")
|
|
31
|
+
]);
|
|
32
|
+
var PARAGRAPH_ATTRIBUTES = /* @__PURE__ */ new Set([
|
|
33
|
+
nameKey(W14_NS, "paraId")
|
|
34
|
+
]);
|
|
35
|
+
var TEXT_ATTRIBUTES = /* @__PURE__ */ new Set([
|
|
36
|
+
nameKey(XML_NS, "space")
|
|
37
|
+
]);
|
|
38
|
+
var PERSON_ATTRIBUTES = /* @__PURE__ */ new Set([
|
|
39
|
+
nameKey(W15_NS, "author")
|
|
40
|
+
]);
|
|
41
|
+
var PRESENCE_ATTRIBUTES = /* @__PURE__ */ new Set([
|
|
42
|
+
nameKey(W15_NS, "providerId"),
|
|
43
|
+
nameKey(W15_NS, "userId")
|
|
44
|
+
]);
|
|
45
|
+
var NO_ATTRIBUTES = /* @__PURE__ */ new Set();
|
|
46
|
+
var THREAD_KEY = /^[0-9A-Fa-f]{8}$/;
|
|
47
|
+
function threadKeyOrNone(el, localName) {
|
|
48
|
+
const value = attributeByLocalName(el, localName);
|
|
49
|
+
return value === null || THREAD_KEY.test(value);
|
|
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
|
+
}
|
|
60
|
+
function attributesWithin(el, allowed) {
|
|
61
|
+
return Array.from(el.attributes).every(
|
|
62
|
+
(attr) => attr.namespaceURI === XMLNS_NS ? declarationWritten(attr) : allowed.has(nameKey(attr.namespaceURI, attr.localName))
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
function isNamed(el, namespace, localName) {
|
|
66
|
+
return el.namespaceURI === namespace && el.localName === localName;
|
|
67
|
+
}
|
|
68
|
+
function holdsElementsOnly(el) {
|
|
69
|
+
return Array.from(el.childNodes).every(
|
|
70
|
+
(node) => node.nodeType === ELEMENT_NODE
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
function holdsTextOnly(el) {
|
|
74
|
+
return Array.from(el.childNodes).every((node) => node.nodeType === TEXT_NODE);
|
|
75
|
+
}
|
|
76
|
+
function renderCommentBody(text, paraId) {
|
|
77
|
+
const lines = text.split("\n");
|
|
78
|
+
const pieces = [];
|
|
79
|
+
lines.forEach((line, index) => {
|
|
80
|
+
if (index > 0) pieces.push(elementXml(wName("br"), []));
|
|
81
|
+
if (line.length > 0 || lines.length === 1) {
|
|
82
|
+
pieces.push(
|
|
83
|
+
elementXml(wName("t"), [["xml:space", "preserve"]], [escapeXml(line)])
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
const key = paraId === null ? [] : [xmlnsAttr("w14"), [qualify("w14", "paraId"), paraId]];
|
|
88
|
+
return elementXml(wName("p"), key, [elementXml(wName("r"), [], pieces)]);
|
|
89
|
+
}
|
|
90
|
+
var PARAGRAPH_OR_SKIPPED = /<!--[\s\S]*?-->|<!\[CDATA\[[\s\S]*?\]\]>|<([^\s<>/:="']+:)?p(?=[\s/>])[^>]*>/g;
|
|
91
|
+
function lastBodyParagraph(comment) {
|
|
92
|
+
const paragraphs = comment.getElementsByTagNameNS(W_NS, "p");
|
|
93
|
+
return paragraphs.length === 0 ? null : paragraphs[paragraphs.length - 1];
|
|
94
|
+
}
|
|
95
|
+
function namedParagraphs(comment) {
|
|
96
|
+
return Array.from(comment.getElementsByTagName("*")).filter(
|
|
97
|
+
(element) => element.localName === "p"
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
function arrivedEntries(partXml) {
|
|
101
|
+
const entries = /* @__PURE__ */ new Map();
|
|
102
|
+
if (partXml === null) return entries;
|
|
103
|
+
let root;
|
|
104
|
+
try {
|
|
105
|
+
root = parseXml(partXml).documentElement;
|
|
106
|
+
} catch {
|
|
107
|
+
return entries;
|
|
108
|
+
}
|
|
109
|
+
for (const entry of elementChildren(root)) {
|
|
110
|
+
if (entry.namespaceURI !== W_NS || entry.localName !== "comment") continue;
|
|
111
|
+
const id = attributeByLocalName(entry, "id");
|
|
112
|
+
if (id !== null && !entries.has(id)) entries.set(id, entry);
|
|
113
|
+
}
|
|
114
|
+
return entries;
|
|
115
|
+
}
|
|
116
|
+
function withThreadKey(commentXml, paraId, arrived) {
|
|
117
|
+
if (arrived === null) return commentXml;
|
|
118
|
+
const target = lastBodyParagraph(arrived);
|
|
119
|
+
if (target === null) return commentXml;
|
|
120
|
+
if (target.getAttributeNS(W14_NS, "paraId") !== null || target.hasAttribute("w14:paraId")) {
|
|
121
|
+
return commentXml;
|
|
122
|
+
}
|
|
123
|
+
const at = namedParagraphs(arrived).indexOf(target);
|
|
124
|
+
const openings = Array.from(commentXml.matchAll(PARAGRAPH_OR_SKIPPED)).filter(
|
|
125
|
+
(match) => !match[0].startsWith("<!")
|
|
126
|
+
);
|
|
127
|
+
const opening = openings[at];
|
|
128
|
+
if (at === -1 || opening === void 0 || opening.index === void 0) {
|
|
129
|
+
return commentXml;
|
|
130
|
+
}
|
|
131
|
+
const selfClosing = opening[0].endsWith("/>");
|
|
132
|
+
const keyed = opening[0].slice(0, selfClosing ? -2 : -1) + ` ${attrsText([[qualify("w14", "paraId"), paraId]])}` + (selfClosing ? "/>" : ">");
|
|
133
|
+
return commentXml.slice(0, opening.index) + keyed + commentXml.slice(opening.index + opening[0].length);
|
|
134
|
+
}
|
|
135
|
+
function readRunText(run) {
|
|
136
|
+
if (!holdsElementsOnly(run)) return null;
|
|
137
|
+
const pieces = [];
|
|
138
|
+
for (const child of Array.from(run.children)) {
|
|
139
|
+
if (isNamed(child, W_NS, "br")) {
|
|
140
|
+
if (!attributesWithin(child, NO_ATTRIBUTES) || child.childNodes.length > 0) {
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
143
|
+
pieces.push("\n");
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
if (!isNamed(child, W_NS, "t")) return null;
|
|
147
|
+
if (!attributesWithin(child, TEXT_ATTRIBUTES) || child.getAttributeNS(XML_NS, "space") !== "preserve" || !holdsTextOnly(child)) {
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
pieces.push(child.textContent ?? "");
|
|
151
|
+
}
|
|
152
|
+
return pieces.join("");
|
|
153
|
+
}
|
|
154
|
+
function wellFormedCommentExtension(entry) {
|
|
155
|
+
return attributesWithin(entry, COMMENT_EX_ATTRIBUTES) && entry.childNodes.length === 0 && threadKeyOrNone(entry, "paraId") && threadKeyOrNone(entry, "paraIdParent") && // The writer says a thread is settled or open, and nothing else `ST_OnOff` would take
|
|
156
|
+
["0", "1", null].includes(attributeByLocalName(entry, "done"));
|
|
157
|
+
}
|
|
158
|
+
function wellFormedPerson(entry) {
|
|
159
|
+
if (!attributesWithin(entry, PERSON_ATTRIBUTES)) return false;
|
|
160
|
+
if (!holdsElementsOnly(entry)) return false;
|
|
161
|
+
const children = Array.from(entry.children);
|
|
162
|
+
if (children.length !== 1) return false;
|
|
163
|
+
const [presence] = children;
|
|
164
|
+
return isNamed(presence, W15_NS, "presenceInfo") && attributesWithin(presence, PRESENCE_ATTRIBUTES) && attributeByLocalName(presence, "providerId") === COMMENT_AUTHOR_PROVIDER && attributeByLocalName(presence, "userId") !== null && presence.childNodes.length === 0;
|
|
165
|
+
}
|
|
166
|
+
function recordedIdentity(person) {
|
|
167
|
+
const [presence] = Array.from(person.children);
|
|
168
|
+
return presence === void 0 ? null : attributeByLocalName(presence, "userId");
|
|
169
|
+
}
|
|
170
|
+
function readStrictCommentBody(comment) {
|
|
171
|
+
if (!holdsElementsOnly(comment)) return null;
|
|
172
|
+
const paragraphs = Array.from(comment.children);
|
|
173
|
+
if (paragraphs.length !== 1) return null;
|
|
174
|
+
const [paragraph] = paragraphs;
|
|
175
|
+
if (!isNamed(paragraph, W_NS, "p")) return null;
|
|
176
|
+
if (!attributesWithin(paragraph, PARAGRAPH_ATTRIBUTES)) return null;
|
|
177
|
+
if (!holdsElementsOnly(paragraph)) return null;
|
|
178
|
+
const runs = Array.from(paragraph.children);
|
|
179
|
+
if (runs.length !== 1) return null;
|
|
180
|
+
const [run] = runs;
|
|
181
|
+
if (!isNamed(run, W_NS, "r")) return null;
|
|
182
|
+
if (!attributesWithin(run, NO_ATTRIBUTES)) return null;
|
|
183
|
+
return readRunText(run);
|
|
184
|
+
}
|
|
185
|
+
function renderCommentExtension(comment) {
|
|
186
|
+
if (comment.extensionXml !== null) return comment.extensionXml;
|
|
187
|
+
const parent = "parentParaId" in comment ? [[qualify("w15", "paraIdParent"), comment.parentParaId]] : [];
|
|
188
|
+
const done = "resolved" in comment ? [[qualify("w15", "done"), comment.resolved ? "1" : "0"]] : [];
|
|
189
|
+
return elementXml(qualify("w15", "commentEx"), [
|
|
190
|
+
[qualify("w15", "paraId"), comment.paraId],
|
|
191
|
+
...parent,
|
|
192
|
+
...done
|
|
193
|
+
]);
|
|
194
|
+
}
|
|
195
|
+
function renderPerson(author, userId, prefix, declaration) {
|
|
196
|
+
const declared = declaration === null ? [] : [declaration];
|
|
197
|
+
return elementXml(
|
|
198
|
+
`${prefix}person`,
|
|
199
|
+
[...declared, [`${prefix}author`, author]],
|
|
200
|
+
[
|
|
201
|
+
elementXml(`${prefix}presenceInfo`, [
|
|
202
|
+
[`${prefix}providerId`, COMMENT_AUTHOR_PROVIDER],
|
|
203
|
+
[`${prefix}userId`, userId]
|
|
204
|
+
])
|
|
205
|
+
]
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
export {
|
|
209
|
+
COMMENT_ATTRIBUTES,
|
|
210
|
+
COMMENT_EX_ATTRIBUTES,
|
|
211
|
+
arrivedEntries,
|
|
212
|
+
attributesWithin,
|
|
213
|
+
declarationWritten,
|
|
214
|
+
lastBodyParagraph,
|
|
215
|
+
readStrictCommentBody,
|
|
216
|
+
recordedIdentity,
|
|
217
|
+
renderCommentBody,
|
|
218
|
+
renderCommentExtension,
|
|
219
|
+
renderPerson,
|
|
220
|
+
wellFormedCommentExtension,
|
|
221
|
+
wellFormedPerson,
|
|
222
|
+
withThreadKey
|
|
223
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
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
|
+
*
|
|
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
|
|
10
|
+
* could have put the entry out, whoever it belongs to. Permission asks whether this author could
|
|
11
|
+
* have made the change. Asking them as one would refuse a moderator rewriting somebody else's
|
|
12
|
+
* comment under `editableComments: "all"`, which is a thing the editor lets them do.
|
|
13
|
+
*/
|
|
14
|
+
import type { EditableComments } from "../../schema/protection";
|
|
15
|
+
import type { StoryPartKind } from "../protectionPolicy";
|
|
16
|
+
import { type ImportedPeople } from "./people";
|
|
17
|
+
/**
|
|
18
|
+
* Whether this editor's writer could have put the entry out, whoever it belongs to.
|
|
19
|
+
*
|
|
20
|
+
* Shape alone: which attributes it carries and what stands inside it. Who may have written it is
|
|
21
|
+
* `entryAllowed`'s question. Each kind is read where it is written (`./grammar`).
|
|
22
|
+
*/
|
|
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;
|
|
33
|
+
/**
|
|
34
|
+
* Whether `authorId` could have written or rewritten this entry.
|
|
35
|
+
*
|
|
36
|
+
* Permission alone: whether the shape is one this editor writes is `wellFormedEntry`'s question.
|
|
37
|
+
* An entry that appeared has to be this author's. One that arrived keeps the identity it arrived
|
|
38
|
+
* with; settling its thread or replying to it belong to everyone and leave what it says alone,
|
|
39
|
+
* while rewriting what it says is its author's, a moderator's, or anyone's where no identity was
|
|
40
|
+
* recorded for it. That last is the rule the editor holds to (`schema/protection`), and the two
|
|
41
|
+
* have to answer alike or a file the editor wrote would be turned down here.
|
|
42
|
+
*/
|
|
43
|
+
export declare function entryAllowed(entry: Element, original: Element | null, authorId: string, editableComments: EditableComments, people: ImportedPeople): boolean;
|
|
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
|
+
];
|