@atlaskit/adf-utils 18.0.2 → 18.0.3
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 +7 -0
- package/dist/cjs/builders/marks/alignment.js +0 -3
- package/dist/cjs/builders/marks/annotation.js +0 -3
- package/dist/cjs/builders/marks/breakout.js +0 -3
- package/dist/cjs/builders/marks/code.js +0 -3
- package/dist/cjs/builders/marks/data-consumer.js +0 -3
- package/dist/cjs/builders/marks/em.js +0 -3
- package/dist/cjs/builders/marks/fragment.js +0 -3
- package/dist/cjs/builders/marks/indentation.js +0 -3
- package/dist/cjs/builders/marks/link.js +0 -3
- package/dist/cjs/builders/marks/strike.js +0 -3
- package/dist/cjs/builders/marks/strong.js +0 -3
- package/dist/cjs/builders/marks/subsup.js +0 -3
- package/dist/cjs/builders/marks/text-color.js +0 -3
- package/dist/cjs/builders/marks/underline.js +0 -3
- package/dist/cjs/builders/nodes/block-card.js +0 -2
- package/dist/cjs/builders/nodes/blockquote.js +0 -3
- package/dist/cjs/builders/nodes/bodied-extension.js +0 -3
- package/dist/cjs/builders/nodes/bullet-list.js +0 -3
- package/dist/cjs/builders/nodes/caption.js +0 -3
- package/dist/cjs/builders/nodes/code-block.js +0 -3
- package/dist/cjs/builders/nodes/date.js +0 -2
- package/dist/cjs/builders/nodes/decision-item.js +0 -3
- package/dist/cjs/builders/nodes/decision-list.js +0 -3
- package/dist/cjs/builders/nodes/doc.js +0 -3
- package/dist/cjs/builders/nodes/embed-card.js +0 -2
- package/dist/cjs/builders/nodes/emoji.js +0 -2
- package/dist/cjs/builders/nodes/expand.js +0 -3
- package/dist/cjs/builders/nodes/extension.js +0 -2
- package/dist/cjs/builders/nodes/hard-break.js +0 -2
- package/dist/cjs/builders/nodes/heading.js +0 -3
- package/dist/cjs/builders/nodes/inline-card.js +0 -2
- package/dist/cjs/builders/nodes/inline-extension.js +0 -2
- package/dist/cjs/builders/nodes/layout-column.js +0 -2
- package/dist/cjs/builders/nodes/layout-section.js +0 -2
- package/dist/cjs/builders/nodes/list-item.js +0 -2
- package/dist/cjs/builders/nodes/media-group.js +0 -3
- package/dist/cjs/builders/nodes/media-inline.js +0 -2
- package/dist/cjs/builders/nodes/media-single.js +0 -2
- package/dist/cjs/builders/nodes/media.js +0 -2
- package/dist/cjs/builders/nodes/mention.js +0 -6
- package/dist/cjs/builders/nodes/nested-expand.js +0 -3
- package/dist/cjs/builders/nodes/ordered-list.js +0 -3
- package/dist/cjs/builders/nodes/panel.js +0 -3
- package/dist/cjs/builders/nodes/paragraph.js +0 -4
- package/dist/cjs/builders/nodes/placeholder.js +0 -2
- package/dist/cjs/builders/nodes/rule.js +0 -2
- package/dist/cjs/builders/nodes/status.js +0 -2
- package/dist/cjs/builders/nodes/table-cell.js +0 -3
- package/dist/cjs/builders/nodes/table-header.js +0 -3
- package/dist/cjs/builders/nodes/table-row.js +0 -2
- package/dist/cjs/builders/nodes/table.js +0 -3
- package/dist/cjs/builders/nodes/task-item.js +0 -3
- package/dist/cjs/builders/nodes/task-list.js +0 -3
- package/dist/cjs/builders/nodes/text.js +0 -2
- package/dist/cjs/builders/utils/apply-mark.js +0 -5
- package/dist/cjs/builders/utils/create-text-nodes.js +0 -3
- package/dist/cjs/builders/utils/is-duplicate-mark.js +0 -3
- package/dist/cjs/builders.js +0 -51
- package/dist/cjs/empty-adf.js +0 -2
- package/dist/cjs/scrub/default-node-replacements.js +0 -11
- package/dist/cjs/scrub/default-value-replacements.js +0 -2
- package/dist/cjs/scrub/hash.js +0 -4
- package/dist/cjs/scrub/scrub-adf.js +2 -25
- package/dist/cjs/scrub/scrub-content.js +7 -37
- package/dist/cjs/scrub.js +0 -2
- package/dist/cjs/transforms/dedupe-marks-transform.js +2 -23
- package/dist/cjs/transforms/helpers.js +0 -3
- package/dist/cjs/transforms/indentation-marks-transform.js +6 -14
- package/dist/cjs/transforms/invalid-media-content-transform.js +3 -22
- package/dist/cjs/transforms/media-link-transform.js +2 -12
- package/dist/cjs/transforms/nodes-missing-content-transform.js +0 -44
- package/dist/cjs/transforms/text-link-code-transform.js +3 -13
- package/dist/cjs/transforms.js +0 -6
- package/dist/cjs/traverse/filter.js +0 -2
- package/dist/cjs/traverse/map.js +0 -2
- package/dist/cjs/traverse/reduce.js +0 -2
- package/dist/cjs/traverse/traverse.js +1 -18
- package/dist/cjs/traverse.js +0 -4
- package/dist/cjs/validator/rules.js +0 -2
- package/dist/cjs/validator/specs/index.js +0 -83
- package/dist/cjs/validator/utils.js +4 -20
- package/dist/cjs/validator/validator.js +67 -218
- package/dist/cjs/validator.js +0 -1
- package/dist/cjs/version.json +1 -1
- package/dist/es2019/builders/utils/apply-mark.js +0 -2
- package/dist/es2019/builders/utils/is-duplicate-mark.js +0 -1
- package/dist/es2019/builders.js +4 -1
- package/dist/es2019/scrub/default-node-replacements.js +2 -7
- package/dist/es2019/scrub/hash.js +0 -2
- package/dist/es2019/scrub/scrub-adf.js +4 -10
- package/dist/es2019/scrub/scrub-content.js +7 -20
- package/dist/es2019/transforms/dedupe-marks-transform.js +4 -16
- package/dist/es2019/transforms/helpers.js +0 -1
- package/dist/es2019/transforms/indentation-marks-transform.js +10 -10
- package/dist/es2019/transforms/invalid-media-content-transform.js +5 -15
- package/dist/es2019/transforms/media-link-transform.js +2 -9
- package/dist/es2019/transforms/nodes-missing-content-transform.js +6 -38
- package/dist/es2019/transforms/text-link-code-transform.js +5 -8
- package/dist/es2019/traverse/traverse.js +5 -13
- package/dist/es2019/validator/utils.js +4 -2
- package/dist/es2019/validator/validator.js +60 -174
- package/dist/es2019/version.json +1 -1
- package/dist/esm/builders/nodes/blockquote.js +0 -1
- package/dist/esm/builders/nodes/bodied-extension.js +0 -1
- package/dist/esm/builders/nodes/bullet-list.js +0 -1
- package/dist/esm/builders/nodes/caption.js +0 -1
- package/dist/esm/builders/nodes/code-block.js +0 -1
- package/dist/esm/builders/nodes/decision-item.js +0 -1
- package/dist/esm/builders/nodes/decision-list.js +0 -1
- package/dist/esm/builders/nodes/doc.js +0 -1
- package/dist/esm/builders/nodes/expand.js +0 -1
- package/dist/esm/builders/nodes/heading.js +0 -1
- package/dist/esm/builders/nodes/media-group.js +0 -1
- package/dist/esm/builders/nodes/mention.js +0 -3
- package/dist/esm/builders/nodes/nested-expand.js +0 -1
- package/dist/esm/builders/nodes/ordered-list.js +0 -1
- package/dist/esm/builders/nodes/panel.js +0 -1
- package/dist/esm/builders/nodes/paragraph.js +0 -1
- package/dist/esm/builders/nodes/table-cell.js +0 -1
- package/dist/esm/builders/nodes/table-header.js +0 -1
- package/dist/esm/builders/nodes/table.js +0 -1
- package/dist/esm/builders/nodes/task-item.js +0 -1
- package/dist/esm/builders/nodes/task-list.js +0 -1
- package/dist/esm/builders/utils/apply-mark.js +0 -2
- package/dist/esm/builders/utils/is-duplicate-mark.js +0 -1
- package/dist/esm/builders.js +4 -1
- package/dist/esm/scrub/default-node-replacements.js +0 -9
- package/dist/esm/scrub/hash.js +0 -2
- package/dist/esm/scrub/scrub-adf.js +2 -17
- package/dist/esm/scrub/scrub-content.js +7 -28
- package/dist/esm/transforms/dedupe-marks-transform.js +2 -18
- package/dist/esm/transforms/helpers.js +0 -1
- package/dist/esm/transforms/indentation-marks-transform.js +6 -11
- package/dist/esm/transforms/invalid-media-content-transform.js +3 -18
- package/dist/esm/transforms/media-link-transform.js +2 -9
- package/dist/esm/transforms/nodes-missing-content-transform.js +0 -38
- package/dist/esm/transforms/text-link-code-transform.js +3 -10
- package/dist/esm/traverse/traverse.js +1 -15
- package/dist/esm/validator/utils.js +4 -2
- package/dist/esm/validator/validator.js +67 -209
- package/dist/esm/version.json +1 -1
- package/package.json +2 -2
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import * as specs from './specs';
|
|
2
2
|
import { copy, isBoolean, isDefined, isInteger, isNumber, isPlainObject, isString, makeArray } from './utils';
|
|
3
3
|
import { validatorFnMap } from './rules';
|
|
4
|
-
|
|
5
4
|
function mapMarksItems(spec, fn = x => x) {
|
|
6
5
|
if (spec.props && spec.props.marks) {
|
|
7
6
|
const {
|
|
8
7
|
items,
|
|
9
8
|
...rest
|
|
10
9
|
} = spec.props.marks;
|
|
11
|
-
return {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
return {
|
|
11
|
+
...spec,
|
|
12
|
+
props: {
|
|
13
|
+
...spec.props,
|
|
14
|
+
marks: {
|
|
15
|
+
...rest,
|
|
15
16
|
/**
|
|
16
17
|
* `Text & MarksObject<Mark-1>` produces `items: ['mark-1']`
|
|
17
18
|
* `Text & MarksObject<Mark-1 | Mark-2>` produces `items: [['mark-1', 'mark-2']]`
|
|
@@ -24,33 +25,31 @@ function mapMarksItems(spec, fn = x => x) {
|
|
|
24
25
|
return spec;
|
|
25
26
|
}
|
|
26
27
|
}
|
|
27
|
-
|
|
28
28
|
const partitionObject = (obj, predicate) => Object.keys(obj).reduce((acc, key) => {
|
|
29
29
|
acc[predicate(key, obj[key], obj) ? 0 : 1].push(key);
|
|
30
30
|
return acc;
|
|
31
31
|
}, [[], []]);
|
|
32
|
+
|
|
32
33
|
/**
|
|
33
34
|
* Normalizes the structure of files imported form './specs'.
|
|
34
35
|
* We denormalised the spec to save bundle size.
|
|
35
36
|
*/
|
|
36
|
-
|
|
37
|
-
|
|
38
37
|
function createSpec(nodes, marks) {
|
|
39
38
|
return Object.keys(specs).reduce((newSpecs, k) => {
|
|
40
|
-
const spec = {
|
|
39
|
+
const spec = {
|
|
40
|
+
...specs[k]
|
|
41
41
|
};
|
|
42
|
-
|
|
43
42
|
if (spec.props) {
|
|
44
|
-
spec.props = {
|
|
43
|
+
spec.props = {
|
|
44
|
+
...spec.props
|
|
45
45
|
};
|
|
46
|
-
|
|
47
46
|
if (spec.props.content) {
|
|
48
47
|
// 'tableCell_content' => { type: 'array', items: [ ... ] }
|
|
49
48
|
if (isString(spec.props.content)) {
|
|
50
49
|
spec.props.content = specs[spec.props.content];
|
|
51
|
-
}
|
|
52
|
-
|
|
50
|
+
}
|
|
53
51
|
|
|
52
|
+
// ['inline', 'emoji']
|
|
54
53
|
if (Array.isArray(spec.props.content)) {
|
|
55
54
|
/**
|
|
56
55
|
* Flatten
|
|
@@ -66,15 +65,20 @@ function createSpec(nodes, marks) {
|
|
|
66
65
|
items: (spec.props.content || []).map(arr => arr.items)
|
|
67
66
|
};
|
|
68
67
|
} else {
|
|
69
|
-
spec.props.content = {
|
|
68
|
+
spec.props.content = {
|
|
69
|
+
...spec.props.content
|
|
70
70
|
};
|
|
71
71
|
}
|
|
72
|
+
spec.props.content.items = spec.props.content.items
|
|
72
73
|
|
|
73
|
-
|
|
74
|
+
// ['inline'] => [['emoji', 'hr', ...]]
|
|
74
75
|
// ['media'] => [['media']]
|
|
75
|
-
.map(item => isString(item) ? Array.isArray(specs[item]) ? specs[item] : [item] : item)
|
|
76
|
-
|
|
77
|
-
|
|
76
|
+
.map(item => isString(item) ? Array.isArray(specs[item]) ? specs[item] : [item] : item)
|
|
77
|
+
// [['emoji', 'hr', 'inline_code']] => [['emoji', 'hr', ['text', { marks: {} }]]]
|
|
78
|
+
.map(item => item.map(subItem => Array.isArray(specs[subItem]) ? specs[subItem] : isString(subItem) ? subItem :
|
|
79
|
+
// Now `NoMark` produces `items: []`, should be fixed in generator
|
|
80
|
+
['text', subItem])
|
|
81
|
+
// Remove unsupported nodes & marks
|
|
78
82
|
// Filter nodes
|
|
79
83
|
.filter(subItem => {
|
|
80
84
|
if (nodes) {
|
|
@@ -82,21 +86,17 @@ function createSpec(nodes, marks) {
|
|
|
82
86
|
// ['mediaSingle', { props: { content: { items: [ 'media', 'caption' ] } }}]
|
|
83
87
|
if (Array.isArray(subItem)) {
|
|
84
88
|
var _subItem$, _subItem$$props, _subItem$$props$conte;
|
|
85
|
-
|
|
86
89
|
const isMainNodeSupported = nodes.indexOf(subItem[0]) > -1;
|
|
87
|
-
|
|
88
90
|
if (isMainNodeSupported && (_subItem$ = subItem[1]) !== null && _subItem$ !== void 0 && (_subItem$$props = _subItem$.props) !== null && _subItem$$props !== void 0 && (_subItem$$props$conte = _subItem$$props.content) !== null && _subItem$$props$conte !== void 0 && _subItem$$props$conte.items) {
|
|
89
91
|
return subItem[1].props.content.items.every(item => nodes.indexOf(item) > -1);
|
|
90
92
|
}
|
|
91
|
-
|
|
92
93
|
return isMainNodeSupported;
|
|
93
94
|
}
|
|
94
|
-
|
|
95
95
|
return nodes.indexOf(subItem) > -1;
|
|
96
96
|
}
|
|
97
|
-
|
|
98
97
|
return true;
|
|
99
|
-
})
|
|
98
|
+
})
|
|
99
|
+
// Filter marks
|
|
100
100
|
.map(subItem => Array.isArray(subItem) && marks ?
|
|
101
101
|
/**
|
|
102
102
|
* TODO: Probably try something like immer, but it's 3.3kb gzipped.
|
|
@@ -105,83 +105,62 @@ function createSpec(nodes, marks) {
|
|
|
105
105
|
[subItem[0], mapMarksItems(subItem[1])] : subItem));
|
|
106
106
|
}
|
|
107
107
|
}
|
|
108
|
-
|
|
109
108
|
newSpecs[k] = spec;
|
|
110
109
|
return newSpecs;
|
|
111
110
|
}, {});
|
|
112
111
|
}
|
|
113
|
-
|
|
114
112
|
function getOptionsForType(type, list) {
|
|
115
113
|
if (!list) {
|
|
116
114
|
return {};
|
|
117
115
|
}
|
|
118
|
-
|
|
119
116
|
for (let i = 0, len = list.length; i < len; i++) {
|
|
120
117
|
const spec = list[i];
|
|
121
118
|
let name = spec;
|
|
122
119
|
let options = {};
|
|
123
|
-
|
|
124
120
|
if (Array.isArray(spec)) {
|
|
125
121
|
[name, options] = spec;
|
|
126
122
|
}
|
|
127
|
-
|
|
128
123
|
if (name === type) {
|
|
129
124
|
return options;
|
|
130
125
|
}
|
|
131
126
|
}
|
|
132
|
-
|
|
133
127
|
return false;
|
|
134
128
|
}
|
|
135
|
-
|
|
136
129
|
export function validateAttrs(spec, value) {
|
|
137
130
|
// extension_node parameters has no type
|
|
138
131
|
if (!isDefined(spec.type)) {
|
|
139
132
|
return !!spec.optional;
|
|
140
133
|
}
|
|
141
|
-
|
|
142
134
|
if (!isDefined(value)) {
|
|
143
135
|
return !!spec.optional;
|
|
144
136
|
}
|
|
145
|
-
|
|
146
137
|
switch (spec.type) {
|
|
147
138
|
case 'boolean':
|
|
148
139
|
return isBoolean(value);
|
|
149
|
-
|
|
150
140
|
case 'number':
|
|
151
141
|
return isNumber(value) && (isDefined(spec.minimum) ? spec.minimum <= value : true) && (isDefined(spec.maximum) ? spec.maximum >= value : true);
|
|
152
|
-
|
|
153
142
|
case 'integer':
|
|
154
143
|
return isInteger(value) && (isDefined(spec.minimum) ? spec.minimum <= value : true) && (isDefined(spec.maximum) ? spec.maximum >= value : true);
|
|
155
|
-
|
|
156
144
|
case 'string':
|
|
157
145
|
const validatorFnPassed = rule => typeof value === 'string' && isDefined(validatorFnMap[rule]) && validatorFnMap[rule](value);
|
|
158
|
-
|
|
159
146
|
return isString(value) && (isDefined(spec.minLength) ? spec.minLength <= value.length : true) && (isDefined(spec.validatorFn) ? validatorFnPassed(spec.validatorFn) : true) && (spec.pattern ? new RegExp(spec.pattern).test(value) : true);
|
|
160
|
-
|
|
161
147
|
case 'object':
|
|
162
148
|
return isPlainObject(value);
|
|
163
|
-
|
|
164
149
|
case 'array':
|
|
165
150
|
const types = spec.items;
|
|
166
151
|
const lastTypeIndex = types.length - 1;
|
|
167
|
-
|
|
168
152
|
if (Array.isArray(value)) {
|
|
169
153
|
// We are doing this to support tuple which can be defined as [number, string]
|
|
170
154
|
// NOTE: Not validating tuples strictly
|
|
171
155
|
return value.every((x, i) => validateAttrs(types[Math.min(i, lastTypeIndex)], x));
|
|
172
156
|
}
|
|
173
|
-
|
|
174
157
|
return false;
|
|
175
|
-
|
|
176
158
|
case 'enum':
|
|
177
159
|
return isString(value) && spec.values.indexOf(value) > -1;
|
|
178
160
|
}
|
|
179
|
-
|
|
180
161
|
return false;
|
|
181
162
|
}
|
|
182
|
-
|
|
183
163
|
const errorMessageFor = (type, message) => `${type}: ${message}.`;
|
|
184
|
-
|
|
185
164
|
const getUnsupportedOptions = spec => {
|
|
186
165
|
if (spec && spec.props && spec.props.content) {
|
|
187
166
|
const {
|
|
@@ -193,31 +172,28 @@ const getUnsupportedOptions = spec => {
|
|
|
193
172
|
allowUnsupportedInline
|
|
194
173
|
};
|
|
195
174
|
}
|
|
196
|
-
|
|
197
175
|
return {};
|
|
198
176
|
};
|
|
199
|
-
|
|
200
177
|
const invalidChildContent = (child, errorCallback, parentSpec) => {
|
|
201
178
|
const message = errorMessageFor(child.type, 'invalid content');
|
|
202
|
-
|
|
203
179
|
if (!errorCallback) {
|
|
204
180
|
throw new Error(message);
|
|
205
181
|
} else {
|
|
206
|
-
return errorCallback({
|
|
182
|
+
return errorCallback({
|
|
183
|
+
...child
|
|
207
184
|
}, {
|
|
208
185
|
code: 'INVALID_CONTENT',
|
|
209
186
|
message
|
|
210
187
|
}, getUnsupportedOptions(parentSpec));
|
|
211
188
|
}
|
|
212
189
|
};
|
|
213
|
-
|
|
214
190
|
const unsupportedMarkContent = (errorCode, mark, errorCallback, errorMessage) => {
|
|
215
191
|
const message = errorMessage || errorMessageFor(mark.type, 'unsupported mark');
|
|
216
|
-
|
|
217
192
|
if (!errorCallback) {
|
|
218
193
|
throw new Error(message);
|
|
219
194
|
} else {
|
|
220
|
-
return errorCallback({
|
|
195
|
+
return errorCallback({
|
|
196
|
+
...mark
|
|
221
197
|
}, {
|
|
222
198
|
code: errorCode,
|
|
223
199
|
message,
|
|
@@ -229,7 +205,6 @@ const unsupportedMarkContent = (errorCode, mark, errorCallback, errorMessage) =>
|
|
|
229
205
|
});
|
|
230
206
|
}
|
|
231
207
|
};
|
|
232
|
-
|
|
233
208
|
const unsupportedNodeAttributesContent = (entity, errorCode, invalidAttributes, message, errorCallback) => {
|
|
234
209
|
if (!errorCallback) {
|
|
235
210
|
throw new Error(message);
|
|
@@ -248,14 +223,12 @@ const unsupportedNodeAttributesContent = (entity, errorCode, invalidAttributes,
|
|
|
248
223
|
});
|
|
249
224
|
}
|
|
250
225
|
};
|
|
251
|
-
|
|
252
226
|
export function validator(nodes, marks, options) {
|
|
253
227
|
const validatorSpecs = createSpec(nodes, marks);
|
|
254
228
|
const {
|
|
255
229
|
mode = 'strict',
|
|
256
230
|
allowPrivateAttributes = false
|
|
257
231
|
} = options || {};
|
|
258
|
-
|
|
259
232
|
const validate = (entity, errorCallback, allowed, parentSpec) => {
|
|
260
233
|
const validationResult = validateNode(entity, errorCallback, allowed, parentSpec);
|
|
261
234
|
return {
|
|
@@ -263,17 +236,15 @@ export function validator(nodes, marks, options) {
|
|
|
263
236
|
valid: validationResult.valid
|
|
264
237
|
};
|
|
265
238
|
};
|
|
266
|
-
|
|
267
239
|
const validateNode = (entity, errorCallback, allowed, parentSpec, isMark = false) => {
|
|
268
240
|
const {
|
|
269
241
|
type
|
|
270
242
|
} = entity;
|
|
271
|
-
let newEntity = {
|
|
243
|
+
let newEntity = {
|
|
244
|
+
...entity
|
|
272
245
|
};
|
|
273
|
-
|
|
274
246
|
const err = (code, msg, meta) => {
|
|
275
247
|
const message = errorMessageFor(type, msg);
|
|
276
|
-
|
|
277
248
|
if (errorCallback) {
|
|
278
249
|
return {
|
|
279
250
|
valid: false,
|
|
@@ -287,42 +258,32 @@ export function validator(nodes, marks, options) {
|
|
|
287
258
|
throw new Error(message);
|
|
288
259
|
}
|
|
289
260
|
};
|
|
290
|
-
|
|
291
261
|
if (type) {
|
|
292
262
|
const typeOptions = getOptionsForType(type, allowed);
|
|
293
|
-
|
|
294
263
|
if (typeOptions === false) {
|
|
295
264
|
return isMark ? {
|
|
296
265
|
valid: false
|
|
297
266
|
} : err('INVALID_TYPE', 'type not allowed here');
|
|
298
267
|
}
|
|
299
|
-
|
|
300
268
|
const spec = validatorSpecs[type];
|
|
301
|
-
|
|
302
269
|
if (!spec) {
|
|
303
270
|
return err('INVALID_TYPE', `${type}: No validation spec found for type!`);
|
|
304
271
|
}
|
|
305
|
-
|
|
306
272
|
const specBasedValidationResult = specBasedValidationFor(spec, typeOptions, entity, err, newEntity, type, errorCallback, isMark);
|
|
307
|
-
|
|
308
273
|
if (specBasedValidationResult.hasValidated && specBasedValidationResult.result) {
|
|
309
274
|
return specBasedValidationResult.result;
|
|
310
275
|
}
|
|
311
276
|
} else {
|
|
312
277
|
return err('INVALID_TYPE', 'ProseMirror Node/Mark should contain a `type`');
|
|
313
278
|
}
|
|
314
|
-
|
|
315
279
|
return {
|
|
316
280
|
valid: true,
|
|
317
281
|
entity: newEntity
|
|
318
282
|
};
|
|
319
283
|
};
|
|
320
|
-
|
|
321
284
|
return validate;
|
|
322
|
-
|
|
323
285
|
function marksValidationFor(validator, entity, errorCallback, newEntity, err) {
|
|
324
286
|
let validationResult;
|
|
325
|
-
|
|
326
287
|
if (validator.props && validator.props.marks) {
|
|
327
288
|
const marksSet = allowedMarksFor(validator);
|
|
328
289
|
const marksValidationResult = marksAfterValidation(entity, errorCallback, marksSet, validator);
|
|
@@ -334,37 +295,35 @@ export function validator(nodes, marks, options) {
|
|
|
334
295
|
} else {
|
|
335
296
|
validationResult = marksForEntitySpecNotSupportingMarks(entity, newEntity, errorCallback, err);
|
|
336
297
|
}
|
|
337
|
-
|
|
338
298
|
return validationResult;
|
|
339
299
|
}
|
|
340
|
-
|
|
341
300
|
function validatorFor(spec, typeOptions) {
|
|
342
|
-
return {
|
|
301
|
+
return {
|
|
302
|
+
...spec,
|
|
343
303
|
...typeOptions,
|
|
344
304
|
// options with props can override props of spec
|
|
345
305
|
...(spec.props ? {
|
|
346
|
-
props: {
|
|
306
|
+
props: {
|
|
307
|
+
...spec.props,
|
|
347
308
|
...(typeOptions['props'] || {})
|
|
348
309
|
}
|
|
349
310
|
} : {})
|
|
350
311
|
};
|
|
351
312
|
}
|
|
352
|
-
|
|
353
313
|
function marksAfterValidation(entity, errorCallback, marksSet, validator) {
|
|
354
314
|
return entity.marks ? entity.marks.map(mark => {
|
|
355
315
|
const isAKnownMark = marks ? marks.indexOf(mark.type) > -1 : true;
|
|
356
|
-
|
|
357
316
|
if (mode === 'strict' && isAKnownMark) {
|
|
358
317
|
const finalResult = validateNode(mark, errorCallback, marksSet, validator, true);
|
|
359
318
|
const finalMark = finalResult.entity;
|
|
360
|
-
|
|
361
319
|
if (finalMark) {
|
|
362
320
|
return {
|
|
363
321
|
valid: true,
|
|
364
322
|
originalMark: mark,
|
|
365
323
|
newMark: finalMark
|
|
366
324
|
};
|
|
367
|
-
}
|
|
325
|
+
}
|
|
326
|
+
// this checks for mark level attribute errors
|
|
368
327
|
// and propagates error code and message
|
|
369
328
|
else if (finalResult.marksValidationOutput && finalResult.marksValidationOutput.length) {
|
|
370
329
|
return {
|
|
@@ -389,7 +348,6 @@ export function validator(nodes, marks, options) {
|
|
|
389
348
|
}
|
|
390
349
|
}) : [];
|
|
391
350
|
}
|
|
392
|
-
|
|
393
351
|
function allowedMarksFor(validator) {
|
|
394
352
|
const {
|
|
395
353
|
items
|
|
@@ -397,20 +355,16 @@ export function validator(nodes, marks, options) {
|
|
|
397
355
|
const marksSet = items.length ? Array.isArray(items[0]) ? items[0] : items : [];
|
|
398
356
|
return marksSet;
|
|
399
357
|
}
|
|
400
|
-
|
|
401
358
|
function marksForEntitySpecNotSupportingMarks(prevEntity, newEntity, errorCallback, err) {
|
|
402
359
|
const errorCode = 'REDUNDANT_MARKS';
|
|
403
360
|
const currentMarks = prevEntity.marks || [];
|
|
404
361
|
const newMarks = currentMarks.map(mark => {
|
|
405
362
|
const isUnsupportedNodeAttributeMark = mark.type === 'unsupportedNodeAttribute';
|
|
406
|
-
|
|
407
363
|
if (isUnsupportedNodeAttributeMark) {
|
|
408
364
|
return mark;
|
|
409
365
|
}
|
|
410
|
-
|
|
411
366
|
return unsupportedMarkContent(errorCode, mark, errorCallback);
|
|
412
367
|
});
|
|
413
|
-
|
|
414
368
|
if (newMarks.length) {
|
|
415
369
|
newEntity.marks = newMarks;
|
|
416
370
|
return {
|
|
@@ -423,50 +377,41 @@ export function validator(nodes, marks, options) {
|
|
|
423
377
|
});
|
|
424
378
|
}
|
|
425
379
|
}
|
|
426
|
-
|
|
427
380
|
function requiredPropertyValidationFor(validatorSpec, prevEntity, err) {
|
|
428
381
|
let result = {
|
|
429
382
|
valid: true,
|
|
430
383
|
entity: prevEntity
|
|
431
384
|
};
|
|
432
|
-
|
|
433
385
|
if (validatorSpec.required) {
|
|
434
386
|
if (!validatorSpec.required.every(prop => isDefined(prevEntity[prop]))) {
|
|
435
387
|
result = err('MISSING_PROPERTIES', 'required prop missing');
|
|
436
388
|
}
|
|
437
389
|
}
|
|
438
|
-
|
|
439
390
|
return result;
|
|
440
391
|
}
|
|
441
|
-
|
|
442
392
|
function textPropertyValidationFor(validatorSpec, prevEntity, err) {
|
|
443
393
|
let result = {
|
|
444
394
|
valid: true,
|
|
445
395
|
entity: prevEntity
|
|
446
396
|
};
|
|
447
|
-
|
|
448
397
|
if (validatorSpec.props.text) {
|
|
449
398
|
if (isDefined(prevEntity.text) && !validateAttrs(validatorSpec.props.text, prevEntity.text)) {
|
|
450
399
|
result = err('INVALID_TEXT', `'text' validation failed`);
|
|
451
400
|
}
|
|
452
401
|
}
|
|
453
|
-
|
|
454
402
|
return result;
|
|
455
403
|
}
|
|
456
|
-
|
|
457
404
|
function contentLengthValidationFor(validatorSpec, prevEntity, err) {
|
|
458
405
|
let result = {
|
|
459
406
|
valid: true,
|
|
460
407
|
entity: prevEntity
|
|
461
408
|
};
|
|
462
|
-
|
|
463
409
|
if (validatorSpec.props.content && prevEntity.content) {
|
|
464
410
|
const {
|
|
465
411
|
minItems,
|
|
466
412
|
maxItems
|
|
467
413
|
} = validatorSpec.props.content;
|
|
468
414
|
const length = prevEntity.content.length;
|
|
469
|
-
|
|
470
415
|
if (isDefined(minItems) && minItems > length) {
|
|
471
416
|
result = err('INVALID_CONTENT_LENGTH', `'content' should have more than ${minItems} child`, {
|
|
472
417
|
length,
|
|
@@ -481,14 +426,11 @@ export function validator(nodes, marks, options) {
|
|
|
481
426
|
});
|
|
482
427
|
}
|
|
483
428
|
}
|
|
484
|
-
|
|
485
429
|
return result;
|
|
486
430
|
}
|
|
487
|
-
|
|
488
431
|
function invalidAttributesFor(validatorSpec, prevEntity) {
|
|
489
432
|
let invalidAttrs = [];
|
|
490
433
|
let validatorAttrs = {};
|
|
491
|
-
|
|
492
434
|
if (validatorSpec.props && validatorSpec.props.attrs) {
|
|
493
435
|
const attrOptions = makeArray(validatorSpec.props.attrs);
|
|
494
436
|
/**
|
|
@@ -496,64 +438,51 @@ export function validator(nodes, marks, options) {
|
|
|
496
438
|
* attrs: [{ props: { url: { type: 'string' } } }, { props: { data: {} } }],
|
|
497
439
|
* Gotcha: It will always report the last failure.
|
|
498
440
|
*/
|
|
499
|
-
|
|
500
441
|
for (let i = 0, length = attrOptions.length; i < length; ++i) {
|
|
501
442
|
const attrOption = attrOptions[i];
|
|
502
|
-
|
|
503
443
|
if (attrOption && attrOption.props) {
|
|
504
444
|
[, invalidAttrs] = partitionObject(attrOption.props, (k, v) => {
|
|
505
445
|
return validateAttrs(v, prevEntity.attrs[k]);
|
|
506
446
|
});
|
|
507
447
|
}
|
|
508
|
-
|
|
509
448
|
validatorAttrs = attrOption;
|
|
510
|
-
|
|
511
449
|
if (!invalidAttrs.length) {
|
|
512
450
|
break;
|
|
513
451
|
}
|
|
514
452
|
}
|
|
515
453
|
}
|
|
516
|
-
|
|
517
454
|
return {
|
|
518
455
|
invalidAttrs,
|
|
519
456
|
validatorAttrs
|
|
520
457
|
};
|
|
521
458
|
}
|
|
522
|
-
|
|
523
459
|
function attributesValidationFor(validatorSpec, prevEntity, newEntity, isMark, errorCallback) {
|
|
524
460
|
const validatorSpecAllowsAttributes = validatorSpec.props && validatorSpec.props.attrs;
|
|
525
|
-
|
|
526
461
|
if (prevEntity.attrs) {
|
|
527
462
|
if (!validatorSpecAllowsAttributes) {
|
|
528
463
|
if (isMark) {
|
|
529
464
|
return handleNoAttibutesAllowedInSpecForMark(prevEntity, prevEntity.attrs);
|
|
530
465
|
}
|
|
531
|
-
|
|
532
466
|
const attrs = Object.keys(prevEntity.attrs);
|
|
533
467
|
return handleUnsupportedNodeAttributes(prevEntity, newEntity, [], attrs, errorCallback);
|
|
534
468
|
}
|
|
535
|
-
|
|
536
469
|
const {
|
|
537
470
|
hasUnsupportedAttrs,
|
|
538
471
|
redundantAttrs,
|
|
539
472
|
invalidAttrs
|
|
540
473
|
} = validateAttributes(validatorSpec, prevEntity, prevEntity.attrs);
|
|
541
|
-
|
|
542
474
|
if (hasUnsupportedAttrs) {
|
|
543
475
|
if (isMark) {
|
|
544
476
|
return handleUnsupportedMarkAttributes(prevEntity, invalidAttrs, redundantAttrs);
|
|
545
477
|
}
|
|
546
|
-
|
|
547
478
|
return handleUnsupportedNodeAttributes(prevEntity, newEntity, invalidAttrs, redundantAttrs, errorCallback);
|
|
548
479
|
}
|
|
549
480
|
}
|
|
550
|
-
|
|
551
481
|
return {
|
|
552
482
|
valid: true,
|
|
553
483
|
entity: prevEntity
|
|
554
484
|
};
|
|
555
485
|
}
|
|
556
|
-
|
|
557
486
|
function validateAttributes(validatorSpec, prevEntity, attributes) {
|
|
558
487
|
const invalidAttributesResult = invalidAttributesFor(validatorSpec, prevEntity);
|
|
559
488
|
const {
|
|
@@ -570,7 +499,6 @@ export function validator(nodes, marks, options) {
|
|
|
570
499
|
redundantAttrs
|
|
571
500
|
};
|
|
572
501
|
}
|
|
573
|
-
|
|
574
502
|
function handleUnsupportedNodeAttributes(prevEntity, newEntity, invalidAttrs, redundantAttrs, errorCallback) {
|
|
575
503
|
const attr = invalidAttrs.concat(redundantAttrs);
|
|
576
504
|
let result = {
|
|
@@ -586,18 +514,15 @@ export function validator(nodes, marks, options) {
|
|
|
586
514
|
};
|
|
587
515
|
return result;
|
|
588
516
|
}
|
|
589
|
-
|
|
590
517
|
function handleUnsupportedMarkAttributes(prevEntity, invalidAttrs, redundantAttrs) {
|
|
591
518
|
let errorCode = 'INVALID_ATTRIBUTES';
|
|
592
519
|
let message = errorMessageFor(prevEntity.type, `'attrs' validation failed`);
|
|
593
520
|
const hasRedundantAttrs = redundantAttrs.length;
|
|
594
521
|
const hasBothInvalidAndRedundantAttrs = hasRedundantAttrs && invalidAttrs.length;
|
|
595
|
-
|
|
596
522
|
if (!hasBothInvalidAndRedundantAttrs && hasRedundantAttrs) {
|
|
597
523
|
errorCode = 'REDUNDANT_ATTRIBUTES';
|
|
598
524
|
message = errorMessageFor('redundant attributes found', redundantAttrs.join(', '));
|
|
599
525
|
}
|
|
600
|
-
|
|
601
526
|
const markValidationResult = {
|
|
602
527
|
valid: true,
|
|
603
528
|
originalMark: prevEntity,
|
|
@@ -609,7 +534,6 @@ export function validator(nodes, marks, options) {
|
|
|
609
534
|
marksValidationOutput: [markValidationResult]
|
|
610
535
|
};
|
|
611
536
|
}
|
|
612
|
-
|
|
613
537
|
function handleNoAttibutesAllowedInSpecForMark(prevEntity, attributes) {
|
|
614
538
|
const message = errorMessageFor('redundant attributes found', Object.keys(attributes).join(', '));
|
|
615
539
|
const errorCode = 'REDUNDANT_ATTRIBUTES';
|
|
@@ -624,22 +548,18 @@ export function validator(nodes, marks, options) {
|
|
|
624
548
|
marksValidationOutput: [markValidationResult]
|
|
625
549
|
};
|
|
626
550
|
}
|
|
627
|
-
|
|
628
551
|
function wrapUnSupportedNodeAttributes(prevEntity, newEntity, invalidAttrs, errorCode, message, errorCallback) {
|
|
629
552
|
let invalidValues = {};
|
|
630
|
-
|
|
631
553
|
for (let invalidAttr in invalidAttrs) {
|
|
632
554
|
invalidValues[invalidAttrs[invalidAttr]] = prevEntity.attrs && prevEntity.attrs[invalidAttrs[invalidAttr]];
|
|
633
|
-
|
|
634
555
|
if (newEntity.attrs) {
|
|
635
556
|
delete newEntity.attrs[invalidAttrs[invalidAttr]];
|
|
636
557
|
}
|
|
637
558
|
}
|
|
638
|
-
|
|
639
559
|
const unsupportedNodeAttributeValues = unsupportedNodeAttributesContent(prevEntity, errorCode, invalidValues, message, errorCallback);
|
|
640
|
-
const finalEntity = {
|
|
560
|
+
const finalEntity = {
|
|
561
|
+
...newEntity
|
|
641
562
|
};
|
|
642
|
-
|
|
643
563
|
if (finalEntity.marks) {
|
|
644
564
|
unsupportedNodeAttributeValues && finalEntity.marks.push(unsupportedNodeAttributeValues);
|
|
645
565
|
return finalEntity.marks;
|
|
@@ -647,14 +567,12 @@ export function validator(nodes, marks, options) {
|
|
|
647
567
|
return [unsupportedNodeAttributeValues];
|
|
648
568
|
}
|
|
649
569
|
}
|
|
650
|
-
|
|
651
570
|
function extraPropsValidationFor(validatorSpec, prevEntity, err, newEntity, type) {
|
|
652
571
|
let result = {
|
|
653
572
|
valid: true,
|
|
654
573
|
entity: prevEntity
|
|
655
574
|
};
|
|
656
575
|
const [requiredProps, redundantProps] = partitionObject(prevEntity, k => isDefined(validatorSpec.props[k]));
|
|
657
|
-
|
|
658
576
|
if (redundantProps.length) {
|
|
659
577
|
if (mode === 'loose') {
|
|
660
578
|
newEntity = {
|
|
@@ -669,34 +587,29 @@ export function validator(nodes, marks, options) {
|
|
|
669
587
|
}
|
|
670
588
|
}
|
|
671
589
|
}
|
|
672
|
-
|
|
673
590
|
return result;
|
|
674
591
|
}
|
|
675
|
-
|
|
676
592
|
function specBasedValidationFor(spec, typeOptions, prevEntity, err, newEntity, type, errorCallback, isMark) {
|
|
677
593
|
let specBasedValidationResult = {
|
|
678
594
|
hasValidated: false
|
|
679
595
|
};
|
|
680
596
|
const validatorSpec = validatorFor(spec, typeOptions);
|
|
681
|
-
|
|
682
597
|
if (!validatorSpec) {
|
|
683
598
|
return specBasedValidationResult;
|
|
684
|
-
}
|
|
685
|
-
// For array format where `required` is an array
|
|
686
|
-
|
|
599
|
+
}
|
|
687
600
|
|
|
601
|
+
// Required Props
|
|
602
|
+
// For array format where `required` is an array
|
|
688
603
|
const requiredPropertyValidatonResult = requiredPropertyValidationFor(validatorSpec, prevEntity, err);
|
|
689
|
-
|
|
690
604
|
if (!requiredPropertyValidatonResult.valid) {
|
|
691
605
|
return {
|
|
692
606
|
hasValidated: true,
|
|
693
607
|
result: requiredPropertyValidatonResult
|
|
694
608
|
};
|
|
695
609
|
}
|
|
696
|
-
|
|
697
610
|
if (!validatorSpec.props) {
|
|
698
|
-
const props = Object.keys(prevEntity);
|
|
699
|
-
|
|
611
|
+
const props = Object.keys(prevEntity);
|
|
612
|
+
// If there's no validator.props then there shouldn't be any key except `type`
|
|
700
613
|
if (props.length > 1) {
|
|
701
614
|
return {
|
|
702
615
|
hasValidated: true,
|
|
@@ -705,34 +618,29 @@ export function validator(nodes, marks, options) {
|
|
|
705
618
|
})
|
|
706
619
|
};
|
|
707
620
|
}
|
|
708
|
-
|
|
709
621
|
return specBasedValidationResult;
|
|
710
|
-
}
|
|
711
|
-
|
|
622
|
+
}
|
|
712
623
|
|
|
624
|
+
// Check text
|
|
713
625
|
const textPropertyValidationResult = textPropertyValidationFor(validatorSpec, prevEntity, err);
|
|
714
|
-
|
|
715
626
|
if (!textPropertyValidationResult.valid) {
|
|
716
627
|
return {
|
|
717
628
|
hasValidated: true,
|
|
718
629
|
result: textPropertyValidationResult
|
|
719
630
|
};
|
|
720
|
-
}
|
|
721
|
-
|
|
722
|
-
|
|
631
|
+
}
|
|
632
|
+
// Content Length
|
|
723
633
|
const contentLengthValidationResult = contentLengthValidationFor(validatorSpec, prevEntity, err);
|
|
724
|
-
|
|
725
634
|
if (!contentLengthValidationResult.valid) {
|
|
726
635
|
return {
|
|
727
636
|
hasValidated: true,
|
|
728
637
|
result: contentLengthValidationResult
|
|
729
638
|
};
|
|
730
|
-
}
|
|
731
|
-
// For object format based on `optional` property
|
|
732
|
-
|
|
639
|
+
}
|
|
733
640
|
|
|
641
|
+
// Required Props
|
|
642
|
+
// For object format based on `optional` property
|
|
734
643
|
const [, missingProps] = partitionObject(validatorSpec.props, (k, v) => v.optional || isDefined(prevEntity[k]));
|
|
735
|
-
|
|
736
644
|
if (missingProps.length) {
|
|
737
645
|
return {
|
|
738
646
|
hasValidated: true,
|
|
@@ -741,45 +649,37 @@ export function validator(nodes, marks, options) {
|
|
|
741
649
|
})
|
|
742
650
|
};
|
|
743
651
|
}
|
|
744
|
-
|
|
745
652
|
const attributesValidationResult = attributesValidationFor(validatorSpec, prevEntity, newEntity, isMark, errorCallback);
|
|
746
|
-
|
|
747
653
|
if (!attributesValidationResult.valid) {
|
|
748
654
|
return {
|
|
749
655
|
hasValidated: true,
|
|
750
656
|
result: attributesValidationResult
|
|
751
657
|
};
|
|
752
658
|
}
|
|
753
|
-
|
|
754
659
|
if (isMark && attributesValidationResult.valid) {
|
|
755
660
|
return {
|
|
756
661
|
hasValidated: true,
|
|
757
662
|
result: attributesValidationResult
|
|
758
663
|
};
|
|
759
664
|
}
|
|
760
|
-
|
|
761
665
|
const extraPropsValidationResult = extraPropsValidationFor(validatorSpec, prevEntity, err, newEntity, type);
|
|
762
|
-
|
|
763
666
|
if (!extraPropsValidationResult.valid) {
|
|
764
667
|
return {
|
|
765
668
|
hasValidated: true,
|
|
766
669
|
result: extraPropsValidationResult
|
|
767
670
|
};
|
|
768
|
-
}
|
|
769
|
-
|
|
671
|
+
}
|
|
770
672
|
|
|
673
|
+
// Children
|
|
771
674
|
if (validatorSpec.props.content) {
|
|
772
675
|
const contentValidatorSpec = validatorSpec.props.content;
|
|
773
|
-
|
|
774
676
|
if (prevEntity.content) {
|
|
775
677
|
const validateChildNode = (child, index) => {
|
|
776
678
|
if (child === undefined) {
|
|
777
679
|
return child;
|
|
778
680
|
}
|
|
779
|
-
|
|
780
681
|
const validateChildMarks = (childEntity, marksValidationOutput, errorCallback, isLastValidationSpec, isParentTupleLike = false) => {
|
|
781
682
|
let marksAreValid = true;
|
|
782
|
-
|
|
783
683
|
if (childEntity && childEntity.marks && marksValidationOutput) {
|
|
784
684
|
const validMarks = marksValidationOutput.filter(mark => mark.valid);
|
|
785
685
|
const finalMarks = marksValidationOutput.map(mr => {
|
|
@@ -789,11 +689,9 @@ export function validator(nodes, marks, options) {
|
|
|
789
689
|
if (validMarks.length || isLastValidationSpec || isParentTupleLike || mr.errorCode === 'INVALID_TYPE' || mr.errorCode === 'INVALID_CONTENT' || mr.errorCode === 'REDUNDANT_ATTRIBUTES' || mr.errorCode === 'INVALID_ATTRIBUTES') {
|
|
790
690
|
return unsupportedMarkContent(mr.errorCode, mr.originalMark, errorCallback, mr.message);
|
|
791
691
|
}
|
|
792
|
-
|
|
793
692
|
return;
|
|
794
693
|
}
|
|
795
694
|
}).filter(Boolean);
|
|
796
|
-
|
|
797
695
|
if (finalMarks.length) {
|
|
798
696
|
childEntity.marks = finalMarks;
|
|
799
697
|
} else {
|
|
@@ -801,15 +699,12 @@ export function validator(nodes, marks, options) {
|
|
|
801
699
|
marksAreValid = false;
|
|
802
700
|
}
|
|
803
701
|
}
|
|
804
|
-
|
|
805
702
|
return {
|
|
806
703
|
valid: marksAreValid,
|
|
807
704
|
entity: childEntity
|
|
808
705
|
};
|
|
809
706
|
};
|
|
810
|
-
|
|
811
707
|
const hasMultipleCombinationOfContentAllowed = !!contentValidatorSpec.isTupleLike;
|
|
812
|
-
|
|
813
708
|
if (hasMultipleCombinationOfContentAllowed) {
|
|
814
709
|
const {
|
|
815
710
|
entity: newChildEntity,
|
|
@@ -819,33 +714,29 @@ export function validator(nodes, marks, options) {
|
|
|
819
714
|
entity
|
|
820
715
|
} = validateChildMarks(newChildEntity, marksValidationOutput, errorCallback, false, true);
|
|
821
716
|
return entity;
|
|
822
|
-
}
|
|
823
|
-
|
|
717
|
+
}
|
|
824
718
|
|
|
825
|
-
|
|
719
|
+
// Only go inside valid branch
|
|
720
|
+
const allowedSpecsForEntity = contentValidatorSpec.items.filter(item => Array.isArray(item) ? item.some(
|
|
721
|
+
// [p, hr, ...] or [p, [text, {}], ...]
|
|
826
722
|
spec => (Array.isArray(spec) ? spec[0] : spec) === child.type) : true);
|
|
827
|
-
|
|
828
723
|
if (allowedSpecsForEntity.length) {
|
|
829
724
|
if (allowedSpecsForEntity.length > 1) {
|
|
830
725
|
throw new Error('Consider using Tuple instead!');
|
|
831
726
|
}
|
|
832
|
-
|
|
833
727
|
const maybeArray = makeArray(allowedSpecsForEntity[0]);
|
|
834
728
|
const allowedSpecsForChild = maybeArray.filter(item => (Array.isArray(item) ? item[0] : item) === child.type);
|
|
835
|
-
|
|
836
729
|
if (allowedSpecsForChild.length === 0) {
|
|
837
730
|
return invalidChildContent(child, errorCallback, validatorSpec);
|
|
838
731
|
}
|
|
732
|
+
|
|
839
733
|
/**
|
|
840
734
|
* When there's multiple possible branches try all of them.
|
|
841
735
|
* If all of them fails, throw the first one.
|
|
842
736
|
* e.g.- [['text', { marks: ['a'] }], ['text', { marks: ['b'] }]]
|
|
843
737
|
*/
|
|
844
|
-
|
|
845
|
-
|
|
846
738
|
let firstError;
|
|
847
739
|
let firstChild;
|
|
848
|
-
|
|
849
740
|
for (let i = 0, len = allowedSpecsForChild.length; i < len; i++) {
|
|
850
741
|
try {
|
|
851
742
|
const allowedValueForCurrentSpec = [allowedSpecsForChild[i]];
|
|
@@ -854,7 +745,6 @@ export function validator(nodes, marks, options) {
|
|
|
854
745
|
entity: newChildEntity,
|
|
855
746
|
marksValidationOutput
|
|
856
747
|
} = validateNode(child, errorCallback, allowedValueForCurrentSpec, validatorSpec);
|
|
857
|
-
|
|
858
748
|
if (valid) {
|
|
859
749
|
const isLastValidationSpec = i === allowedSpecsForChild.length - 1;
|
|
860
750
|
const {
|
|
@@ -862,7 +752,6 @@ export function validator(nodes, marks, options) {
|
|
|
862
752
|
entity
|
|
863
753
|
} = validateChildMarks(newChildEntity, marksValidationOutput, errorCallback, isLastValidationSpec);
|
|
864
754
|
const unsupportedMarks = entity && entity.marks && entity.marks.filter(mark => mark.type === 'unsupportedMark') || [];
|
|
865
|
-
|
|
866
755
|
if (marksAreValid && !unsupportedMarks.length) {
|
|
867
756
|
return entity;
|
|
868
757
|
} else {
|
|
@@ -875,7 +764,6 @@ export function validator(nodes, marks, options) {
|
|
|
875
764
|
firstError = firstError || error;
|
|
876
765
|
}
|
|
877
766
|
}
|
|
878
|
-
|
|
879
767
|
if (!errorCallback) {
|
|
880
768
|
throw firstError;
|
|
881
769
|
} else {
|
|
@@ -885,7 +773,6 @@ export function validator(nodes, marks, options) {
|
|
|
885
773
|
return invalidChildContent(child, errorCallback, validatorSpec);
|
|
886
774
|
}
|
|
887
775
|
};
|
|
888
|
-
|
|
889
776
|
newEntity.content = prevEntity.content.map(validateChildNode).filter(Boolean);
|
|
890
777
|
} else if (!contentValidatorSpec.optional) {
|
|
891
778
|
return {
|
|
@@ -893,16 +780,15 @@ export function validator(nodes, marks, options) {
|
|
|
893
780
|
result: err('MISSING_PROPERTIES', 'missing `content` prop')
|
|
894
781
|
};
|
|
895
782
|
}
|
|
896
|
-
}
|
|
897
|
-
|
|
783
|
+
}
|
|
898
784
|
|
|
785
|
+
// Marks
|
|
899
786
|
if (prevEntity.marks) {
|
|
900
787
|
return {
|
|
901
788
|
hasValidated: true,
|
|
902
789
|
result: marksValidationFor(validatorSpec, prevEntity, errorCallback, newEntity, err)
|
|
903
790
|
};
|
|
904
791
|
}
|
|
905
|
-
|
|
906
792
|
return specBasedValidationResult;
|
|
907
793
|
}
|
|
908
794
|
}
|