-
Notifications
You must be signed in to change notification settings - Fork 132
Expand file tree
/
Copy pathsetProtectionMode.js
More file actions
85 lines (73 loc) · 2.57 KB
/
setProtectionMode.js
File metadata and controls
85 lines (73 loc) · 2.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
// @ts-check
import { carbonCopy } from '@core/utilities/carbonCopy.js';
const SETTINGS_PATH = 'word/settings.xml';
const DOC_PROTECTION_NODE = 'w:documentProtection';
const PROTECTION_VALUE_MAP = Object.freeze({
noProtection: null,
allowOnlyRevisions: 'trackedChanges',
allowOnlyComments: 'comments',
allowOnlyFormFields: 'forms',
allowOnlyReading: 'readOnly',
});
const DEFAULT_MODE = 'noProtection';
/**
* Normalize the caller provided document protection mode.
* @param {string} mode
* @returns {keyof typeof PROTECTION_VALUE_MAP}
*/
function normalizeMode(mode) {
const normalized = typeof mode === 'string' ? mode.trim() : '';
return /** @type {keyof typeof PROTECTION_VALUE_MAP} */ (normalized || DEFAULT_MODE);
}
/**
* Build the document protection XML node.
* @param {string} editValue
* @returns {Object}
*/
function createDocProtectionNode(editValue) {
return {
type: 'element',
name: DOC_PROTECTION_NODE,
attributes: {
'w:edit': editValue,
'w:enforcement': '1',
},
};
}
/**
* Update the DOCX settings to enforce or remove document protection.
* @param {'noProtection' | 'allowOnlyRevisions' | 'allowOnlyComments' | 'allowOnlyFormFields' | 'allowOnlyReading'} mode
* @returns {import('./types').Command}
*/
export const setProtectionMode = (mode) => {
return ({ editor }) => {
if (!mode || typeof mode !== 'string') return false;
const convertedXml = editor?.converter?.convertedXml;
if (!convertedXml) return false;
const normalizedMode = normalizeMode(mode);
if (!(normalizedMode in PROTECTION_VALUE_MAP)) return false;
const settingsXml = convertedXml[SETTINGS_PATH];
const settingsRoot = settingsXml?.elements?.[0];
if (!settingsRoot) return false;
const updatedSettings = carbonCopy(settingsXml);
const updatedRoot = updatedSettings.elements?.[0];
if (!updatedRoot) return false;
if (!Array.isArray(updatedRoot.elements)) {
updatedRoot.elements = [];
}
const elements = updatedRoot.elements;
const existingIndex = elements.findIndex((node) => node?.name === DOC_PROTECTION_NODE);
if (existingIndex !== -1) {
elements.splice(existingIndex, 1);
}
const mappedValue = PROTECTION_VALUE_MAP[normalizedMode];
if (mappedValue) {
const protectionNode = createDocProtectionNode(mappedValue);
const insertIndex = existingIndex >= 0 ? existingIndex : 0;
elements.splice(insertIndex, 0, protectionNode);
}
convertedXml[SETTINGS_PATH] = updatedSettings;
editor.updateInternalXmlFile(SETTINGS_PATH, updatedSettings);
return true;
};
};