@pie-lib/editable-html-tip-tap 1.0.2 → 1.0.4

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.
Files changed (165) hide show
  1. package/lib/components/CharacterPicker.js +221 -0
  2. package/lib/components/CharacterPicker.js.map +1 -0
  3. package/lib/components/EditableHtml.js +323 -0
  4. package/lib/components/EditableHtml.js.map +1 -0
  5. package/lib/components/MenuBar.js +694 -0
  6. package/lib/components/MenuBar.js.map +1 -0
  7. package/lib/components/TiptapContainer.js +90 -0
  8. package/lib/components/TiptapContainer.js.map +1 -0
  9. package/lib/components/buttons/done-button.js +53 -0
  10. package/lib/components/characters/characterUtils.js +112 -0
  11. package/lib/components/characters/characterUtils.js.map +1 -0
  12. package/lib/components/characters/custom-popper.js +73 -0
  13. package/lib/components/characters/custom-popper.js.map +1 -0
  14. package/lib/components/common/done-button.js +53 -0
  15. package/lib/components/common/done-button.js.map +1 -0
  16. package/lib/components/common/toolbar-buttons.js +194 -0
  17. package/lib/components/icons/CssIcon.js +37 -0
  18. package/lib/components/icons/CssIcon.js.map +1 -0
  19. package/lib/components/icons/RespArea.js +95 -0
  20. package/lib/components/icons/RespArea.js.map +1 -0
  21. package/lib/components/icons/TableIcons.js +69 -0
  22. package/lib/components/icons/TableIcons.js.map +1 -0
  23. package/lib/components/icons/TextAlign.js +194 -0
  24. package/lib/components/icons/TextAlign.js.map +1 -0
  25. package/lib/components/icons/index.js +194 -0
  26. package/lib/components/image/AltDialog.js +129 -0
  27. package/lib/components/image/ImageToolbar.js +177 -0
  28. package/lib/components/image/ImageToolbar.js.map +1 -0
  29. package/lib/components/image/InsertImageHandler.js +115 -0
  30. package/lib/components/image/InsertImageHandler.js.map +1 -0
  31. package/lib/components/image/alt-dialog.js +2 -0
  32. package/lib/components/media/MediaDialog.js +709 -0
  33. package/lib/components/media/MediaDialog.js.map +1 -0
  34. package/lib/components/media/MediaToolbar.js +101 -0
  35. package/lib/components/media/MediaToolbar.js.map +1 -0
  36. package/lib/components/media/MediaWrapper.js +93 -0
  37. package/lib/components/respArea/DragInTheBlank/DragInTheBlank.js +94 -0
  38. package/lib/components/respArea/DragInTheBlank/DragInTheBlank.js.map +1 -0
  39. package/lib/components/respArea/DragInTheBlank/choice.js +289 -0
  40. package/lib/components/respArea/DragInTheBlank/choice.js.map +1 -0
  41. package/lib/components/respArea/DragInTheBlank.js +94 -0
  42. package/lib/components/respArea/ExplicitConstructedResponse.js +120 -0
  43. package/lib/components/respArea/ExplicitConstructedResponse.js.map +1 -0
  44. package/lib/components/respArea/InlineDropdown.js +126 -0
  45. package/lib/components/respArea/InlineDropdown.js.map +1 -0
  46. package/lib/components/respArea/ToolbarIcon.js +105 -0
  47. package/lib/components/respArea/ToolbarIcon.js.map +1 -0
  48. package/lib/components/respArea/choice.js +2 -0
  49. package/lib/constants.js.map +1 -0
  50. package/lib/extensions/component.js +5 -5
  51. package/lib/extensions/component.js.map +1 -0
  52. package/lib/extensions/css.js.map +1 -0
  53. package/lib/extensions/custom-toolbar-wrapper.js +2 -4
  54. package/lib/extensions/custom-toolbar-wrapper.js.map +1 -0
  55. package/lib/extensions/extended-table.js +30 -0
  56. package/lib/extensions/extended-table.js.map +1 -0
  57. package/lib/extensions/image.js +2 -8
  58. package/lib/extensions/image.js.map +1 -0
  59. package/lib/extensions/index.js +52 -0
  60. package/lib/extensions/index.js.map +1 -0
  61. package/lib/extensions/math.js.map +1 -0
  62. package/lib/extensions/media.js +7 -7
  63. package/lib/extensions/media.js.map +1 -0
  64. package/lib/extensions/responseArea.js +7 -7
  65. package/lib/extensions/responseArea.js.map +1 -0
  66. package/lib/index.js +16 -1481
  67. package/lib/index.js.map +1 -0
  68. package/lib/plugins/index.js +8 -80
  69. package/lib/styles/editorContainerStyles.js +200 -0
  70. package/lib/styles/editorContainerStyles.js.map +1 -0
  71. package/lib/theme.js.map +1 -0
  72. package/lib/utils/size.js +34 -0
  73. package/lib/utils/size.js.map +1 -0
  74. package/package.json +1 -1
  75. package/src/components/CharacterPicker.jsx +185 -0
  76. package/src/components/EditableHtml.jsx +306 -0
  77. package/src/components/MenuBar.jsx +630 -0
  78. package/src/components/TiptapContainer.jsx +96 -0
  79. package/src/components/characters/characterUtils.js +127 -0
  80. package/src/{plugins/image/image-toolbar.jsx → components/image/ImageToolbar.jsx} +2 -2
  81. package/src/{plugins/image/insert-image-handler.js → components/image/InsertImageHandler.js} +0 -1
  82. package/src/{plugins/media/media-dialog.js → components/media/MediaDialog.js} +2 -2
  83. package/src/{plugins/respArea/drag-in-the-blank → components/respArea/DragInTheBlank}/choice.jsx +1 -1
  84. package/src/{plugins/respArea/inline-dropdown/index.jsx → components/respArea/InlineDropdown.jsx} +1 -1
  85. package/src/components/respArea/ToolbarIcon.jsx +68 -0
  86. package/src/extensions/component.jsx +2 -2
  87. package/src/extensions/custom-toolbar-wrapper.jsx +6 -7
  88. package/src/extensions/extended-table.js +27 -0
  89. package/src/extensions/image.js +2 -2
  90. package/src/extensions/index.js +76 -0
  91. package/src/extensions/media.js +12 -7
  92. package/src/extensions/responseArea.js +7 -7
  93. package/src/index.jsx +3 -1440
  94. package/src/styles/editorContainerStyles.js +203 -0
  95. package/src/utils/size.js +32 -0
  96. package/src/__tests__/editor.test.jsx +0 -363
  97. package/src/__tests__/serialization.test.js +0 -291
  98. package/src/block-tags.js +0 -17
  99. package/src/editor.jsx +0 -1197
  100. package/src/extensions/characters.js +0 -46
  101. package/src/old-index.jsx +0 -162
  102. package/src/parse-html.js +0 -8
  103. package/src/plugins/README.md +0 -27
  104. package/src/plugins/characters/index.jsx +0 -284
  105. package/src/plugins/characters/utils.js +0 -447
  106. package/src/plugins/css/index.jsx +0 -340
  107. package/src/plugins/customPlugin/index.jsx +0 -85
  108. package/src/plugins/html/icons/index.jsx +0 -19
  109. package/src/plugins/html/index.jsx +0 -72
  110. package/src/plugins/image/__tests__/__snapshots__/component.test.jsx.snap +0 -51
  111. package/src/plugins/image/__tests__/__snapshots__/image-toolbar-logic.test.jsx.snap +0 -27
  112. package/src/plugins/image/__tests__/__snapshots__/image-toolbar.test.jsx.snap +0 -44
  113. package/src/plugins/image/__tests__/component.test.jsx +0 -41
  114. package/src/plugins/image/__tests__/image-toolbar-logic.test.jsx +0 -42
  115. package/src/plugins/image/__tests__/image-toolbar.test.jsx +0 -11
  116. package/src/plugins/image/__tests__/index.test.js +0 -95
  117. package/src/plugins/image/__tests__/insert-image-handler.test.js +0 -113
  118. package/src/plugins/image/__tests__/mock-change.js +0 -15
  119. package/src/plugins/image/component.jsx +0 -343
  120. package/src/plugins/image/index.jsx +0 -227
  121. package/src/plugins/index.jsx +0 -377
  122. package/src/plugins/list/__tests__/index.test.js +0 -54
  123. package/src/plugins/list/index.jsx +0 -305
  124. package/src/plugins/math/__tests__/__snapshots__/index.test.jsx.snap +0 -48
  125. package/src/plugins/math/__tests__/index.test.jsx +0 -245
  126. package/src/plugins/math/index.jsx +0 -379
  127. package/src/plugins/media/__tests__/index.test.js +0 -75
  128. package/src/plugins/media/index.jsx +0 -325
  129. package/src/plugins/rendering/index.js +0 -31
  130. package/src/plugins/respArea/index.jsx +0 -299
  131. package/src/plugins/respArea/math-templated/index.jsx +0 -104
  132. package/src/plugins/respArea/utils.jsx +0 -90
  133. package/src/plugins/table/CustomTablePlugin.js +0 -113
  134. package/src/plugins/table/__tests__/__snapshots__/table-toolbar.test.jsx.snap +0 -44
  135. package/src/plugins/table/__tests__/index.test.jsx +0 -401
  136. package/src/plugins/table/__tests__/table-toolbar.test.jsx +0 -42
  137. package/src/plugins/table/index.jsx +0 -427
  138. package/src/plugins/table/table-toolbar.jsx +0 -136
  139. package/src/plugins/textAlign/index.jsx +0 -23
  140. package/src/plugins/toolbar/__tests__/__snapshots__/default-toolbar.test.jsx.snap +0 -923
  141. package/src/plugins/toolbar/__tests__/__snapshots__/editor-and-toolbar.test.jsx.snap +0 -20
  142. package/src/plugins/toolbar/__tests__/__snapshots__/toolbar-buttons.test.jsx.snap +0 -36
  143. package/src/plugins/toolbar/__tests__/__snapshots__/toolbar.test.jsx.snap +0 -46
  144. package/src/plugins/toolbar/__tests__/default-toolbar.test.jsx +0 -94
  145. package/src/plugins/toolbar/__tests__/editor-and-toolbar.test.jsx +0 -37
  146. package/src/plugins/toolbar/__tests__/toolbar-buttons.test.jsx +0 -51
  147. package/src/plugins/toolbar/__tests__/toolbar.test.jsx +0 -106
  148. package/src/plugins/toolbar/default-toolbar.jsx +0 -206
  149. package/src/plugins/toolbar/editor-and-toolbar.jsx +0 -257
  150. package/src/plugins/toolbar/index.jsx +0 -23
  151. package/src/plugins/toolbar/toolbar.jsx +0 -338
  152. package/src/plugins/utils.js +0 -31
  153. package/src/serialization.jsx +0 -621
  154. /package/src/{plugins → components}/characters/custom-popper.js +0 -0
  155. /package/src/{plugins/toolbar → components/common}/done-button.jsx +0 -0
  156. /package/src/{plugins/toolbar → components/common}/toolbar-buttons.jsx +0 -0
  157. /package/src/{plugins/css/icons/index.jsx → components/icons/CssIcon.jsx} +0 -0
  158. /package/src/{plugins/respArea/icons/index.jsx → components/icons/RespArea.jsx} +0 -0
  159. /package/src/{plugins/table/icons/index.jsx → components/icons/TableIcons.jsx} +0 -0
  160. /package/src/{plugins/textAlign/icons/index.jsx → components/icons/TextAlign.jsx} +0 -0
  161. /package/src/{plugins/image/alt-dialog.jsx → components/image/AltDialog.jsx} +0 -0
  162. /package/src/{plugins/media/media-toolbar.jsx → components/media/MediaToolbar.jsx} +0 -0
  163. /package/src/{plugins/media/media-wrapper.jsx → components/media/MediaWrapper.jsx} +0 -0
  164. /package/src/{plugins/respArea/drag-in-the-blank/index.jsx → components/respArea/DragInTheBlank/DragInTheBlank.jsx} +0 -0
  165. /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('$$&lt;$$', '<', MathPlugin.DOLLAR);
88
- assertDeserialize('$&lt;$', '<', MathPlugin.DOLLAR);
89
- assertDeserialize('\\(&lt;\\)', '<', MathPlugin.ROUND_BRACKETS);
90
- assertDeserialize('\\[&lt;\\]', '<', 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>&#xA0;</mtext> <mo>&#x2264;</mo> <mn>4</mn> <mi>y</mi> <mtext>&#xA0;</mtext> <mo>+</mo> <mtext>&#xA0;</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>&#xA0;</mtext> <mo>&#x2264;</mo> <mn>4</mn> <mi>y</mi> <mtext>&#xA0;</mtext> <mo>+</mo> <mtext>&#xA0;</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
- });