@pie-lib/editable-html 10.0.0-beta.6 → 10.0.0

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 (118) hide show
  1. package/CHANGELOG.json +1 -1
  2. package/CHANGELOG.md +81 -0
  3. package/LICENSE.md +5 -0
  4. package/lib/editor.js +410 -543
  5. package/lib/editor.js.map +1 -1
  6. package/lib/index.js +200 -101
  7. package/lib/index.js.map +1 -1
  8. package/lib/parse-html.js +5 -6
  9. package/lib/parse-html.js.map +1 -1
  10. package/lib/plugins/characters/custom-popper.js +12 -2
  11. package/lib/plugins/characters/custom-popper.js.map +1 -1
  12. package/lib/plugins/characters/index.js +71 -19
  13. package/lib/plugins/characters/index.js.map +1 -1
  14. package/lib/plugins/characters/utils.js.map +1 -1
  15. package/lib/plugins/html/icons/index.js +38 -0
  16. package/lib/plugins/html/icons/index.js.map +1 -0
  17. package/lib/plugins/html/index.js +75 -0
  18. package/lib/plugins/html/index.js.map +1 -0
  19. package/lib/plugins/image/alt-dialog.js +26 -0
  20. package/lib/plugins/image/alt-dialog.js.map +1 -1
  21. package/lib/plugins/image/component.js +124 -90
  22. package/lib/plugins/image/component.js.map +1 -1
  23. package/lib/plugins/image/image-toolbar.js +45 -7
  24. package/lib/plugins/image/image-toolbar.js.map +1 -1
  25. package/lib/plugins/image/index.js +91 -113
  26. package/lib/plugins/image/index.js.map +1 -1
  27. package/lib/plugins/image/insert-image-handler.js +54 -72
  28. package/lib/plugins/image/insert-image-handler.js.map +1 -1
  29. package/lib/plugins/index.js +71 -31
  30. package/lib/plugins/index.js.map +1 -1
  31. package/lib/plugins/list/index.js +129 -58
  32. package/lib/plugins/list/index.js.map +1 -1
  33. package/lib/plugins/math/index.js +152 -118
  34. package/lib/plugins/math/index.js.map +1 -1
  35. package/lib/plugins/media/index.js +185 -168
  36. package/lib/plugins/media/index.js.map +1 -1
  37. package/lib/plugins/media/media-dialog.js +197 -110
  38. package/lib/plugins/media/media-dialog.js.map +1 -1
  39. package/lib/plugins/media/media-toolbar.js +24 -4
  40. package/lib/plugins/media/media-toolbar.js.map +1 -1
  41. package/lib/plugins/media/media-wrapper.js +65 -23
  42. package/lib/plugins/media/media-wrapper.js.map +1 -1
  43. package/lib/plugins/respArea/drag-in-the-blank/choice.js +50 -10
  44. package/lib/plugins/respArea/drag-in-the-blank/choice.js.map +1 -1
  45. package/lib/plugins/respArea/drag-in-the-blank/index.js +22 -9
  46. package/lib/plugins/respArea/drag-in-the-blank/index.js.map +1 -1
  47. package/lib/plugins/respArea/explicit-constructed-response/index.js +9 -4
  48. package/lib/plugins/respArea/explicit-constructed-response/index.js.map +1 -1
  49. package/lib/plugins/respArea/icons/index.js +18 -1
  50. package/lib/plugins/respArea/icons/index.js.map +1 -1
  51. package/lib/plugins/respArea/index.js +133 -122
  52. package/lib/plugins/respArea/index.js.map +1 -1
  53. package/lib/plugins/respArea/inline-dropdown/index.js +10 -4
  54. package/lib/plugins/respArea/inline-dropdown/index.js.map +1 -1
  55. package/lib/plugins/respArea/utils.js +33 -15
  56. package/lib/plugins/respArea/utils.js.map +1 -1
  57. package/lib/plugins/table/icons/index.js +7 -0
  58. package/lib/plugins/table/icons/index.js.map +1 -1
  59. package/lib/plugins/table/index.js +279 -390
  60. package/lib/plugins/table/index.js.map +1 -1
  61. package/lib/plugins/table/table-toolbar.js +47 -14
  62. package/lib/plugins/table/table-toolbar.js.map +1 -1
  63. package/lib/plugins/toolbar/default-toolbar.js +63 -51
  64. package/lib/plugins/toolbar/default-toolbar.js.map +1 -1
  65. package/lib/plugins/toolbar/done-button.js +9 -1
  66. package/lib/plugins/toolbar/done-button.js.map +1 -1
  67. package/lib/plugins/toolbar/editor-and-toolbar.js +140 -83
  68. package/lib/plugins/toolbar/editor-and-toolbar.js.map +1 -1
  69. package/lib/plugins/toolbar/index.js +5 -0
  70. package/lib/plugins/toolbar/index.js.map +1 -1
  71. package/lib/plugins/toolbar/toolbar-buttons.js +39 -8
  72. package/lib/plugins/toolbar/toolbar-buttons.js.map +1 -1
  73. package/lib/plugins/toolbar/toolbar.js +261 -225
  74. package/lib/plugins/toolbar/toolbar.js.map +1 -1
  75. package/lib/plugins/utils.js +16 -19
  76. package/lib/plugins/utils.js.map +1 -1
  77. package/lib/serialization.js +70 -11
  78. package/lib/serialization.js.map +1 -1
  79. package/lib/theme.js.map +1 -1
  80. package/package.json +18 -17
  81. package/src/editor.jsx +140 -450
  82. package/src/index.jsx +96 -62
  83. package/src/plugins/characters/index.jsx +18 -14
  84. package/src/plugins/html/icons/index.jsx +19 -0
  85. package/src/plugins/html/index.jsx +68 -0
  86. package/src/plugins/image/component.jsx +41 -67
  87. package/src/plugins/image/index.jsx +43 -108
  88. package/src/plugins/image/insert-image-handler.js +27 -62
  89. package/src/plugins/index.jsx +39 -21
  90. package/src/plugins/list/index.jsx +91 -66
  91. package/src/plugins/math/index.jsx +71 -84
  92. package/src/plugins/media/index.jsx +118 -147
  93. package/src/plugins/media/media-dialog.js +9 -10
  94. package/src/plugins/media/media-wrapper.jsx +27 -29
  95. package/src/plugins/respArea/drag-in-the-blank/index.jsx +7 -10
  96. package/src/plugins/respArea/explicit-constructed-response/index.jsx +2 -3
  97. package/src/plugins/respArea/index.jsx +90 -138
  98. package/src/plugins/respArea/inline-dropdown/index.jsx +2 -3
  99. package/src/plugins/respArea/utils.jsx +28 -23
  100. package/src/plugins/table/index.jsx +216 -340
  101. package/src/plugins/table/table-toolbar.jsx +5 -9
  102. package/src/plugins/toolbar/default-toolbar.jsx +31 -51
  103. package/src/plugins/toolbar/editor-and-toolbar.jsx +114 -121
  104. package/src/plugins/toolbar/toolbar.jsx +224 -258
  105. package/src/plugins/utils.js +2 -19
  106. package/src/serialization.jsx +1 -1
  107. package/lib/components.js +0 -92
  108. package/lib/components.js.map +0 -1
  109. package/lib/new-serialization.js +0 -280
  110. package/lib/new-serialization.js.map +0 -1
  111. package/lib/plugins/hotKeys/index.js +0 -60
  112. package/lib/plugins/hotKeys/index.js.map +0 -1
  113. package/lib/test-serializer.js +0 -138
  114. package/lib/test-serializer.js.map +0 -1
  115. package/src/components.js +0 -135
  116. package/src/new-serialization.jsx +0 -310
  117. package/src/plugins/hotKeys/index.js +0 -54
  118. package/src/test-serializer.js +0 -132
