UNPKG

4.24 kBJavaScriptView Raw
1'use strict';
2
3var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
4
5function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
6
7var isList = require('./isList');
8
9/**
10 * Create a schema for lists
11 * @param {PluginOptions} The plugin options
12 * @return {Object} A schema definition with rules to normalize lists
13 */
14function makeSchema(opts) {
15 var schema = {
16 blocks: _defineProperty({}, opts.typeItem, {
17 parent: { types: opts.types },
18 nodes: [{ kinds: ['block'] }],
19 normalize: function normalize(change, reason, context) {
20 if (reason === 'parent_type_invalid') {
21 return change.unwrapBlockByKey(context.node.key, { normalize: false });
22 }
23
24 if (reason === 'child_kind_invalid') {
25 return wrapChildrenInDefaultBlock(change, opts, context.node);
26 }
27 }
28 })
29 };
30
31 // validate all list types, ensure they only have list item children
32 opts.types.forEach(function (type) {
33 schema.blocks[type] = {
34 nodes: [{ types: [opts.typeItem] }],
35 normalize: function normalize(change, reason, context) {
36 if (reason === 'child_type_invalid') {
37 return change.wrapBlockByKey(context.child.key, opts.typeItem, { normalize: false });
38 }
39 }
40 };
41 });
42
43 return {
44 schema: schema,
45 validateNode: function validateNode(node) {
46 return joinAdjacentLists(opts, node);
47 }
48 };
49}
50
51/**
52 * Wraps all child nodes of a list item in the default block type.
53 * @param {Slate.Change} A change object
54 * @param {PluginOptions} The plugin options
55 * @return {Slate.Change} A change object, for purposes of chaining
56 */
57function wrapChildrenInDefaultBlock(change, opts, node) {
58 change.wrapBlockByKey(node.nodes.first().key, opts.typeDefault, { normalize: false });
59
60 var wrapper = change.value.document.getDescendant(node.key).nodes.first();
61
62 // Add the remaining items
63 node.nodes.rest().forEach(function (child, index) {
64 return change.moveNodeByKey(child.key, wrapper.key, index + 1, { normalize: false });
65 });
66
67 return change;
68}
69
70/**
71 * @param {PluginOptions} The plugin options
72 * @return {Object} A rule that joins adjacent, same types lists
73 */
74function joinAdjacentLists(opts, node) {
75 if (node.kind !== 'document' && node.kind !== 'block') return;
76
77 var invalids = node.nodes.map(function (child, i) {
78 if (!isList(opts, child)) return;
79 var next = node.nodes.get(i + 1);
80 if (!next || next.type !== child.type) return;
81 return [child, next];
82 }).filter(Boolean);
83
84 if (invalids.isEmpty()) return;
85
86 /**
87 * Join the list pairs
88 */
89 // We join in reverse order, so that multiple lists folds onto the first one
90 return function (change) {
91 invalids.reverse().forEach(function (pair) {
92 var _pair = _slicedToArray(pair, 2),
93 first = _pair[0],
94 second = _pair[1];
95
96 var updatedSecond = change.value.document.getDescendant(second.key);
97 updatedSecond.nodes.forEach(function (secondNode, index) {
98 change.insertNodeByKey(first.key, first.nodes.size + index, secondNode, { normalize: false });
99 });
100
101 change.removeNodeByKey(second.key, { normalize: false });
102 });
103 };
104}
105
106module.exports = makeSchema;
\No newline at end of file