@pie-lib/editable-html 10.0.0-beta.7 → 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.
- package/CHANGELOG.json +1 -1
- package/CHANGELOG.md +81 -0
- package/LICENSE.md +5 -0
- package/lib/editor.js +410 -543
- package/lib/editor.js.map +1 -1
- package/lib/index.js +200 -101
- package/lib/index.js.map +1 -1
- package/lib/parse-html.js +5 -6
- package/lib/parse-html.js.map +1 -1
- package/lib/plugins/characters/custom-popper.js +12 -2
- package/lib/plugins/characters/custom-popper.js.map +1 -1
- package/lib/plugins/characters/index.js +71 -19
- package/lib/plugins/characters/index.js.map +1 -1
- package/lib/plugins/characters/utils.js.map +1 -1
- package/lib/plugins/html/icons/index.js +38 -0
- package/lib/plugins/html/icons/index.js.map +1 -0
- package/lib/plugins/html/index.js +75 -0
- package/lib/plugins/html/index.js.map +1 -0
- package/lib/plugins/image/alt-dialog.js +26 -0
- package/lib/plugins/image/alt-dialog.js.map +1 -1
- package/lib/plugins/image/component.js +124 -90
- package/lib/plugins/image/component.js.map +1 -1
- package/lib/plugins/image/image-toolbar.js +45 -7
- package/lib/plugins/image/image-toolbar.js.map +1 -1
- package/lib/plugins/image/index.js +91 -113
- package/lib/plugins/image/index.js.map +1 -1
- package/lib/plugins/image/insert-image-handler.js +54 -72
- package/lib/plugins/image/insert-image-handler.js.map +1 -1
- package/lib/plugins/index.js +71 -31
- package/lib/plugins/index.js.map +1 -1
- package/lib/plugins/list/index.js +129 -58
- package/lib/plugins/list/index.js.map +1 -1
- package/lib/plugins/math/index.js +152 -118
- package/lib/plugins/math/index.js.map +1 -1
- package/lib/plugins/media/index.js +185 -168
- package/lib/plugins/media/index.js.map +1 -1
- package/lib/plugins/media/media-dialog.js +197 -110
- package/lib/plugins/media/media-dialog.js.map +1 -1
- package/lib/plugins/media/media-toolbar.js +24 -4
- package/lib/plugins/media/media-toolbar.js.map +1 -1
- package/lib/plugins/media/media-wrapper.js +65 -23
- package/lib/plugins/media/media-wrapper.js.map +1 -1
- package/lib/plugins/respArea/drag-in-the-blank/choice.js +50 -10
- package/lib/plugins/respArea/drag-in-the-blank/choice.js.map +1 -1
- package/lib/plugins/respArea/drag-in-the-blank/index.js +22 -9
- package/lib/plugins/respArea/drag-in-the-blank/index.js.map +1 -1
- package/lib/plugins/respArea/explicit-constructed-response/index.js +9 -4
- package/lib/plugins/respArea/explicit-constructed-response/index.js.map +1 -1
- package/lib/plugins/respArea/icons/index.js +18 -1
- package/lib/plugins/respArea/icons/index.js.map +1 -1
- package/lib/plugins/respArea/index.js +133 -122
- package/lib/plugins/respArea/index.js.map +1 -1
- package/lib/plugins/respArea/inline-dropdown/index.js +10 -4
- package/lib/plugins/respArea/inline-dropdown/index.js.map +1 -1
- package/lib/plugins/respArea/utils.js +33 -15
- package/lib/plugins/respArea/utils.js.map +1 -1
- package/lib/plugins/table/icons/index.js +7 -0
- package/lib/plugins/table/icons/index.js.map +1 -1
- package/lib/plugins/table/index.js +279 -390
- package/lib/plugins/table/index.js.map +1 -1
- package/lib/plugins/table/table-toolbar.js +47 -14
- package/lib/plugins/table/table-toolbar.js.map +1 -1
- package/lib/plugins/toolbar/default-toolbar.js +63 -51
- package/lib/plugins/toolbar/default-toolbar.js.map +1 -1
- package/lib/plugins/toolbar/done-button.js +9 -1
- package/lib/plugins/toolbar/done-button.js.map +1 -1
- package/lib/plugins/toolbar/editor-and-toolbar.js +140 -83
- package/lib/plugins/toolbar/editor-and-toolbar.js.map +1 -1
- package/lib/plugins/toolbar/index.js +5 -0
- package/lib/plugins/toolbar/index.js.map +1 -1
- package/lib/plugins/toolbar/toolbar-buttons.js +39 -8
- package/lib/plugins/toolbar/toolbar-buttons.js.map +1 -1
- package/lib/plugins/toolbar/toolbar.js +261 -225
- package/lib/plugins/toolbar/toolbar.js.map +1 -1
- package/lib/plugins/utils.js +16 -19
- package/lib/plugins/utils.js.map +1 -1
- package/lib/serialization.js +70 -11
- package/lib/serialization.js.map +1 -1
- package/lib/theme.js.map +1 -1
- package/package.json +18 -17
- package/src/editor.jsx +139 -434
- package/src/index.jsx +96 -62
- package/src/plugins/characters/index.jsx +17 -12
- package/src/plugins/html/icons/index.jsx +19 -0
- package/src/plugins/html/index.jsx +68 -0
- package/src/plugins/image/component.jsx +38 -60
- package/src/plugins/image/index.jsx +42 -95
- package/src/plugins/image/insert-image-handler.js +27 -62
- package/src/plugins/index.jsx +39 -21
- package/src/plugins/list/index.jsx +90 -62
- package/src/plugins/math/index.jsx +70 -93
- package/src/plugins/media/index.jsx +117 -146
- package/src/plugins/media/media-dialog.js +9 -10
- package/src/plugins/media/media-wrapper.jsx +27 -29
- package/src/plugins/respArea/drag-in-the-blank/index.jsx +4 -5
- package/src/plugins/respArea/explicit-constructed-response/index.jsx +1 -2
- package/src/plugins/respArea/index.jsx +84 -114
- package/src/plugins/respArea/inline-dropdown/index.jsx +2 -3
- package/src/plugins/respArea/utils.jsx +28 -23
- package/src/plugins/table/index.jsx +214 -334
- package/src/plugins/table/table-toolbar.jsx +4 -3
- package/src/plugins/toolbar/default-toolbar.jsx +30 -48
- package/src/plugins/toolbar/editor-and-toolbar.jsx +114 -114
- package/src/plugins/toolbar/toolbar.jsx +224 -254
- package/src/plugins/utils.js +0 -16
- package/src/serialization.jsx +1 -1
- package/lib/components.js +0 -92
- package/lib/components.js.map +0 -1
- package/lib/new-serialization.js +0 -280
- package/lib/new-serialization.js.map +0 -1
- package/lib/plugins/hotKeys/index.js +0 -60
- package/lib/plugins/hotKeys/index.js.map +0 -1
- package/lib/test-serializer.js +0 -138
- package/lib/test-serializer.js.map +0 -1
- package/src/components.js +0 -135
- package/src/new-serialization.jsx +0 -310
- package/src/plugins/hotKeys/index.js +0 -54
- 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 {
|
|
4
|
+
import { withStyles } from '@material-ui/core/styles';
|
|
5
5
|
|
|
6
|
-
const useStyles =
|
|
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
|
-
|
|
17
|
-
|
|
18
|
-
|
|
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
|
-
|
|
21
|
-
|
|
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
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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,7 +9,7 @@ export const onValueChange = (nodeProps, n, value) => {
|
|
|
9
9
|
change.setNodeByKey(n.key, {
|
|
10
10
|
data: {
|
|
11
11
|
...value,
|
|
12
|
-
index: n.data.index,
|
|
12
|
+
index: n.data.get('index'),
|
|
13
13
|
},
|
|
14
14
|
});
|
|
15
15
|
|
|
@@ -21,11 +21,11 @@ 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((n) => n.data && n.data.index === value.index);
|
|
24
|
+
const dragInTheBlank = val.document.findDescendant((n) => n.data && n.data.get('index') === value.index);
|
|
25
25
|
|
|
26
26
|
change.setNodeByKey(dragInTheBlank.key, {
|
|
27
27
|
data: {
|
|
28
|
-
index: dragInTheBlank.data.index,
|
|
28
|
+
index: dragInTheBlank.data.get('index'),
|
|
29
29
|
},
|
|
30
30
|
});
|
|
31
31
|
|
|
@@ -35,7 +35,7 @@ export const onRemoveResponse = (nodeProps, value) => {
|
|
|
35
35
|
};
|
|
36
36
|
|
|
37
37
|
const DragDrop = (props) => {
|
|
38
|
-
const { attributes,
|
|
38
|
+
const { attributes, data, n, nodeProps, opts } = props;
|
|
39
39
|
const { inTable } = data;
|
|
40
40
|
|
|
41
41
|
return (
|
|
@@ -60,7 +60,6 @@ const DragDrop = (props) => {
|
|
|
60
60
|
removeResponse={(value) => onRemoveResponse(nodeProps, value)}
|
|
61
61
|
>
|
|
62
62
|
{nodeProps.children}
|
|
63
|
-
{children}
|
|
64
63
|
</DragDropTile>
|
|
65
64
|
</span>
|
|
66
65
|
);
|
|
@@ -2,7 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
|
|
4
4
|
const ExplicitConstructedResponse = (props) => {
|
|
5
|
-
const { attributes,
|
|
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> </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,30 +26,24 @@ export default function ResponseAreaPlugin(opts) {
|
|
|
30
26
|
buttonStyles: {
|
|
31
27
|
margin: '0 20px 0 auto',
|
|
32
28
|
},
|
|
33
|
-
onClick: (
|
|
29
|
+
onClick: (value, onChange) => {
|
|
34
30
|
log('[toolbar] onClick');
|
|
35
|
-
const
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
descendants.forEach((d) => {
|
|
39
|
-
if (isOfCurrentType(d)) {
|
|
40
|
-
currentRespAreaList.push(d);
|
|
41
|
-
}
|
|
42
|
-
});
|
|
31
|
+
const change = value.change();
|
|
32
|
+
const currentRespAreaList = change.value.document.filterDescendants(isOfCurrentType);
|
|
43
33
|
|
|
44
|
-
if (currentRespAreaList.
|
|
34
|
+
if (currentRespAreaList.size >= opts.maxResponseAreas) {
|
|
45
35
|
return;
|
|
46
36
|
}
|
|
47
37
|
|
|
48
38
|
const type = opts.type.replace(/-/g, '_');
|
|
49
39
|
const prevIndex = lastIndexMap[type];
|
|
50
|
-
const newIndex =
|
|
40
|
+
const newIndex = prevIndex === 0 ? prevIndex : prevIndex + 1;
|
|
51
41
|
const newInline = getDefaultElement(opts, newIndex);
|
|
52
42
|
|
|
53
43
|
lastIndexMap[type] += 1;
|
|
54
44
|
|
|
55
45
|
if (newInline) {
|
|
56
|
-
|
|
46
|
+
if (change.value.selection.startKey || change.value.selection.endKey) {
|
|
57
47
|
change.insertInline(newInline);
|
|
58
48
|
} else {
|
|
59
49
|
// If the markup is empty and there's no focus
|
|
@@ -79,76 +69,19 @@ export default function ResponseAreaPlugin(opts) {
|
|
|
79
69
|
if (nextText) {
|
|
80
70
|
change.moveFocusTo(nextText.key, 0).moveAnchorTo(nextText.key, 0);
|
|
81
71
|
}
|
|
82
|
-
}
|
|
83
|
-
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
onChange(change);
|
|
84
75
|
}
|
|
85
76
|
},
|
|
86
77
|
customToolbar: opts.respAreaToolbar,
|
|
78
|
+
supports: (node) => node.object === 'inline' && elTypesArray.indexOf(node.type) >= 0,
|
|
87
79
|
showDone: false,
|
|
88
80
|
};
|
|
89
81
|
|
|
90
82
|
return {
|
|
91
83
|
name: 'response_area',
|
|
92
84
|
toolbar,
|
|
93
|
-
rules: (editor) => {
|
|
94
|
-
const { isVoid, isInline, onChange } = editor;
|
|
95
|
-
|
|
96
|
-
editor.isVoid = (element) => {
|
|
97
|
-
return elTypesArray.includes(element.type) ? true : isVoid(element);
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
editor.isInline = (element) => {
|
|
101
|
-
return elTypesArray.includes(element.type) ? true : isInline(element);
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
let oldEditor = cloneDeep(editor);
|
|
105
|
-
|
|
106
|
-
editor.onChange = (options) => {
|
|
107
|
-
const descendants = Array.from(SlateNode.descendants(editor, { reverse: true })).map(([d]) => d);
|
|
108
|
-
const type = opts.type.replace(/-/g, '_');
|
|
109
|
-
|
|
110
|
-
if (isUndefined(lastIndexMap[type])) {
|
|
111
|
-
lastIndexMap[type] = 0;
|
|
112
|
-
|
|
113
|
-
descendants.forEach((d) => {
|
|
114
|
-
if (d.type === type) {
|
|
115
|
-
const newIndex = parseInt(d.data.index, 10);
|
|
116
|
-
|
|
117
|
-
if (newIndex > lastIndexMap[type]) {
|
|
118
|
-
lastIndexMap[type] = newIndex;
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
if (isEqual(editor, oldEditor)) {
|
|
125
|
-
return;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
const oldDescendants = Array.from(SlateNode.descendants(oldEditor, { reverse: true })).map(([d]) => d);
|
|
129
|
-
const currentRespAreaList = descendants.filter(isOfCurrentType);
|
|
130
|
-
const oldRespAreaList = oldDescendants.filter(isOfCurrentType);
|
|
131
|
-
|
|
132
|
-
toolbar.disabled = currentRespAreaList.length >= opts.maxResponseAreas;
|
|
133
|
-
|
|
134
|
-
const arrayToFilter =
|
|
135
|
-
oldRespAreaList.length > currentRespAreaList.length ? oldRespAreaList : currentRespAreaList;
|
|
136
|
-
const arrayToUseForFilter = arrayToFilter === oldRespAreaList ? currentRespAreaList : oldRespAreaList;
|
|
137
|
-
|
|
138
|
-
const elementsWithChangedStatus = arrayToFilter.filter(
|
|
139
|
-
(d) => !arrayToUseForFilter.find((e) => e.data.index === d.data.index),
|
|
140
|
-
);
|
|
141
|
-
|
|
142
|
-
if (elementsWithChangedStatus.length && oldRespAreaList.length > currentRespAreaList.length) {
|
|
143
|
-
opts.onHandleAreaChange(elementsWithChangedStatus);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
oldEditor = cloneDeep(editor);
|
|
147
|
-
onChange(options);
|
|
148
|
-
};
|
|
149
|
-
|
|
150
|
-
return editor;
|
|
151
|
-
},
|
|
152
85
|
filterPlugins: (node, plugins) => {
|
|
153
86
|
if (node.type === 'explicit_constructed_response' || node.type === 'drag_in_the_blank') {
|
|
154
87
|
return [];
|
|
@@ -156,22 +89,18 @@ export default function ResponseAreaPlugin(opts) {
|
|
|
156
89
|
|
|
157
90
|
return plugins.filter((p) => p.name !== 'response_area');
|
|
158
91
|
},
|
|
159
|
-
deleteNode: (e, node,
|
|
92
|
+
deleteNode: (e, node, value, onChange) => {
|
|
160
93
|
e.preventDefault();
|
|
161
94
|
|
|
162
|
-
|
|
163
|
-
type: 'remove_node',
|
|
164
|
-
path: nodePath,
|
|
165
|
-
});
|
|
95
|
+
const change = value.change().removeNodeByKey(node.key);
|
|
166
96
|
|
|
167
|
-
onChange(
|
|
97
|
+
onChange(change);
|
|
168
98
|
},
|
|
169
|
-
supports: (node) => elTypesArray.indexOf(node.type) >= 0,
|
|
170
99
|
renderNode(props) {
|
|
171
|
-
const { attributes, node } = props;
|
|
100
|
+
const { attributes, node: n } = props;
|
|
172
101
|
|
|
173
|
-
if (
|
|
174
|
-
const
|
|
102
|
+
if (n.type === 'explicit_constructed_response') {
|
|
103
|
+
const data = n.data.toJSON();
|
|
175
104
|
let error;
|
|
176
105
|
|
|
177
106
|
if (opts.error) {
|
|
@@ -183,30 +112,61 @@ export default function ResponseAreaPlugin(opts) {
|
|
|
183
112
|
attributes={attributes}
|
|
184
113
|
value={data.value}
|
|
185
114
|
error={error && error[data.index] && error[data.index][0]}
|
|
186
|
-
|
|
187
|
-
{props.children}
|
|
188
|
-
</ExplicitConstructedResponse>
|
|
115
|
+
/>
|
|
189
116
|
);
|
|
190
117
|
}
|
|
191
118
|
|
|
192
|
-
if (
|
|
193
|
-
const
|
|
119
|
+
if (n.type === 'drag_in_the_blank') {
|
|
120
|
+
const data = n.data.toJSON();
|
|
194
121
|
|
|
195
|
-
return
|
|
196
|
-
<DragInTheBlank attributes={attributes} data={data} n={node} nodeProps={props} opts={opts}>
|
|
197
|
-
{props.children}
|
|
198
|
-
</DragInTheBlank>
|
|
199
|
-
);
|
|
122
|
+
return <DragInTheBlank attributes={attributes} data={data} n={n} nodeProps={props} opts={opts} />;
|
|
200
123
|
}
|
|
201
124
|
|
|
202
|
-
if (
|
|
203
|
-
const
|
|
125
|
+
if (n.type === 'inline_dropdown') {
|
|
126
|
+
const data = n.data.toJSON();
|
|
204
127
|
|
|
205
|
-
return
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
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);
|
|
210
170
|
}
|
|
211
171
|
},
|
|
212
172
|
onDrop(event, change, editor) {
|
|
@@ -226,47 +186,57 @@ export const serialization = {
|
|
|
226
186
|
|
|
227
187
|
switch (type) {
|
|
228
188
|
case 'inline_dropdown':
|
|
229
|
-
return
|
|
189
|
+
return {
|
|
190
|
+
object: 'inline',
|
|
230
191
|
type: 'inline_dropdown',
|
|
192
|
+
isVoid: true,
|
|
231
193
|
data: {
|
|
232
194
|
index: el.dataset.index,
|
|
233
195
|
value: el.dataset.value,
|
|
234
196
|
},
|
|
235
|
-
}
|
|
197
|
+
};
|
|
236
198
|
case 'explicit_constructed_response':
|
|
237
|
-
return
|
|
199
|
+
return {
|
|
200
|
+
object: 'inline',
|
|
238
201
|
type: 'explicit_constructed_response',
|
|
202
|
+
isVoid: true,
|
|
239
203
|
data: {
|
|
240
204
|
index: el.dataset.index,
|
|
241
205
|
value: el.dataset.value,
|
|
242
206
|
},
|
|
243
|
-
}
|
|
207
|
+
};
|
|
244
208
|
case 'drag_in_the_blank':
|
|
245
|
-
return
|
|
209
|
+
return {
|
|
210
|
+
object: 'inline',
|
|
246
211
|
type: 'drag_in_the_blank',
|
|
212
|
+
isVoid: true,
|
|
247
213
|
data: {
|
|
248
214
|
index: el.dataset.index,
|
|
249
215
|
id: el.dataset.id,
|
|
250
216
|
value: el.dataset.value,
|
|
251
217
|
inTable: el.dataset.inTable,
|
|
252
218
|
},
|
|
253
|
-
}
|
|
219
|
+
};
|
|
254
220
|
}
|
|
255
221
|
},
|
|
256
222
|
serialize(object) {
|
|
223
|
+
if (object.object !== 'inline') {
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
|
|
257
227
|
switch (object.type) {
|
|
258
228
|
case 'inline_dropdown': {
|
|
259
|
-
const data = object.data;
|
|
229
|
+
const data = object.data.toJSON();
|
|
260
230
|
|
|
261
231
|
return <span data-type="inline_dropdown" data-index={data.index} data-value={data.value} />;
|
|
262
232
|
}
|
|
263
233
|
case 'explicit_constructed_response': {
|
|
264
|
-
const data = object.data;
|
|
234
|
+
const data = object.data.toJSON();
|
|
265
235
|
|
|
266
236
|
return <span data-type="explicit_constructed_response" data-index={data.index} data-value={data.value} />;
|
|
267
237
|
}
|
|
268
238
|
case 'drag_in_the_blank': {
|
|
269
|
-
const data = object.data;
|
|
239
|
+
const data = object.data.toJSON();
|
|
270
240
|
|
|
271
241
|
return (
|
|
272
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,
|
|
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> </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
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
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
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
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) {
|