@@ -102,15 +102,14 @@ export class MediaDialog extends React.Component {
102
102
 
103
103
  this.state = {
104
104
  ends: ends || 0,
105
- url: url || '',
106
- urlToUse: urlToUse || '',
107
- formattedUrl: src || '',
105
+ url: url,
106
+ urlToUse: urlToUse,
107
+ formattedUrl: src,
108
108
  height: height || 315,
109
109
  invalid: false,
110
110
  starts: starts || 0,
111
111
  width: width || 560,
112
112
  tabValue: 0,
113
- updating: false,
114
113
  fileUpload: {
115
114
  loading: false,
116
115
  url: '',
@@ -133,7 +132,7 @@ export class MediaDialog extends React.Component {
133
132
  const { url, urlToUse, starts, ends } = this.state;
134
133
  const isYoutube = matchYoutubeUrl(url);
135
134
  const isVimeo = matchVimeoUrl(url);
136
- let formattedUrl = urlToUse || '';
135
+ let formattedUrl = urlToUse;
137
136
 
138
137
  if ((isYoutube || isVimeo) && urlToUse) {
139
138
  const params = [];
@@ -184,7 +183,7 @@ export class MediaDialog extends React.Component {
184
183
  this.handleStateChange({
185
184
  urlToUse,
186
185
  invalid: !urlToUse,
187
- url: value || '',
186
+ url: value,
188
187
  });
189
188
  })
190
189
  .catch(log);
@@ -202,7 +201,7 @@ export class MediaDialog extends React.Component {
202
201
 
203
202
  this.handleStateChange({
204
203
  urlToUse,
205
- url: value || '',
204
+ url: value,
206
205
  invalid: false,
207
206
  });
208
207
 
@@ -217,7 +216,7 @@ export class MediaDialog extends React.Component {
217
216
 
218
217
  this.handleStateChange({
219
218
  urlToUse,
220
- url: value || '',
219
+ url: value,
221
220
  ends: null,
222
221
  invalid: false,
223
222
  });
@@ -227,8 +226,8 @@ export class MediaDialog extends React.Component {
227
226
  }
228
227
 
229
228
  this.handleStateChange({
230
- urlToUse: '',
231
- url: '',
229
+ urlToUse: null,
230
+ url: null,
232
231
  invalid: true,
233
232
  });
234
233
  };
@@ -1,9 +1,9 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import classNames from 'classnames';
4
- import { makeStyles } from '@material-ui/styles';
4
+ import { withStyles } from '@material-ui/core/styles';
5
5
 
6
- const useStyles = makeStyles(() => ({
6
+ const useStyles = withStyles(() => ({
7
7
  root: {
8
8
  position: 'relative',
9
9
  },
@@ -13,33 +13,31 @@ const useStyles = makeStyles(() => ({
13
13
  },
14
14
  }));
15
15
 
16
- const MediaWrapper = React.forwardRef((props, ref) => {
17
- const { children, width, attributes, ...rest } = props;
18
- const classes = useStyles(props);
16
+ class MediaWrapper extends React.Component {
17
+ static propTypes = {
18
+ classes: PropTypes.object,
19
+ children: PropTypes.array,
20
+ editor: PropTypes.bool,
21
+ width: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
22
+ };
19
23
 
20
- return (
21
- <span
22
- className={classNames(classes.root, {
23
- [classes.editor]: editor,
24
- })}
25
- ref={ref}
26
- {...rest}
27
- {...attributes}
28
- contentEditable={false}
29
- style={{
30
- width: width || 300
31
- }}
32
- >
33
- {children}
34
- </span>
35
- );
36
- });
24
+ render() {
25
+ const { editor, classes, children, width, ...rest } = this.props;
37
26
 
38
- MediaWrapper.propTypes = {
39
- attributes: PropTypes.object,
40
- classes: PropTypes.object,
41
- children: PropTypes.array,
42
- width: PropTypes.oneOfType([PropTypes.number, PropTypes.string])
43
- };
27
+ return (
28
+ <span
29
+ className={classNames(classes.root, {
30
+ [classes.editor]: editor,
31
+ })}
32
+ {...rest}
33
+ style={{
34
+ width: width || 300,
35
+ }}
36
+ >
37
+ {children}
38
+ </span>
39
+ );
40
+ }
41
+ }
44
42
 
45
- export default MediaWrapper;
43
+ export default useStyles(MediaWrapper);
@@ -9,8 +9,8 @@ export const onValueChange = (nodeProps, n, value) => {
9
9
  change.setNodeByKey(n.key, {
10
10
  data: {
11
11
  ...value,
12
- index: n.data.index
13
- }
12
+ index: n.data.get('index'),
13
+ },
14
14
  });
15
15
 
16
16
  nodeProps.editor.props.onChange(change, () => {
@@ -21,14 +21,12 @@ export const onValueChange = (nodeProps, n, value) => {
21
21
  export const onRemoveResponse = (nodeProps, value) => {
22
22
  const val = nodeProps.editor.value;
23
23
  const change = val.change();
24
- const dragInTheBlank = val.document.findDescendant(
25
- n => n.data && n.data.index === value.index
26
- );
24
+ const dragInTheBlank = val.document.findDescendant((n) => n.data && n.data.get('index') === value.index);
27
25
 
28
26
  change.setNodeByKey(dragInTheBlank.key, {
29
27
  data: {
30
- index: dragInTheBlank.data.index
31
- }
28
+ index: dragInTheBlank.data.get('index'),
29
+ },
32
30
  });
33
31
 
34
32
  nodeProps.editor.props.onChange(change, () => {
@@ -36,8 +34,8 @@ export const onRemoveResponse = (nodeProps, value) => {
36
34
  });
37
35
  };
38
36
 
39
- const DragDrop = props => {
40
- const { attributes, children, data, n, nodeProps, opts } = props;
37
+ const DragDrop = (props) => {
38
+ const { attributes, data, n, nodeProps, opts } = props;
41
39
  const { inTable } = data;
42
40
 
43
41
  return (
@@ -62,7 +60,6 @@ const DragDrop = props => {
62
60
  removeResponse={(value) => onRemoveResponse(nodeProps, value)}
63
61
  >
64
62
  {nodeProps.children}
65
- {children}
66
63
  </DragDropTile>
67
64
  </span>
68
65
  );
@@ -1,8 +1,8 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
 
4
- const ExplicitConstructedResponse = props => {
5
- const { attributes, children, value, error } = props;
4
+ const ExplicitConstructedResponse = (props) => {
5
+ const { attributes, value, error } = props;
6
6
 
7
7
  return (
8
8
  <span
@@ -33,7 +33,6 @@ const ExplicitConstructedResponse = props => {
33
33
  __html: value || '<div>&nbsp;</div>',
34
34
  }}
35
35
  />
36
- {children}
37
36
  </span>
38
37
  );
39
38
  };
@@ -1,11 +1,7 @@
1
1
  import React from 'react';
2
- import { Node as SlateNode } from 'slate';
3
- import { jsx } from 'slate-hyperscript';
4
2
  import debug from 'debug';
5
-
6
- import cloneDeep from 'lodash/cloneDeep';
7
- import isEqual from 'lodash/isEqual';
8
3
  import isUndefined from 'lodash/isUndefined';
4
+
9
5
  import InlineDropdown from './inline-dropdown';
10
6
  import DragInTheBlank from './drag-in-the-blank';
11
7
  import ExplicitConstructedResponse from './explicit-constructed-response';
@@ -30,32 +26,24 @@ export default function ResponseAreaPlugin(opts) {
30
26
  buttonStyles: {
31
27
  margin: '0 20px 0 auto',
32
28
  },
33
- onClick: editor => {
29
+ onClick: (value, onChange) => {
34
30
  log('[toolbar] onClick');
35
- const currentRespAreaList = [];
36
- const descendants = Array.from(SlateNode.descendants(editor, { reverse: true })).map(
37
- ([d]) => d
38
- );
39
-
40
- descendants.forEach(d => {
41
- if (isOfCurrentType(d)) {
42
- currentRespAreaList.push(d);
43
- }
44
- });
31
+ const change = value.change();
32
+ const currentRespAreaList = change.value.document.filterDescendants(isOfCurrentType);
45
33
 
46
- if (currentRespAreaList.length >= opts.maxResponseAreas) {
34
+ if (currentRespAreaList.size >= opts.maxResponseAreas) {
47
35
  return;
48
36
  }
49
37
 
50
38
  const type = opts.type.replace(/-/g, '_');
51
39
  const prevIndex = lastIndexMap[type];
52
- const newIndex = !prevIndex ? 0 : prevIndex + 1;
40
+ const newIndex = prevIndex === 0 ? prevIndex : prevIndex + 1;
53
41
  const newInline = getDefaultElement(opts, newIndex);
54
42
 
55
43
  lastIndexMap[type] += 1;
56
44
 
57
45
  if (newInline) {
58
- /* if (change.value.selection.startKey || change.value.selection.endKey) {
46
+ if (change.value.selection.startKey || change.value.selection.endKey) {
59
47
  change.insertInline(newInline);
60
48
  } else {
61
49
  // If the markup is empty and there's no focus
@@ -81,86 +69,19 @@ export default function ResponseAreaPlugin(opts) {
81
69
  if (nextText) {
82
70
  change.moveFocusTo(nextText.key, 0).moveAnchorTo(nextText.key, 0);
83
71
  }
84
- }*/
85
- editor.insertNode(newInline);
72
+ }
73
+
74
+ onChange(change);
86
75
  }
87
76
  },
88
77
  customToolbar: opts.respAreaToolbar,
78
+ supports: (node) => node.object === 'inline' && elTypesArray.indexOf(node.type) >= 0,
89
79
  showDone: false,
90
80
  };
91
81
 
92
82
  return {
93
83
  name: 'response_area',
94
84
  toolbar,
95
- rules: editor => {
96
- const { isVoid, isInline, onChange } = editor;
97
-
98
- editor.isVoid = element => {
99
- return elTypesArray.includes(element.type) ? true : isVoid(element);
100
- };
101
-
102
- editor.isInline = element => {
103
- return elTypesArray.includes(element.type) ? true : isInline(element);
104
- };
105
-
106
- let oldEditor = cloneDeep(editor);
107
-
108
- editor.onChange = options => {
109
- const descendants = Array.from(SlateNode.descendants(editor, { reverse: true })).map(
110
- ([d]) => d
111
- );
112
- const type = opts.type.replace(/-/g, '_');
113
-
114
- if (isUndefined(lastIndexMap[type])) {
115
- lastIndexMap[type] = 0;
116
-
117
- descendants.forEach(d => {
118
- if (d.type === type) {
119
- const newIndex = parseInt(d.data.index, 10);
120
-
121
- if (newIndex > lastIndexMap[type]) {
122
- lastIndexMap[type] = newIndex;
123
- }
124
- }
125
- });
126
- }
127
-
128
- if (isEqual(editor, oldEditor)) {
129
- return;
130
- }
131
-
132
- const oldDescendants = Array.from(SlateNode.descendants(oldEditor, { reverse: true })).map(
133
- ([d]) => d
134
- );
135
- const currentRespAreaList = descendants.filter(isOfCurrentType);
136
- const oldRespAreaList = oldDescendants.filter(isOfCurrentType);
137
-
138
- toolbar.disabled = currentRespAreaList.length >= opts.maxResponseAreas;
139
-
140
- const arrayToFilter =
141
- oldRespAreaList.length > currentRespAreaList.length
142
- ? oldRespAreaList
143
- : currentRespAreaList;
144
- const arrayToUseForFilter =
145
- arrayToFilter === oldRespAreaList ? currentRespAreaList : oldRespAreaList;
146
-
147
- const elementsWithChangedStatus = arrayToFilter.filter(
148
- d => !arrayToUseForFilter.find(e => e.data.index === d.data.index)
149
- );
150
-
151
- if (
152
- elementsWithChangedStatus.length &&
153
- oldRespAreaList.length > currentRespAreaList.length
154
- ) {
155
- opts.onHandleAreaChange(elementsWithChangedStatus);
156
- }
157
-
158
- oldEditor = cloneDeep(editor);
159
- onChange(options);
160
- };
161
-
162
- return editor;
163
- },
164
85
  filterPlugins: (node, plugins) => {
165
86
  if (node.type === 'explicit_constructed_response' || node.type === 'drag_in_the_blank') {
166
87
  return [];
@@ -168,22 +89,18 @@ export default function ResponseAreaPlugin(opts) {
168
89
 
169
90
  return plugins.filter((p) => p.name !== 'response_area');
170
91
  },
171
- deleteNode: (e, node, nodePath, editor, onChange) => {
92
+ deleteNode: (e, node, value, onChange) => {
172
93
  e.preventDefault();
173
94
 
174
- editor.apply({
175
- type: 'remove_node',
176
- path: nodePath
177
- });
95
+ const change = value.change().removeNodeByKey(node.key);
178
96
 
179
- onChange(editor);
97
+ onChange(change);
180
98
  },
181
- supports: node => elTypesArray.indexOf(node.type) >= 0,
182
99
  renderNode(props) {
183
- const { attributes, node } = props;
100
+ const { attributes, node: n } = props;
184
101
 
185
- if (node.type === 'explicit_constructed_response') {
186
- const { data } = node;
102
+ if (n.type === 'explicit_constructed_response') {
103
+ const data = n.data.toJSON();
187
104
  let error;
188
105
 
189
106
  if (opts.error) {
@@ -195,36 +112,61 @@ export default function ResponseAreaPlugin(opts) {
195
112
  attributes={attributes}
196
113
  value={data.value}
197
114
  error={error && error[data.index] && error[data.index][0]}
198
- >
199
- {props.children}
200
- </ExplicitConstructedResponse>
115
+ />
201
116
  );
202
117
  }
203
118
 
204
- if (node.type === 'drag_in_the_blank') {
205
- const { data } = node;
119
+ if (n.type === 'drag_in_the_blank') {
120
+ const data = n.data.toJSON();
206
121
 
207
- return (
208
- <DragInTheBlank
209
- attributes={attributes}
210
- data={data}
211
- n={node}
212
- nodeProps={props}
213
- opts={opts}
214
- >
215
- {props.children}
216
- </DragInTheBlank>
217
- );
122
+ return <DragInTheBlank attributes={attributes} data={data} n={n} nodeProps={props} opts={opts} />;
218
123
  }
219
124
 
220
- if (node.type === 'inline_dropdown') {
221
- const { data } = node;
125
+ if (n.type === 'inline_dropdown') {
126
+ const data = n.data.toJSON();
222
127
 
223
- return (
224
- <InlineDropdown attributes={attributes} selectedItem={data.value}>
225
- {props.children}
226
- </InlineDropdown>
227
- );
128
+ return <InlineDropdown attributes={attributes} selectedItem={data.value} />;
129
+ }
130
+ },
131
+ onChange(change, editor) {
132
+ const type = opts.type.replace(/-/g, '_');
133
+
134
+ if (isUndefined(lastIndexMap[type])) {
135
+ lastIndexMap[type] = 0;
136
+
137
+ change.value.document.forEachDescendant((d) => {
138
+ if (d.type === type) {
139
+ const newIndex = parseInt(d.data.get('index'), 10);
140
+
141
+ if (newIndex > lastIndexMap[type]) {
142
+ lastIndexMap[type] = newIndex;
143
+ }
144
+ }
145
+ });
146
+ }
147
+
148
+ if (!editor.value) {
149
+ return;
150
+ }
151
+
152
+ const currentRespAreaList = change.value.document.filterDescendants(isOfCurrentType);
153
+ const oldRespAreaList = editor.value.document.filterDescendants(isOfCurrentType);
154
+
155
+ if (currentRespAreaList.size >= opts.maxResponseAreas) {
156
+ toolbar.disabled = true;
157
+ } else {
158
+ toolbar.disabled = false;
159
+ }
160
+
161
+ const arrayToFilter = oldRespAreaList.size > currentRespAreaList.size ? oldRespAreaList : currentRespAreaList;
162
+ const arrayToUseForFilter = arrayToFilter === oldRespAreaList ? currentRespAreaList : oldRespAreaList;
163
+
164
+ const elementsWithChangedStatus = arrayToFilter.filter(
165
+ (d) => !arrayToUseForFilter.find((e) => e.data.get('index') === d.data.get('index')),
166
+ );
167
+
168
+ if (elementsWithChangedStatus.size && oldRespAreaList.size > currentRespAreaList.size) {
169
+ opts.onHandleAreaChange(elementsWithChangedStatus);
228
170
  }
229
171
  },
230
172
  onDrop(event, change, editor) {
@@ -244,47 +186,57 @@ export const serialization = {
244
186
 
245
187
  switch (type) {
246
188
  case 'inline_dropdown':
247
- return jsx('element', {
189
+ return {
190
+ object: 'inline',
248
191
  type: 'inline_dropdown',
192
+ isVoid: true,
249
193
  data: {
250
194
  index: el.dataset.index,
251
- value: el.dataset.value
252
- }
253
- });
195
+ value: el.dataset.value,
196
+ },
197
+ };
254
198
  case 'explicit_constructed_response':
255
- return jsx('element', {
199
+ return {
200
+ object: 'inline',
256
201
  type: 'explicit_constructed_response',
202
+ isVoid: true,
257
203
  data: {
258
204
  index: el.dataset.index,
259
- value: el.dataset.value
260
- }
261
- });
205
+ value: el.dataset.value,
206
+ },
207
+ };
262
208
  case 'drag_in_the_blank':
263
- return jsx('element', {
209
+ return {
210
+ object: 'inline',
264
211
  type: 'drag_in_the_blank',
212
+ isVoid: true,
265
213
  data: {
266
214
  index: el.dataset.index,
267
215
  id: el.dataset.id,
268
216
  value: el.dataset.value,
269
- inTable: el.dataset.inTable
270
- }
271
- });
217
+ inTable: el.dataset.inTable,
218
+ },
219
+ };
272
220
  }
273
221
  },
274
222
  serialize(object) {
223
+ if (object.object !== 'inline') {
224
+ return;
225
+ }
226
+
275
227
  switch (object.type) {
276
228
  case 'inline_dropdown': {
277
- const data = object.data;
229
+ const data = object.data.toJSON();
278
230
 
279
231
  return <span data-type="inline_dropdown" data-index={data.index} data-value={data.value} />;
280
232
  }
281
233
  case 'explicit_constructed_response': {
282
- const data = object.data;
234
+ const data = object.data.toJSON();
283
235
 
284
236
  return <span data-type="explicit_constructed_response" data-index={data.index} data-value={data.value} />;
285
237
  }
286
238
  case 'drag_in_the_blank': {
287
- const data = object.data;
239
+ const data = object.data.toJSON();
288
240
 
289
241
  return (
290
242
  <span
@@ -2,14 +2,14 @@ import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import { Chevron } from '../icons';
4
4
 
5
- const InlineDropdown = ({ attributes, children, selectedItem }) => {
5
+ const InlineDropdown = ({ attributes, selectedItem }) => {
6
+ // TODO: Investigate
6
7
  // Needed because items with values inside have different positioning for some reason
7
8
  const html = selectedItem || '<div>&nbsp</div>';
8
9
 
9
10
  return (
10
11
  <span
11
12
  {...attributes}
12
- contentEditable={false}
13
13
  style={{
14
14
  display: 'inline-flex',
15
15
  height: '50px',
@@ -29,7 +29,6 @@ const InlineDropdown = ({ attributes, children, selectedItem }) => {
29
29
  position: 'relative',
30
30
  }}
31
31
  >
32
- {children}
33
32
  <div
34
33
  style={{
35
34
  flex: 1,
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import ReactDOM from 'react-dom';
3
+ import { Inline } from 'slate';
3
4
  import Snackbar from '@material-ui/core/Snackbar';
4
5
 
5
6
  export const isNumber = (val) => !isNaN(parseFloat(val)) && isFinite(val);
@@ -33,31 +34,35 @@ export const insertSnackBar = (message) => {
33
34
  }, 2000);
34
35
  };
35
36
 
36
- export const defaultECR = index => ({
37
- type: 'explicit_constructed_response',
38
- children: [{ text: '' }],
39
- data: {
40
- index
41
- }
42
- });
37
+ export const defaultECR = (index) =>
38
+ Inline.create({
39
+ type: 'explicit_constructed_response',
40
+ isVoid: true,
41
+ data: {
42
+ index,
43
+ },
44
+ });
43
45
 
44
- export const defaultDIB = (opts, index) => ({
45
- type: 'drag_in_the_blank',
46
- children: [{ text: '' }],
47
- data: {
48
- index,
49
- duplicates: opts.options.duplicates,
50
- value: null
51
- }
52
- });
46
+ export const defaultDIB = (opts, index) =>
47
+ Inline.create({
48
+ type: 'drag_in_the_blank',
49
+ isVoid: true,
50
+ data: {
51
+ index,
52
+ duplicates: opts.options.duplicates,
53
+ value: null,
54
+ },
55
+ });
53
56
 
54
- export const defaultIDD = index => ({
55
- type: 'inline_dropdown',
56
- children: [{ text: '' }],
57
- data: {
58
- index
59
- }
60
- });
57
+ export const defaultIDD = (index) =>
58
+ Inline.create({
59
+ object: 'inline',
60
+ type: 'inline_dropdown',
61
+ isVoid: true,
62
+ data: {
63
+ index,
64
+ },
65
+ });
61
66
 
62
67
  export const getDefaultElement = (opts, index) => {
63
68
  switch (opts.type) {