@pie-lib/editable-html-tip-tap 1.0.2 → 1.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/lib/components/CharacterPicker.js +221 -0
- package/lib/components/EditableHtml.js +323 -0
- package/lib/components/MenuBar.js +693 -0
- package/lib/components/TiptapContainer.js +90 -0
- package/lib/components/buttons/done-button.js +53 -0
- package/lib/components/characters/characterUtils.js +112 -0
- package/lib/components/characters/custom-popper.js +73 -0
- package/lib/components/common/done-button.js +53 -0
- package/lib/components/icons/CssIcon.js +37 -0
- package/lib/components/icons/RespArea.js +95 -0
- package/lib/components/icons/TableIcons.js +69 -0
- package/lib/components/icons/TextAlign.js +194 -0
- package/lib/components/icons/index.js +194 -0
- package/lib/components/image/ImageToolbar.js +16 -0
- package/lib/components/image/InsertImageHandler.js +16 -0
- package/lib/components/media/MediaDialog.js +16 -0
- package/lib/components/media/MediaToolbar.js +16 -0
- package/lib/components/respArea/DragInTheBlank/DragInTheBlank.js +94 -0
- package/lib/components/respArea/DragInTheBlank/choice.js +289 -0
- package/lib/components/respArea/DragInTheBlank.js +94 -0
- package/lib/components/respArea/ExplicitConstructedResponse.js +120 -0
- package/lib/components/respArea/InlineDropdown.js +126 -0
- package/lib/components/respArea/ToolbarIcon.js +105 -0
- package/lib/components/respArea/choice.js +2 -0
- package/lib/extensions/component.js +5 -5
- package/lib/extensions/custom-toolbar-wrapper.js +2 -4
- package/lib/extensions/extended-table.js +30 -0
- package/lib/extensions/index.js +52 -0
- package/lib/extensions/media.js +5 -5
- package/lib/extensions/responseArea.js +7 -7
- package/lib/index.js +16 -1481
- package/lib/plugins/index.js +8 -80
- package/lib/styles/editorContainerStyles.js +200 -0
- package/lib/utils/size.js +34 -0
- package/package.json +1 -1
- package/src/components/CharacterPicker.jsx +185 -0
- package/src/components/EditableHtml.jsx +306 -0
- package/src/components/MenuBar.jsx +630 -0
- package/src/components/TiptapContainer.jsx +96 -0
- package/src/components/characters/characterUtils.js +127 -0
- package/src/components/image/ImageToolbar.jsx +1 -0
- package/src/components/image/InsertImageHandler.js +1 -0
- package/src/components/media/MediaDialog.js +1 -0
- package/src/components/media/MediaToolbar.jsx +1 -0
- package/src/{plugins/respArea/drag-in-the-blank → components/respArea/DragInTheBlank}/choice.jsx +1 -1
- package/src/{plugins/respArea/inline-dropdown/index.jsx → components/respArea/InlineDropdown.jsx} +1 -1
- package/src/components/respArea/ToolbarIcon.jsx +68 -0
- package/src/extensions/component.jsx +2 -2
- package/src/extensions/custom-toolbar-wrapper.jsx +6 -7
- package/src/extensions/extended-table.js +27 -0
- package/src/extensions/index.js +76 -0
- package/src/extensions/media.js +10 -4
- package/src/extensions/responseArea.js +7 -7
- package/src/index.jsx +3 -1440
- package/src/styles/editorContainerStyles.js +203 -0
- package/src/utils/size.js +32 -0
- package/src/__tests__/editor.test.jsx +0 -363
- package/src/__tests__/serialization.test.js +0 -291
- package/src/block-tags.js +0 -17
- package/src/editor.jsx +0 -1197
- package/src/extensions/characters.js +0 -46
- package/src/old-index.jsx +0 -162
- package/src/parse-html.js +0 -8
- package/src/plugins/README.md +0 -27
- package/src/plugins/characters/index.jsx +0 -284
- package/src/plugins/characters/utils.js +0 -447
- package/src/plugins/css/index.jsx +0 -340
- package/src/plugins/customPlugin/index.jsx +0 -85
- package/src/plugins/html/icons/index.jsx +0 -19
- package/src/plugins/html/index.jsx +0 -72
- package/src/plugins/image/__tests__/__snapshots__/component.test.jsx.snap +0 -51
- package/src/plugins/image/__tests__/__snapshots__/image-toolbar-logic.test.jsx.snap +0 -27
- package/src/plugins/image/__tests__/__snapshots__/image-toolbar.test.jsx.snap +0 -44
- package/src/plugins/image/__tests__/component.test.jsx +0 -41
- package/src/plugins/image/__tests__/image-toolbar-logic.test.jsx +0 -42
- package/src/plugins/image/__tests__/image-toolbar.test.jsx +0 -11
- package/src/plugins/image/__tests__/index.test.js +0 -95
- package/src/plugins/image/__tests__/insert-image-handler.test.js +0 -113
- package/src/plugins/image/__tests__/mock-change.js +0 -15
- package/src/plugins/image/alt-dialog.jsx +0 -82
- package/src/plugins/image/component.jsx +0 -343
- package/src/plugins/image/image-toolbar.jsx +0 -100
- package/src/plugins/image/index.jsx +0 -227
- package/src/plugins/image/insert-image-handler.js +0 -79
- package/src/plugins/index.jsx +0 -377
- package/src/plugins/list/__tests__/index.test.js +0 -54
- package/src/plugins/list/index.jsx +0 -305
- package/src/plugins/math/__tests__/__snapshots__/index.test.jsx.snap +0 -48
- package/src/plugins/math/__tests__/index.test.jsx +0 -245
- package/src/plugins/math/index.jsx +0 -379
- package/src/plugins/media/__tests__/index.test.js +0 -75
- package/src/plugins/media/index.jsx +0 -325
- package/src/plugins/media/media-dialog.js +0 -624
- package/src/plugins/media/media-toolbar.jsx +0 -56
- package/src/plugins/media/media-wrapper.jsx +0 -43
- package/src/plugins/rendering/index.js +0 -31
- package/src/plugins/respArea/index.jsx +0 -299
- package/src/plugins/respArea/math-templated/index.jsx +0 -104
- package/src/plugins/respArea/utils.jsx +0 -90
- package/src/plugins/table/CustomTablePlugin.js +0 -113
- package/src/plugins/table/__tests__/__snapshots__/table-toolbar.test.jsx.snap +0 -44
- package/src/plugins/table/__tests__/index.test.jsx +0 -401
- package/src/plugins/table/__tests__/table-toolbar.test.jsx +0 -42
- package/src/plugins/table/index.jsx +0 -427
- package/src/plugins/table/table-toolbar.jsx +0 -136
- package/src/plugins/textAlign/index.jsx +0 -23
- package/src/plugins/toolbar/__tests__/__snapshots__/default-toolbar.test.jsx.snap +0 -923
- package/src/plugins/toolbar/__tests__/__snapshots__/editor-and-toolbar.test.jsx.snap +0 -20
- package/src/plugins/toolbar/__tests__/__snapshots__/toolbar-buttons.test.jsx.snap +0 -36
- package/src/plugins/toolbar/__tests__/__snapshots__/toolbar.test.jsx.snap +0 -46
- package/src/plugins/toolbar/__tests__/default-toolbar.test.jsx +0 -94
- package/src/plugins/toolbar/__tests__/editor-and-toolbar.test.jsx +0 -37
- package/src/plugins/toolbar/__tests__/toolbar-buttons.test.jsx +0 -51
- package/src/plugins/toolbar/__tests__/toolbar.test.jsx +0 -106
- package/src/plugins/toolbar/default-toolbar.jsx +0 -206
- package/src/plugins/toolbar/editor-and-toolbar.jsx +0 -257
- package/src/plugins/toolbar/index.jsx +0 -23
- package/src/plugins/toolbar/toolbar-buttons.jsx +0 -138
- package/src/plugins/toolbar/toolbar.jsx +0 -338
- package/src/plugins/utils.js +0 -31
- package/src/serialization.jsx +0 -621
- /package/src/{plugins → components}/characters/custom-popper.js +0 -0
- /package/src/{plugins/toolbar → components/common}/done-button.jsx +0 -0
- /package/src/{plugins/css/icons/index.jsx → components/icons/CssIcon.jsx} +0 -0
- /package/src/{plugins/respArea/icons/index.jsx → components/icons/RespArea.jsx} +0 -0
- /package/src/{plugins/table/icons/index.jsx → components/icons/TableIcons.jsx} +0 -0
- /package/src/{plugins/textAlign/icons/index.jsx → components/icons/TextAlign.jsx} +0 -0
- /package/src/{plugins/respArea/drag-in-the-blank/index.jsx → components/respArea/DragInTheBlank/DragInTheBlank.jsx} +0 -0
- /package/src/{plugins/respArea/explicit-constructed-response/index.jsx → components/respArea/ExplicitConstructedResponse.jsx} +0 -0
|
@@ -1,305 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { Data } from 'slate';
|
|
3
|
-
import Immutable from 'immutable';
|
|
4
|
-
import PropTypes from 'prop-types';
|
|
5
|
-
import EditList from 'slate-edit-list';
|
|
6
|
-
import ListOptions from 'slate-edit-list/dist/options';
|
|
7
|
-
import debug from 'debug';
|
|
8
|
-
|
|
9
|
-
const log = debug('@pie-lib:editable-html:plugins:list');
|
|
10
|
-
|
|
11
|
-
const b = (type, next, childNodes) => ({
|
|
12
|
-
object: 'block',
|
|
13
|
-
type,
|
|
14
|
-
nodes: next(childNodes),
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
export const serialization = {
|
|
18
|
-
deserialize(el, next) {
|
|
19
|
-
const name = el.tagName.toLowerCase();
|
|
20
|
-
|
|
21
|
-
if (name === 'li') {
|
|
22
|
-
return b('list_item', next, el.childNodes);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
if (name === 'ul') {
|
|
26
|
-
return b('ul_list', next, el.children.length ? Array.from(el.children) : el.childNodes);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
if (name === 'ol') {
|
|
30
|
-
return b('ol_list', next, el.children.length ? Array.from(el.children) : el.childNodes);
|
|
31
|
-
}
|
|
32
|
-
},
|
|
33
|
-
serialize(object, children) {
|
|
34
|
-
if (object.object !== 'block') return;
|
|
35
|
-
|
|
36
|
-
if (object.type === 'list_item') {
|
|
37
|
-
return <li>{children}</li>;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
if (object.type === 'ul_list') {
|
|
41
|
-
return <ul>{children}</ul>;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
if (object.type === 'ol_list') {
|
|
45
|
-
return <ol>{children}</ol>;
|
|
46
|
-
}
|
|
47
|
-
},
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
const createEditList = () => {
|
|
51
|
-
const core = EditList({
|
|
52
|
-
typeDefault: 'span',
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
const listOptions = new ListOptions({
|
|
56
|
-
typeDefault: 'span',
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
// fix outdated schema
|
|
60
|
-
if (core.schema && core.schema.blocks) {
|
|
61
|
-
Object.keys(core.schema.blocks).forEach((key) => {
|
|
62
|
-
const block = core.schema.blocks[key];
|
|
63
|
-
|
|
64
|
-
if (block.parent) {
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
block.nodes[0] = { type: block.nodes[0].types[0] };
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* This override of the core.changes.wrapInList is needed because the version
|
|
74
|
-
* of immutable that we have does not support getting the element at a specific
|
|
75
|
-
* index with a square bracket (list[0]). We have to use the list.get function instead
|
|
76
|
-
*/
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Returns the highest list of blocks that cover the current selection
|
|
80
|
-
*/
|
|
81
|
-
const getHighestSelectedBlocks = (value) => {
|
|
82
|
-
const range = value.selection;
|
|
83
|
-
const document = value.document;
|
|
84
|
-
|
|
85
|
-
const startBlock = document.getClosestBlock(range.startKey);
|
|
86
|
-
const endBlock = document.getClosestBlock(range.endKey);
|
|
87
|
-
|
|
88
|
-
if (startBlock === endBlock) {
|
|
89
|
-
return Immutable.List([startBlock]);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
const ancestor = document.getCommonAncestor(startBlock.key, endBlock.key);
|
|
93
|
-
const startPath = ancestor.getPath(startBlock.key);
|
|
94
|
-
const endPath = ancestor.getPath(endBlock.key);
|
|
95
|
-
|
|
96
|
-
return ancestor.nodes.slice(startPath.get(0), endPath.get(0) + 1);
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Wrap the blocks in the current selection in a new list. Selected
|
|
101
|
-
* lists are merged together.
|
|
102
|
-
*/
|
|
103
|
-
core.changes.wrapInList = function(change, type, data) {
|
|
104
|
-
const selectedBlocks = getHighestSelectedBlocks(change.value);
|
|
105
|
-
|
|
106
|
-
// Wrap in container
|
|
107
|
-
change.wrapBlock({ type: type, data: Data.create(data) }, { normalize: false });
|
|
108
|
-
|
|
109
|
-
// Wrap in list items
|
|
110
|
-
selectedBlocks.forEach(function(node) {
|
|
111
|
-
if (core.utils.isList(node)) {
|
|
112
|
-
// Merge its items with the created list
|
|
113
|
-
node.nodes.forEach(function(_ref) {
|
|
114
|
-
const key = _ref.key;
|
|
115
|
-
return change.unwrapNodeByKey(key, { normalize: false });
|
|
116
|
-
});
|
|
117
|
-
} else if (node.type !== 'list_item') {
|
|
118
|
-
change.wrapBlockByKey(node.key, 'list_item', {
|
|
119
|
-
normalize: false,
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
return change.normalize();
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
core.changes.unwrapList = function unwrapList(opts, change) {
|
|
128
|
-
const items = core.utils.getItemsAtRange(change.value);
|
|
129
|
-
|
|
130
|
-
if (items.isEmpty()) {
|
|
131
|
-
return change;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
// Unwrap the items from their list
|
|
135
|
-
items.forEach((item) => change.unwrapNodeByKey(item.key, { normalize: false }));
|
|
136
|
-
|
|
137
|
-
// Parent of the list of the items
|
|
138
|
-
const firstItem = items.first();
|
|
139
|
-
const parent = change.value.document.getParent(firstItem.key);
|
|
140
|
-
|
|
141
|
-
let index = parent.nodes.findIndex((node) => node.key === firstItem.key);
|
|
142
|
-
|
|
143
|
-
// Unwrap the items' children
|
|
144
|
-
items.forEach((item) => {
|
|
145
|
-
item.nodes.forEach((node) => {
|
|
146
|
-
change.moveNodeByKey(node.key, parent.key, index, {
|
|
147
|
-
normalize: false,
|
|
148
|
-
});
|
|
149
|
-
index += 1;
|
|
150
|
-
});
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
// Finally, remove the now empty items
|
|
154
|
-
items.forEach((item) => change.removeNodeByKey(item.key, { normalize: false }));
|
|
155
|
-
|
|
156
|
-
return change;
|
|
157
|
-
}.bind(this, listOptions);
|
|
158
|
-
|
|
159
|
-
core.utils.getItemsAtRange = function(opts, value, range) {
|
|
160
|
-
range = range || value.selection;
|
|
161
|
-
|
|
162
|
-
if (!range.startKey) {
|
|
163
|
-
return Immutable.List();
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
const { document } = value;
|
|
167
|
-
|
|
168
|
-
const startBlock = document.getClosestBlock(range.startKey);
|
|
169
|
-
const endBlock = document.getClosestBlock(range.endKey);
|
|
170
|
-
|
|
171
|
-
if (startBlock === endBlock) {
|
|
172
|
-
const item = core.utils.getCurrentItem(value, startBlock);
|
|
173
|
-
return item ? Immutable.List([item]) : Immutable.List();
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
const ancestor = document.getCommonAncestor(startBlock.key, endBlock.key);
|
|
177
|
-
|
|
178
|
-
if (core.utils.isList(ancestor)) {
|
|
179
|
-
const startPath = ancestor.getPath(startBlock.key);
|
|
180
|
-
const endPath = ancestor.getPath(endBlock.key);
|
|
181
|
-
|
|
182
|
-
return ancestor.nodes.slice(startPath.get(0), endPath.get(0) + 1);
|
|
183
|
-
} else if (ancestor.type === opts.typeItem) {
|
|
184
|
-
// The ancestor is the highest list item that covers the range
|
|
185
|
-
return Immutable.List([ancestor]);
|
|
186
|
-
}
|
|
187
|
-
// No list of items can cover the range
|
|
188
|
-
return Immutable.List();
|
|
189
|
-
}.bind(this, listOptions);
|
|
190
|
-
|
|
191
|
-
core.utils.getListForItem = function(opts, value, item) {
|
|
192
|
-
const { document } = value;
|
|
193
|
-
const parent = document.getParent(item.key);
|
|
194
|
-
return parent && core.utils.isList(parent) ? parent : null;
|
|
195
|
-
}.bind(this, listOptions);
|
|
196
|
-
|
|
197
|
-
core.utils.isSelectionInList = function(opts, value, type) {
|
|
198
|
-
const items = core.utils.getItemsAtRange(value);
|
|
199
|
-
return (
|
|
200
|
-
!items.isEmpty() &&
|
|
201
|
-
// Check the type of the list if needed
|
|
202
|
-
(!type || core.utils.getListForItem(value, items.first()).get('type') === type)
|
|
203
|
-
);
|
|
204
|
-
}.bind(this, listOptions);
|
|
205
|
-
|
|
206
|
-
return core;
|
|
207
|
-
};
|
|
208
|
-
|
|
209
|
-
export default (options) => {
|
|
210
|
-
const { type, icon } = options;
|
|
211
|
-
|
|
212
|
-
const core = createEditList();
|
|
213
|
-
|
|
214
|
-
// eslint-disable-next-line react/display-name
|
|
215
|
-
core.renderNode = (props) => {
|
|
216
|
-
const { node, attributes, children } = props;
|
|
217
|
-
|
|
218
|
-
switch (node.type) {
|
|
219
|
-
case 'ul_list':
|
|
220
|
-
return <ul {...attributes}>{children}</ul>;
|
|
221
|
-
case 'ol_list':
|
|
222
|
-
return <ol {...attributes}>{children}</ol>;
|
|
223
|
-
case 'list_item':
|
|
224
|
-
return <li {...attributes}>{children}</li>;
|
|
225
|
-
}
|
|
226
|
-
};
|
|
227
|
-
|
|
228
|
-
core.toolbar = {
|
|
229
|
-
isMark: false,
|
|
230
|
-
ariaLabel: type == 'ul_list' ? 'bulleted list' : 'numbered-list',
|
|
231
|
-
type,
|
|
232
|
-
icon,
|
|
233
|
-
isActive: (value, type) => {
|
|
234
|
-
if (!core.utils.isSelectionInList(value)) {
|
|
235
|
-
return false;
|
|
236
|
-
}
|
|
237
|
-
const current = core.utils.getCurrentList(value);
|
|
238
|
-
return current ? current.type === type : false;
|
|
239
|
-
},
|
|
240
|
-
onClick: (value, onChange) => {
|
|
241
|
-
log('[onClick]', value);
|
|
242
|
-
const inList = core.utils.isSelectionInList(value);
|
|
243
|
-
if (inList) {
|
|
244
|
-
const change = value.change().call(core.changes.unwrapList);
|
|
245
|
-
onChange(change);
|
|
246
|
-
} else {
|
|
247
|
-
const change = value.change().call(core.changes.wrapInList, type);
|
|
248
|
-
onChange(change);
|
|
249
|
-
}
|
|
250
|
-
},
|
|
251
|
-
};
|
|
252
|
-
|
|
253
|
-
core.normalizeNode = (node) => {
|
|
254
|
-
if (node.object !== 'document' && node.object !== 'block') {
|
|
255
|
-
return undefined;
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
const response = core.validateNode(node);
|
|
259
|
-
|
|
260
|
-
const invalidListItems = [];
|
|
261
|
-
|
|
262
|
-
node.forEachDescendant((d) => {
|
|
263
|
-
if (d.type === 'list_item' && d.nodes.size === 1 && d.nodes.first().object === 'text') {
|
|
264
|
-
// if we have a list_item that has only a text inside, we need to add a block in it
|
|
265
|
-
invalidListItems.push(d);
|
|
266
|
-
}
|
|
267
|
-
});
|
|
268
|
-
|
|
269
|
-
if (!invalidListItems.length && !response) {
|
|
270
|
-
return undefined;
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
return (change) => {
|
|
274
|
-
if (response) {
|
|
275
|
-
response(change);
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
if (invalidListItems.length) {
|
|
279
|
-
change.withoutNormalization(() => {
|
|
280
|
-
invalidListItems.forEach((node) => {
|
|
281
|
-
const textNode = node.nodes.first();
|
|
282
|
-
const wrappedBlock = {
|
|
283
|
-
object: 'block',
|
|
284
|
-
type: 'div',
|
|
285
|
-
nodes: [textNode.toJSON()],
|
|
286
|
-
};
|
|
287
|
-
|
|
288
|
-
change.removeNodeByKey(textNode.key);
|
|
289
|
-
|
|
290
|
-
change.insertNodeByKey(node.key, 0, wrappedBlock);
|
|
291
|
-
});
|
|
292
|
-
});
|
|
293
|
-
}
|
|
294
|
-
};
|
|
295
|
-
};
|
|
296
|
-
|
|
297
|
-
core.renderNode.propTypes = {
|
|
298
|
-
node: PropTypes.object,
|
|
299
|
-
attributes: PropTypes.object,
|
|
300
|
-
children: PropTypes.func,
|
|
301
|
-
};
|
|
302
|
-
core.name = type;
|
|
303
|
-
|
|
304
|
-
return core;
|
|
305
|
-
};
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
-
|
|
3
|
-
exports[`CustomToolbarComp render renders with default keypadMode 1`] = `
|
|
4
|
-
<MathToolbar
|
|
5
|
-
additionalKeys={Array []}
|
|
6
|
-
autoFocus={true}
|
|
7
|
-
controlledKeypadMode={true}
|
|
8
|
-
keypadMode="geometry"
|
|
9
|
-
latex="foo"
|
|
10
|
-
onChange={[Function]}
|
|
11
|
-
onDone={[Function]}
|
|
12
|
-
/>
|
|
13
|
-
`;
|
|
14
|
-
|
|
15
|
-
exports[`CustomToolbarComp render renders with default keypadMode 2`] = `
|
|
16
|
-
<MathToolbar
|
|
17
|
-
additionalKeys={Array []}
|
|
18
|
-
autoFocus={true}
|
|
19
|
-
controlledKeypadMode={true}
|
|
20
|
-
keypadMode={3}
|
|
21
|
-
latex="foo"
|
|
22
|
-
onChange={[Function]}
|
|
23
|
-
onDone={[Function]}
|
|
24
|
-
/>
|
|
25
|
-
`;
|
|
26
|
-
|
|
27
|
-
exports[`CustomToolbarComp render renders without default keypadMode 1`] = `
|
|
28
|
-
<MathToolbar
|
|
29
|
-
additionalKeys={Array []}
|
|
30
|
-
autoFocus={true}
|
|
31
|
-
controlledKeypadMode={true}
|
|
32
|
-
latex="foo"
|
|
33
|
-
onChange={[Function]}
|
|
34
|
-
onDone={[Function]}
|
|
35
|
-
/>
|
|
36
|
-
`;
|
|
37
|
-
|
|
38
|
-
exports[`CustomToolbarComp render renders without default keypadMode 2`] = `
|
|
39
|
-
<MathToolbar
|
|
40
|
-
additionalKeys={Array []}
|
|
41
|
-
autoFocus={true}
|
|
42
|
-
controlledKeypadMode={true}
|
|
43
|
-
keypadMode={3}
|
|
44
|
-
latex="foo"
|
|
45
|
-
onChange={[Function]}
|
|
46
|
-
onDone={[Function]}
|
|
47
|
-
/>
|
|
48
|
-
`;
|
|
@@ -1,245 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import debug from 'debug';
|
|
3
|
-
import MockChange from '../../image/__tests__/mock-change';
|
|
4
|
-
import { Data } from 'slate';
|
|
5
|
-
import MathPlugin, { serialization, inlineMath, CustomToolbarComp } from '../index';
|
|
6
|
-
import { shallow } from 'enzyme';
|
|
7
|
-
import { MathToolbar } from '@pie-lib/math-toolbar';
|
|
8
|
-
jest.mock('@pie-framework/mathquill', () => ({
|
|
9
|
-
StaticMath: jest.fn(),
|
|
10
|
-
getInterface: jest.fn().mockReturnThis(),
|
|
11
|
-
registerEmbed: jest.fn(),
|
|
12
|
-
}));
|
|
13
|
-
|
|
14
|
-
jest.mock('@pie-lib/math-toolbar', () => ({
|
|
15
|
-
MathPreview: () => <div />,
|
|
16
|
-
MathToolbar: () => <div />,
|
|
17
|
-
}));
|
|
18
|
-
|
|
19
|
-
jest.mock('@pie-lib/math-rendering', () => ({
|
|
20
|
-
...jest.requireActual('@pie-lib/math-rendering'),
|
|
21
|
-
mmlToLatex: jest.fn(() => {
|
|
22
|
-
return '/foobar/latex';
|
|
23
|
-
}),
|
|
24
|
-
}));
|
|
25
|
-
const log = debug('@pie-lib:editable-html:test:math');
|
|
26
|
-
|
|
27
|
-
// I believe @andrei is moving this stuff out.
|
|
28
|
-
describe('MathPlugin', () => {
|
|
29
|
-
describe('toolbar', () => {
|
|
30
|
-
describe('onClick', () => {
|
|
31
|
-
let plugin, mockChange, value, onChange;
|
|
32
|
-
beforeEach(() => {
|
|
33
|
-
plugin = MathPlugin({});
|
|
34
|
-
mockChange = new MockChange();
|
|
35
|
-
value = {
|
|
36
|
-
change: jest.fn(() => mockChange),
|
|
37
|
-
};
|
|
38
|
-
onChange = jest.fn();
|
|
39
|
-
plugin.toolbar.onClick(value, onChange);
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
test('calls insertInline', () => {
|
|
43
|
-
expect(mockChange.insertInline).toBeCalledWith(expect.objectContaining({ data: inlineMath().data }));
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
test('it calls onChange', () => {
|
|
47
|
-
expect(onChange).toHaveBeenCalledWith(mockChange);
|
|
48
|
-
});
|
|
49
|
-
});
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
describe('renderNode', () => {
|
|
53
|
-
test('the component has props', () => {
|
|
54
|
-
const plugin = MathPlugin({});
|
|
55
|
-
const { props } = plugin.renderNode({ node: { type: 'math' } });
|
|
56
|
-
expect(props.node).toEqual({ type: 'math' });
|
|
57
|
-
});
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
describe('serialization', () => {
|
|
61
|
-
describe('deserialize', () => {
|
|
62
|
-
const assertDeserialize = (html, expected, wrapType) => {
|
|
63
|
-
it(`innerHTML: ${html} is deserialized to: ${expected} with wrapType: ${wrapType}`, () => {
|
|
64
|
-
const el = {
|
|
65
|
-
tagName: 'span',
|
|
66
|
-
childNodes: [],
|
|
67
|
-
getAttribute: jest.fn(() => ''),
|
|
68
|
-
hasAttribute: jest.fn(() => true),
|
|
69
|
-
innerHTML: html,
|
|
70
|
-
};
|
|
71
|
-
const next = jest.fn();
|
|
72
|
-
|
|
73
|
-
const out = serialization.deserialize(el, next);
|
|
74
|
-
expect(out).toEqual({
|
|
75
|
-
object: 'inline',
|
|
76
|
-
type: 'math',
|
|
77
|
-
isVoid: true,
|
|
78
|
-
nodes: [],
|
|
79
|
-
data: {
|
|
80
|
-
latex: expected,
|
|
81
|
-
wrapper: wrapType,
|
|
82
|
-
},
|
|
83
|
-
});
|
|
84
|
-
});
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
assertDeserialize('$$<$$', '<', MathPlugin.DOLLAR);
|
|
88
|
-
assertDeserialize('$<$', '<', MathPlugin.DOLLAR);
|
|
89
|
-
assertDeserialize('\\(<\\)', '<', MathPlugin.ROUND_BRACKETS);
|
|
90
|
-
assertDeserialize('\\[<\\]', '<', MathPlugin.ROUND_BRACKETS);
|
|
91
|
-
assertDeserialize('latex', 'latex', MathPlugin.ROUND_BRACKETS);
|
|
92
|
-
assertDeserialize('\\displaystyle foo', 'foo', MathPlugin.ROUND_BRACKETS);
|
|
93
|
-
|
|
94
|
-
it('should make mathml editable if MathPlugin.mathMlOptions.mmlEditing is true', () => {
|
|
95
|
-
MathPlugin.mathMlOptions.mmlEditing = true;
|
|
96
|
-
const el = {
|
|
97
|
-
tagName: 'math',
|
|
98
|
-
outerHTML:
|
|
99
|
-
'<math xmlns="http://www.w3.org/1998/Math/MathML"> <mn>2</mn> <mi>x</mi> <mtext> </mtext> <mo>≤</mo> <mn>4</mn> <mi>y</mi> <mtext> </mtext> <mo>+</mo> <mtext> </mtext> <mn>8</mn> <msqrt> <mi>h</mi> </msqrt></math>',
|
|
100
|
-
};
|
|
101
|
-
const next = jest.fn();
|
|
102
|
-
|
|
103
|
-
const out = serialization.deserialize(el, next);
|
|
104
|
-
|
|
105
|
-
expect(out).toEqual({
|
|
106
|
-
object: 'inline',
|
|
107
|
-
type: 'math',
|
|
108
|
-
isVoid: true,
|
|
109
|
-
nodes: [],
|
|
110
|
-
data: {
|
|
111
|
-
latex: '/foobar/latex',
|
|
112
|
-
wrapper: 'round_brackets',
|
|
113
|
-
},
|
|
114
|
-
});
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
it('should make mathml readOnly if MathPlugin.mathMlOptions.mmlEditing is false', () => {
|
|
118
|
-
MathPlugin.mathMlOptions.mmlEditing = false;
|
|
119
|
-
const el = {
|
|
120
|
-
tagName: 'math',
|
|
121
|
-
outerHTML:
|
|
122
|
-
'<math xmlns="http://www.w3.org/1998/Math/MathML"> <mn>2</mn> <mi>x</mi> <mtext> </mtext> <mo>≤</mo> <mn>4</mn> <mi>y</mi> <mtext> </mtext> <mo>+</mo> <mtext> </mtext> <mn>8</mn> <msqrt> <mi>h</mi> </msqrt></math>',
|
|
123
|
-
};
|
|
124
|
-
const next = jest.fn();
|
|
125
|
-
|
|
126
|
-
const out = serialization.deserialize(el, next);
|
|
127
|
-
|
|
128
|
-
expect(out).toEqual({
|
|
129
|
-
object: 'inline',
|
|
130
|
-
isVoid: true,
|
|
131
|
-
type: 'mathml',
|
|
132
|
-
data: {
|
|
133
|
-
html: el.outerHTML,
|
|
134
|
-
},
|
|
135
|
-
});
|
|
136
|
-
});
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
describe('serialize', () => {
|
|
140
|
-
const assertSerialize = (latex, expectedHtml, wrapper) => {
|
|
141
|
-
wrapper = wrapper || MathPlugin.ROUND_BRACKETS;
|
|
142
|
-
it(`${latex} is serialized to: ${expectedHtml}`, () => {
|
|
143
|
-
const object = {
|
|
144
|
-
kind: 'inline',
|
|
145
|
-
type: 'math',
|
|
146
|
-
isVoid: true,
|
|
147
|
-
nodes: [],
|
|
148
|
-
data: Data.create({ latex, wrapper }),
|
|
149
|
-
};
|
|
150
|
-
const children = [];
|
|
151
|
-
|
|
152
|
-
const out = serialization.serialize(object, children);
|
|
153
|
-
log('out: ', out);
|
|
154
|
-
expect(out).toEqual(
|
|
155
|
-
<span data-latex="" data-raw={latex}>
|
|
156
|
-
{expectedHtml}
|
|
157
|
-
</span>,
|
|
158
|
-
);
|
|
159
|
-
});
|
|
160
|
-
};
|
|
161
|
-
|
|
162
|
-
assertSerialize('latex', '\\(latex\\)', MathPlugin.ROUND_BRACKETS);
|
|
163
|
-
assertSerialize('latex', '\\(latex\\)', MathPlugin.SQUARE_BRACKETS);
|
|
164
|
-
assertSerialize('latex', '$latex$', MathPlugin.DOLLAR);
|
|
165
|
-
assertSerialize('latex', '$latex$', MathPlugin.DOUBLE_DOLLAR);
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
* Note that when this is converted to html it get's escaped - but that's an issue with the slate html-serializer.
|
|
169
|
-
*/
|
|
170
|
-
assertSerialize('<', '\\(<\\)');
|
|
171
|
-
assertSerialize('x<y', '\\(x<y\\)');
|
|
172
|
-
});
|
|
173
|
-
});
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
describe('CustomToolbarComp', () => {
|
|
177
|
-
let onDataChange;
|
|
178
|
-
let onToolbarDone;
|
|
179
|
-
|
|
180
|
-
const wrapper = (extras) => {
|
|
181
|
-
let mockChange = new MockChange();
|
|
182
|
-
const defaults = {
|
|
183
|
-
node: {
|
|
184
|
-
key: '1',
|
|
185
|
-
data: Data.create({ latex: 'foo' }),
|
|
186
|
-
equals: () => true,
|
|
187
|
-
},
|
|
188
|
-
value: {
|
|
189
|
-
document: {
|
|
190
|
-
getNextText: jest.fn().mockReturnValue({ key: 'nt' }),
|
|
191
|
-
},
|
|
192
|
-
change: jest.fn().mockReturnValue(mockChange),
|
|
193
|
-
},
|
|
194
|
-
onDataChange,
|
|
195
|
-
onToolbarDone,
|
|
196
|
-
};
|
|
197
|
-
|
|
198
|
-
const props = {
|
|
199
|
-
...defaults,
|
|
200
|
-
...extras,
|
|
201
|
-
};
|
|
202
|
-
|
|
203
|
-
return shallow(<CustomToolbarComp {...props} />);
|
|
204
|
-
};
|
|
205
|
-
|
|
206
|
-
describe('render', () => {
|
|
207
|
-
it('renders without default keypadMode', () => {
|
|
208
|
-
const w = wrapper();
|
|
209
|
-
|
|
210
|
-
expect(w).toMatchSnapshot();
|
|
211
|
-
|
|
212
|
-
w.setProps({ pluginProps: { math: { keypadMode: 3 } } });
|
|
213
|
-
|
|
214
|
-
expect(w).toMatchSnapshot();
|
|
215
|
-
});
|
|
216
|
-
|
|
217
|
-
it('renders with default keypadMode', () => {
|
|
218
|
-
const w = wrapper({ pluginProps: { math: { keypadMode: 'geometry' } } });
|
|
219
|
-
|
|
220
|
-
expect(w).toMatchSnapshot();
|
|
221
|
-
|
|
222
|
-
w.setProps({ pluginProps: { math: { keypadMode: 3 } } });
|
|
223
|
-
|
|
224
|
-
expect(w).toMatchSnapshot();
|
|
225
|
-
});
|
|
226
|
-
});
|
|
227
|
-
|
|
228
|
-
describe('onDone', () => {
|
|
229
|
-
it('calls onToolbarDone', () => {
|
|
230
|
-
onToolbarDone = jest.fn();
|
|
231
|
-
const w = wrapper();
|
|
232
|
-
w.find(MathToolbar).prop('onDone')('oo');
|
|
233
|
-
expect(onToolbarDone).toHaveBeenCalledWith(expect.anything(), false);
|
|
234
|
-
});
|
|
235
|
-
});
|
|
236
|
-
|
|
237
|
-
describe('onChange', () => {
|
|
238
|
-
it('calls onDataChange', () => {
|
|
239
|
-
onDataChange = jest.fn();
|
|
240
|
-
const w = wrapper();
|
|
241
|
-
w.find(MathToolbar).prop('onChange')('oo');
|
|
242
|
-
expect(onDataChange).toHaveBeenCalledWith('1', { latex: 'oo' });
|
|
243
|
-
});
|
|
244
|
-
});
|
|
245
|
-
});
|