@pie-lib/editable-html 10.0.0-beta.5 → 10.0.0-beta.7
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.md +255 -152
- package/lib/components.js +15 -39
- package/lib/components.js.map +1 -1
- package/lib/editor.js +200 -356
- package/lib/editor.js.map +1 -1
- package/lib/index.js +25 -49
- package/lib/index.js.map +1 -1
- package/lib/new-serialization.js +6 -67
- package/lib/new-serialization.js.map +1 -1
- package/lib/parse-html.js +7 -6
- package/lib/parse-html.js.map +1 -1
- package/lib/plugins/characters/custom-popper.js +3 -13
- package/lib/plugins/characters/custom-popper.js.map +1 -1
- package/lib/plugins/characters/index.js +20 -59
- package/lib/plugins/characters/index.js.map +1 -1
- package/lib/plugins/characters/utils.js +1 -1
- package/lib/plugins/characters/utils.js.map +1 -1
- package/lib/plugins/hotKeys/index.js +9 -16
- package/lib/plugins/hotKeys/index.js.map +1 -1
- package/lib/plugins/image/alt-dialog.js +6 -27
- package/lib/plugins/image/alt-dialog.js.map +1 -1
- package/lib/plugins/image/component.js +42 -99
- package/lib/plugins/image/component.js.map +1 -1
- package/lib/plugins/image/image-toolbar.js +14 -50
- package/lib/plugins/image/image-toolbar.js.map +1 -1
- package/lib/plugins/image/index.js +16 -59
- package/lib/plugins/image/index.js.map +1 -1
- package/lib/plugins/image/insert-image-handler.js +13 -25
- package/lib/plugins/image/insert-image-handler.js.map +1 -1
- package/lib/plugins/index.js +6 -36
- package/lib/plugins/index.js.map +1 -1
- package/lib/plugins/list/index.js +11 -46
- package/lib/plugins/list/index.js.map +1 -1
- package/lib/plugins/math/index.js +89 -93
- package/lib/plugins/math/index.js.map +1 -1
- package/lib/plugins/media/index.js +32 -109
- package/lib/plugins/media/index.js.map +1 -1
- package/lib/plugins/media/media-dialog.js +107 -195
- package/lib/plugins/media/media-dialog.js.map +1 -1
- package/lib/plugins/media/media-toolbar.js +7 -27
- package/lib/plugins/media/media-toolbar.js.map +1 -1
- package/lib/plugins/media/media-wrapper.js +9 -14
- package/lib/plugins/media/media-wrapper.js.map +1 -1
- package/lib/plugins/respArea/drag-in-the-blank/choice.js +13 -53
- package/lib/plugins/respArea/drag-in-the-blank/choice.js.map +1 -1
- package/lib/plugins/respArea/drag-in-the-blank/index.js +6 -20
- package/lib/plugins/respArea/drag-in-the-blank/index.js.map +1 -1
- package/lib/plugins/respArea/explicit-constructed-response/index.js +5 -10
- package/lib/plugins/respArea/explicit-constructed-response/index.js.map +1 -1
- package/lib/plugins/respArea/icons/index.js +16 -31
- package/lib/plugins/respArea/icons/index.js.map +1 -1
- package/lib/plugins/respArea/index.js +7 -54
- package/lib/plugins/respArea/index.js.map +1 -1
- package/lib/plugins/respArea/inline-dropdown/index.js +3 -10
- package/lib/plugins/respArea/inline-dropdown/index.js.map +1 -1
- package/lib/plugins/respArea/utils.js +6 -21
- package/lib/plugins/respArea/utils.js.map +1 -1
- package/lib/plugins/table/icons/index.js +1 -8
- package/lib/plugins/table/icons/index.js.map +1 -1
- package/lib/plugins/table/index.js +54 -187
- package/lib/plugins/table/index.js.map +1 -1
- package/lib/plugins/table/table-toolbar.js +12 -44
- package/lib/plugins/table/table-toolbar.js.map +1 -1
- package/lib/plugins/toolbar/default-toolbar.js +17 -46
- package/lib/plugins/toolbar/default-toolbar.js.map +1 -1
- package/lib/plugins/toolbar/done-button.js +2 -10
- package/lib/plugins/toolbar/done-button.js.map +1 -1
- package/lib/plugins/toolbar/editor-and-toolbar.js +134 -144
- package/lib/plugins/toolbar/editor-and-toolbar.js.map +1 -1
- package/lib/plugins/toolbar/index.js +2 -6
- package/lib/plugins/toolbar/index.js.map +1 -1
- package/lib/plugins/toolbar/toolbar-buttons.js +9 -40
- package/lib/plugins/toolbar/toolbar-buttons.js.map +1 -1
- package/lib/plugins/toolbar/toolbar.js +29 -83
- package/lib/plugins/toolbar/toolbar.js.map +1 -1
- package/lib/plugins/utils.js +8 -30
- package/lib/plugins/utils.js.map +1 -1
- package/lib/serialization.js +11 -69
- package/lib/serialization.js.map +1 -1
- package/lib/test-serializer.js +3 -46
- package/lib/test-serializer.js.map +1 -1
- package/lib/theme.js +1 -1
- package/lib/theme.js.map +1 -1
- package/package.json +7 -7
- package/playground/image/data.js +20 -20
- package/playground/image/index.html +20 -22
- package/playground/image/index.jsx +10 -12
- package/playground/index.html +23 -25
- package/playground/mathquill/index.html +20 -23
- package/playground/mathquill/index.jsx +22 -18
- package/playground/prod-test/index.html +20 -24
- package/playground/prod-test/index.jsx +3 -5
- package/playground/schema-override/data.js +10 -10
- package/playground/schema-override/image-plugin.jsx +4 -3
- package/playground/schema-override/index.html +19 -21
- package/playground/schema-override/index.jsx +14 -13
- package/playground/serialization/data.js +10 -10
- package/playground/serialization/image-plugin.jsx +4 -3
- package/playground/serialization/index.html +20 -22
- package/playground/table-examples.html +8 -5
- package/playground/webpack.config.js +10 -10
- package/src/components.js +7 -7
- package/src/editor.jsx +144 -155
- package/src/index.jsx +24 -17
- package/src/new-serialization.jsx +22 -22
- package/src/parse-html.js +1 -1
- package/src/plugins/characters/custom-popper.js +7 -7
- package/src/plugins/characters/index.jsx +36 -26
- package/src/plugins/characters/utils.js +81 -81
- package/src/plugins/hotKeys/index.js +3 -3
- package/src/plugins/image/alt-dialog.jsx +5 -4
- package/src/plugins/image/component.jsx +52 -53
- package/src/plugins/image/image-toolbar.jsx +19 -27
- package/src/plugins/image/index.jsx +41 -47
- package/src/plugins/image/insert-image-handler.js +23 -14
- package/src/plugins/index.jsx +8 -10
- package/src/plugins/list/index.jsx +21 -24
- package/src/plugins/math/index.jsx +93 -40
- package/src/plugins/media/index.jsx +42 -42
- package/src/plugins/media/media-dialog.js +63 -89
- package/src/plugins/media/media-toolbar.jsx +8 -8
- package/src/plugins/media/media-wrapper.jsx +10 -7
- package/src/plugins/respArea/drag-in-the-blank/choice.jsx +19 -21
- package/src/plugins/respArea/drag-in-the-blank/index.jsx +10 -12
- package/src/plugins/respArea/explicit-constructed-response/index.jsx +6 -5
- package/src/plugins/respArea/icons/index.jsx +14 -11
- package/src/plugins/respArea/index.jsx +32 -56
- package/src/plugins/respArea/inline-dropdown/index.jsx +6 -6
- package/src/plugins/respArea/utils.jsx +15 -11
- package/src/plugins/table/icons/index.jsx +11 -17
- package/src/plugins/table/index.jsx +69 -69
- package/src/plugins/table/table-toolbar.jsx +8 -13
- package/src/plugins/toolbar/default-toolbar.jsx +15 -17
- package/src/plugins/toolbar/done-button.jsx +4 -4
- package/src/plugins/toolbar/editor-and-toolbar.jsx +50 -54
- package/src/plugins/toolbar/index.jsx +3 -2
- package/src/plugins/toolbar/toolbar-buttons.jsx +11 -11
- package/src/plugins/toolbar/toolbar.jsx +43 -42
- package/src/plugins/utils.js +7 -8
- package/src/serialization.jsx +34 -32
- package/src/test-serializer.js +13 -13
- package/lib/old-serialization.js +0 -330
- package/lib/slate-editor.js +0 -302
- package/package-lock.json +0 -3762
package/src/index.jsx
CHANGED
|
@@ -5,6 +5,7 @@ import Editor, { DEFAULT_PLUGINS, ALL_PLUGINS } from './editor';
|
|
|
5
5
|
import { htmlToValue, valueToHtml } from './new-serialization';
|
|
6
6
|
import { parseDegrees } from './parse-html';
|
|
7
7
|
import debug from 'debug';
|
|
8
|
+
import { Range } from 'slate';
|
|
8
9
|
|
|
9
10
|
const log = debug('@pie-lib:editable-html');
|
|
10
11
|
/**
|
|
@@ -48,15 +49,11 @@ const EditableHtml = React.forwardRef((props, forwardedRef) => {
|
|
|
48
49
|
}
|
|
49
50
|
};
|
|
50
51
|
|
|
51
|
-
const focus = (position, node) => {
|
|
52
|
+
const focus = (position, node, select = false) => {
|
|
52
53
|
if (this.editorRef) {
|
|
53
|
-
this.editorRef.change(c => {
|
|
54
|
-
const lastText = node
|
|
55
|
-
|
|
56
|
-
: c.value.document.getLastText();
|
|
57
|
-
const editorDOM = document.querySelector(
|
|
58
|
-
`[data-key="${this.editorRef.value.document.key}"]`
|
|
59
|
-
);
|
|
54
|
+
this.editorRef.change((c) => {
|
|
55
|
+
const lastText = node ? c.value.document.getNextText(node.key) : c.value.document.getLastText();
|
|
56
|
+
const editorDOM = document.querySelector(`[data-key="${this.editorRef.value.document.key}"]`);
|
|
60
57
|
|
|
61
58
|
if (editorDOM !== document.activeElement) {
|
|
62
59
|
document.activeElement.blur();
|
|
@@ -65,15 +62,24 @@ const EditableHtml = React.forwardRef((props, forwardedRef) => {
|
|
|
65
62
|
c.focus();
|
|
66
63
|
|
|
67
64
|
if (position === 'end' && lastText) {
|
|
68
|
-
c.moveFocusTo(lastText.key, lastText.text?.length).moveAnchorTo(
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
65
|
+
c.moveFocusTo(lastText.key, lastText.text?.length).moveAnchorTo(lastText.key, lastText.text?.length);
|
|
66
|
+
if (select) {
|
|
67
|
+
const range = Range.fromJSON({
|
|
68
|
+
anchorKey: lastText.key,
|
|
69
|
+
anchorOffset: 0,
|
|
70
|
+
focusKey: lastText.key,
|
|
71
|
+
focusOffset: lastText.text?.length,
|
|
72
|
+
isFocused: true,
|
|
73
|
+
isBackward: false,
|
|
74
|
+
});
|
|
75
|
+
c.select(range);
|
|
76
|
+
}
|
|
72
77
|
}
|
|
73
78
|
|
|
74
79
|
if (position === 'beginning' && lastText) {
|
|
75
80
|
c.moveFocusTo(lastText.key, 0).moveAnchorTo(lastText.key, 0);
|
|
76
81
|
}
|
|
82
|
+
editorDOM.focus();
|
|
77
83
|
});
|
|
78
84
|
}
|
|
79
85
|
};
|
|
@@ -88,13 +94,14 @@ const EditableHtml = React.forwardRef((props, forwardedRef) => {
|
|
|
88
94
|
...props,
|
|
89
95
|
markup: null,
|
|
90
96
|
value,
|
|
91
|
-
onChange
|
|
97
|
+
onChange,
|
|
98
|
+
focus,
|
|
92
99
|
};
|
|
93
100
|
|
|
94
101
|
return (
|
|
95
102
|
<Editor
|
|
96
103
|
{...newProps}
|
|
97
|
-
onRef={ref => {
|
|
104
|
+
onRef={(ref) => {
|
|
98
105
|
if (ref) {
|
|
99
106
|
rootRef.current = ref;
|
|
100
107
|
|
|
@@ -103,7 +110,7 @@ const EditableHtml = React.forwardRef((props, forwardedRef) => {
|
|
|
103
110
|
}
|
|
104
111
|
}
|
|
105
112
|
}}
|
|
106
|
-
editorRef={ref => ref && (editorRef.current = ref)}
|
|
113
|
+
editorRef={(ref) => ref && (editorRef.current = ref)}
|
|
107
114
|
/>
|
|
108
115
|
);
|
|
109
116
|
});
|
|
@@ -113,12 +120,12 @@ EditableHtml.propTypes = {
|
|
|
113
120
|
onDone: PropTypes.func,
|
|
114
121
|
onEditor: PropTypes.func,
|
|
115
122
|
markup: PropTypes.string.isRequired,
|
|
116
|
-
allowValidation: PropTypes.bool
|
|
123
|
+
allowValidation: PropTypes.bool,
|
|
117
124
|
};
|
|
118
125
|
|
|
119
126
|
EditableHtml.defaultProps = {
|
|
120
127
|
onDone: () => {},
|
|
121
|
-
allowValidation: false
|
|
128
|
+
allowValidation: false,
|
|
122
129
|
};
|
|
123
130
|
|
|
124
131
|
export default EditableHtml;
|
|
@@ -9,9 +9,9 @@ import { serialization as mediaSerialization } from './plugins/media';
|
|
|
9
9
|
import { serialization as listSerialization } from './plugins/list';
|
|
10
10
|
import { serialization as tableSerialization } from './plugins/table';
|
|
11
11
|
import { serialization as responseAreaSerialization } from './plugins/respArea';
|
|
12
|
-
import { Mark, Text, Value } from
|
|
13
|
-
import { jsx } from
|
|
14
|
-
import escapeHtml from
|
|
12
|
+
import { Mark, Text, Value } from 'slate';
|
|
13
|
+
import { jsx } from 'slate-hyperscript';
|
|
14
|
+
import escapeHtml from 'escape-html';
|
|
15
15
|
|
|
16
16
|
const log = debug('@pie-lib:editable-html:serialization');
|
|
17
17
|
|
|
@@ -32,7 +32,7 @@ export const BLOCK_TAGS = {
|
|
|
32
32
|
h3: 'heading-three',
|
|
33
33
|
h4: 'heading-four',
|
|
34
34
|
h5: 'heading-five',
|
|
35
|
-
h6: 'heading-six'
|
|
35
|
+
h6: 'heading-six',
|
|
36
36
|
};
|
|
37
37
|
|
|
38
38
|
/**
|
|
@@ -48,10 +48,10 @@ export const MARK_TAGS = {
|
|
|
48
48
|
s: 'strikethrough',
|
|
49
49
|
del: 'strikethrough',
|
|
50
50
|
code: 'code',
|
|
51
|
-
strong: 'bold'
|
|
51
|
+
strong: 'bold',
|
|
52
52
|
};
|
|
53
53
|
|
|
54
|
-
export const parseStyleString = s => {
|
|
54
|
+
export const parseStyleString = (s) => {
|
|
55
55
|
const regex = /([\w-]*)\s*:\s*([^;]*)/g;
|
|
56
56
|
let match;
|
|
57
57
|
const result = {};
|
|
@@ -61,18 +61,18 @@ export const parseStyleString = s => {
|
|
|
61
61
|
return result;
|
|
62
62
|
};
|
|
63
63
|
|
|
64
|
-
export const getBase64 = file => {
|
|
64
|
+
export const getBase64 = (file) => {
|
|
65
65
|
return new Promise((resolve, reject) => {
|
|
66
66
|
const reader = new FileReader();
|
|
67
67
|
reader.readAsDataURL(file);
|
|
68
68
|
reader.onload = () => resolve(reader.result);
|
|
69
|
-
reader.onerror = error => reject(error);
|
|
69
|
+
reader.onerror = (error) => reject(error);
|
|
70
70
|
});
|
|
71
71
|
};
|
|
72
72
|
|
|
73
|
-
export const reactAttributes = o => toStyleObject(o, { camelize: true, addUnits: false });
|
|
73
|
+
export const reactAttributes = (o) => toStyleObject(o, { camelize: true, addUnits: false });
|
|
74
74
|
|
|
75
|
-
const attributesToMap = el => (acc, attribute) => {
|
|
75
|
+
const attributesToMap = (el) => (acc, attribute) => {
|
|
76
76
|
const value = el.getAttribute(attribute);
|
|
77
77
|
if (value) {
|
|
78
78
|
if (attribute === 'style') {
|
|
@@ -116,9 +116,9 @@ const blocks = {
|
|
|
116
116
|
/**
|
|
117
117
|
* Here for rendering styles for all block elements
|
|
118
118
|
*/
|
|
119
|
-
data: { attributes: attributes.reduce(attributesToMap(el), {}) }
|
|
119
|
+
data: { attributes: attributes.reduce(attributesToMap(el), {}) },
|
|
120
120
|
},
|
|
121
|
-
next(el.childNodes)
|
|
121
|
+
next(el.childNodes),
|
|
122
122
|
);
|
|
123
123
|
},
|
|
124
124
|
serialize: (object, children) => {
|
|
@@ -136,7 +136,7 @@ const blocks = {
|
|
|
136
136
|
return <Tag {...jsonData.attributes}>{children}</Tag>;
|
|
137
137
|
}
|
|
138
138
|
}
|
|
139
|
-
}
|
|
139
|
+
},
|
|
140
140
|
};
|
|
141
141
|
|
|
142
142
|
const marks = {
|
|
@@ -175,10 +175,10 @@ const marks = {
|
|
|
175
175
|
|
|
176
176
|
return string;
|
|
177
177
|
}
|
|
178
|
-
}
|
|
178
|
+
},
|
|
179
179
|
};
|
|
180
180
|
|
|
181
|
-
const findPreviousText = el => {
|
|
181
|
+
const findPreviousText = (el) => {
|
|
182
182
|
if (el.nodeName === '#text') {
|
|
183
183
|
return el;
|
|
184
184
|
}
|
|
@@ -217,7 +217,7 @@ export const TEXT_RULE = {
|
|
|
217
217
|
return array;
|
|
218
218
|
}, []);
|
|
219
219
|
}
|
|
220
|
-
}
|
|
220
|
+
},
|
|
221
221
|
};
|
|
222
222
|
|
|
223
223
|
const RULES = [
|
|
@@ -229,7 +229,7 @@ const RULES = [
|
|
|
229
229
|
responseAreaSerialization,
|
|
230
230
|
TEXT_RULE,
|
|
231
231
|
blocks,
|
|
232
|
-
marks
|
|
232
|
+
marks,
|
|
233
233
|
];
|
|
234
234
|
|
|
235
235
|
function allWhitespace(node) {
|
|
@@ -240,7 +240,7 @@ function allWhitespace(node) {
|
|
|
240
240
|
function defaultParseHtml(html) {
|
|
241
241
|
if (typeof DOMParser === 'undefined') {
|
|
242
242
|
throw new Error(
|
|
243
|
-
'The native `DOMParser` global which the `Html` serializer uses by default is not present in this environment. You must supply the `options.parseHtml` function instead.'
|
|
243
|
+
'The native `DOMParser` global which the `Html` serializer uses by default is not present in this environment. You must supply the `options.parseHtml` function instead.',
|
|
244
244
|
);
|
|
245
245
|
}
|
|
246
246
|
|
|
@@ -264,14 +264,14 @@ function defaultParseHtml(html) {
|
|
|
264
264
|
const parseHtml =
|
|
265
265
|
typeof window === 'undefined'
|
|
266
266
|
? () => ({
|
|
267
|
-
childNodes: []
|
|
267
|
+
childNodes: [],
|
|
268
268
|
})
|
|
269
269
|
: defaultParseHtml;
|
|
270
270
|
|
|
271
271
|
const serializer = new TestSerializer({
|
|
272
272
|
defaultBlock: 'div',
|
|
273
273
|
rules: RULES,
|
|
274
|
-
parseHtml
|
|
274
|
+
parseHtml,
|
|
275
275
|
});
|
|
276
276
|
|
|
277
277
|
const _extends =
|
|
@@ -290,7 +290,7 @@ const _extends =
|
|
|
290
290
|
return target;
|
|
291
291
|
};
|
|
292
292
|
|
|
293
|
-
export const htmlToValue = html => {
|
|
293
|
+
export const htmlToValue = (html) => {
|
|
294
294
|
try {
|
|
295
295
|
return serializer.deserialize(html);
|
|
296
296
|
} catch (e) {
|
|
@@ -299,7 +299,7 @@ export const htmlToValue = html => {
|
|
|
299
299
|
}
|
|
300
300
|
};
|
|
301
301
|
|
|
302
|
-
export const valueToHtml = value => serializer.serialize(value);
|
|
302
|
+
export const valueToHtml = (value) => serializer.serialize(value);
|
|
303
303
|
|
|
304
304
|
/**
|
|
305
305
|
*
|
package/src/parse-html.js
CHANGED
|
@@ -8,17 +8,17 @@ const styles = () => ({
|
|
|
8
8
|
background: '#fff',
|
|
9
9
|
padding: '10px',
|
|
10
10
|
pointerEvents: 'none',
|
|
11
|
-
zIndex: 99999
|
|
11
|
+
zIndex: 99999,
|
|
12
12
|
},
|
|
13
13
|
paper: {
|
|
14
14
|
padding: 20,
|
|
15
15
|
height: 'auto',
|
|
16
|
-
width: 'auto'
|
|
16
|
+
width: 'auto',
|
|
17
17
|
},
|
|
18
18
|
typography: {
|
|
19
19
|
fontSize: 50,
|
|
20
|
-
textAlign: 'center'
|
|
21
|
-
}
|
|
20
|
+
textAlign: 'center',
|
|
21
|
+
},
|
|
22
22
|
});
|
|
23
23
|
|
|
24
24
|
const CustomPopper = withStyles(styles)(({ classes, children, ...props }) => (
|
|
@@ -27,15 +27,15 @@ const CustomPopper = withStyles(styles)(({ classes, children, ...props }) => (
|
|
|
27
27
|
open
|
|
28
28
|
className={classes.popover}
|
|
29
29
|
classes={{
|
|
30
|
-
paper: classes.paper
|
|
30
|
+
paper: classes.paper,
|
|
31
31
|
}}
|
|
32
32
|
anchorOrigin={{
|
|
33
33
|
vertical: 'bottom',
|
|
34
|
-
horizontal: 'left'
|
|
34
|
+
horizontal: 'left',
|
|
35
35
|
}}
|
|
36
36
|
transformOrigin={{
|
|
37
37
|
vertical: 'top',
|
|
38
|
-
horizontal: 'left'
|
|
38
|
+
horizontal: 'left',
|
|
39
39
|
}}
|
|
40
40
|
disableRestoreFocus
|
|
41
41
|
disableAutoFocus
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import { ReactEditor } from 'slate-react';
|
|
3
|
+
import { Editor } from 'slate';
|
|
2
4
|
import ReactDOM from 'react-dom';
|
|
5
|
+
import PropTypes from 'prop-types';
|
|
3
6
|
import debug from 'debug';
|
|
4
7
|
import get from 'lodash/get';
|
|
5
8
|
|
|
@@ -8,22 +11,20 @@ import { PureToolbar } from '@pie-lib/math-toolbar';
|
|
|
8
11
|
import CustomPopper from './custom-popper';
|
|
9
12
|
import { insertSnackBar } from '../respArea/utils';
|
|
10
13
|
import { characterIcons, spanishConfig, specialConfig } from './utils';
|
|
11
|
-
import { ReactEditor } from 'slate-react';
|
|
12
|
-
import { Editor } from 'slate';
|
|
13
14
|
const log = debug('@pie-lib:editable-html:plugins:characters');
|
|
14
15
|
|
|
15
16
|
const removePopOvers = () => {
|
|
16
17
|
const prevPopOvers = document.querySelectorAll('#mouse-over-popover');
|
|
17
18
|
|
|
18
19
|
log('[characters:removePopOvers]');
|
|
19
|
-
prevPopOvers.forEach(s => s.remove());
|
|
20
|
+
prevPopOvers.forEach((s) => s.remove());
|
|
20
21
|
};
|
|
21
22
|
|
|
22
23
|
export const removeDialogs = () => {
|
|
23
24
|
const prevDialogs = document.querySelectorAll('.insert-character-dialog');
|
|
24
25
|
|
|
25
26
|
log('[characters:removeDialogs]');
|
|
26
|
-
prevDialogs.forEach(s => s.remove());
|
|
27
|
+
prevDialogs.forEach((s) => s.remove());
|
|
27
28
|
removePopOvers();
|
|
28
29
|
};
|
|
29
30
|
|
|
@@ -62,7 +63,7 @@ const insertDialog = ({ editor, callback, opts }) => {
|
|
|
62
63
|
|
|
63
64
|
return obj;
|
|
64
65
|
},
|
|
65
|
-
{ rows: configToUse.characters.length, columns: 0 }
|
|
66
|
+
{ rows: configToUse.characters.length, columns: 0 },
|
|
66
67
|
);
|
|
67
68
|
|
|
68
69
|
let popoverEl;
|
|
@@ -93,7 +94,7 @@ const insertDialog = ({ editor, callback, opts }) => {
|
|
|
93
94
|
|
|
94
95
|
<div style={infoStyle}>{el.unicode}</div>
|
|
95
96
|
</CustomPopper>,
|
|
96
|
-
popoverEl
|
|
97
|
+
popoverEl,
|
|
97
98
|
);
|
|
98
99
|
|
|
99
100
|
document.body.appendChild(newEl);
|
|
@@ -101,13 +102,12 @@ const insertDialog = ({ editor, callback, opts }) => {
|
|
|
101
102
|
|
|
102
103
|
let firstCallMade = false;
|
|
103
104
|
|
|
104
|
-
const listener = e => {
|
|
105
|
+
const listener = (e) => {
|
|
105
106
|
// this will be triggered right after setting it because
|
|
106
107
|
// this toolbar is added on the mousedown event
|
|
107
108
|
// so right after mouseup, the click will be triggered
|
|
108
109
|
if (firstCallMade) {
|
|
109
|
-
const focusIsInModals =
|
|
110
|
-
newEl.contains(e.target) || (popoverEl && popoverEl.contains(e.target));
|
|
110
|
+
const focusIsInModals = newEl.contains(e.target) || (popoverEl && popoverEl.contains(e.target));
|
|
111
111
|
const editorDOM = ReactEditor.toDOMNode(editor, editor);
|
|
112
112
|
const focusIsInEditor = editorDOM.contains(e.target);
|
|
113
113
|
|
|
@@ -126,7 +126,7 @@ const insertDialog = ({ editor, callback, opts }) => {
|
|
|
126
126
|
document.body.removeEventListener('click', listener);
|
|
127
127
|
};
|
|
128
128
|
|
|
129
|
-
const handleChange = val => {
|
|
129
|
+
const handleChange = (val) => {
|
|
130
130
|
if (typeof val === 'string') {
|
|
131
131
|
callback(val, true);
|
|
132
132
|
}
|
|
@@ -138,11 +138,12 @@ const insertDialog = ({ editor, callback, opts }) => {
|
|
|
138
138
|
noDecimal
|
|
139
139
|
hideInput
|
|
140
140
|
noLatexHandling
|
|
141
|
+
hideDoneButtonBackground
|
|
141
142
|
layoutForKeyPad={layoutForCharacters}
|
|
142
143
|
additionalKeys={configToUse.characters.reduce((arr, n) => {
|
|
143
144
|
arr = [
|
|
144
145
|
...arr,
|
|
145
|
-
...n.map(k => ({
|
|
146
|
+
...n.map((k) => ({
|
|
146
147
|
name: get(k, 'name') || k,
|
|
147
148
|
write: get(k, 'write') || k,
|
|
148
149
|
label: get(k, 'label') || k,
|
|
@@ -152,15 +153,15 @@ const insertDialog = ({ editor, callback, opts }) => {
|
|
|
152
153
|
...(k.extraProps || {}),
|
|
153
154
|
style: {
|
|
154
155
|
...(k.extraProps || {}).style,
|
|
155
|
-
border: '1px solid #000'
|
|
156
|
-
}
|
|
156
|
+
border: '1px solid #000',
|
|
157
|
+
},
|
|
157
158
|
},
|
|
158
159
|
...(configToUse.hasPreview
|
|
159
160
|
? {
|
|
160
|
-
actions: { onMouseEnter: ev => renderPopOver(ev, k), onMouseLeave: closePopOver }
|
|
161
|
+
actions: { onMouseEnter: (ev) => renderPopOver(ev, k), onMouseLeave: closePopOver },
|
|
161
162
|
}
|
|
162
|
-
: {})
|
|
163
|
-
}))
|
|
163
|
+
: {}),
|
|
164
|
+
})),
|
|
164
165
|
];
|
|
165
166
|
|
|
166
167
|
return arr;
|
|
@@ -180,14 +181,19 @@ const insertDialog = ({ editor, callback, opts }) => {
|
|
|
180
181
|
const boundRect = cursorItem.getBoundingClientRect();
|
|
181
182
|
|
|
182
183
|
document.body.appendChild(newEl);
|
|
184
|
+
|
|
185
|
+
// when height of toolbar exceeds screen - can happen in scrollable contexts
|
|
186
|
+
let additionalTopOffset = 0;
|
|
187
|
+
if (boundRect.y < newEl.offsetHeight) {
|
|
188
|
+
additionalTopOffset = newEl.offsetHeight - boundRect.y + 10;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
newEl.style.maxWidth = '500px';
|
|
183
192
|
newEl.style.position = 'absolute';
|
|
184
|
-
newEl.style.top = `${boundRect.top + Math.abs(bodyRect.top) - newEl.offsetHeight - 10}px`;
|
|
193
|
+
newEl.style.top = `${boundRect.top + Math.abs(bodyRect.top) - newEl.offsetHeight - 10 + additionalTopOffset}px`;
|
|
185
194
|
newEl.style.zIndex = 99999;
|
|
186
195
|
|
|
187
|
-
const leftValue = `${boundRect.left +
|
|
188
|
-
Math.abs(bodyRect.left) +
|
|
189
|
-
cursorItem.offsetWidth +
|
|
190
|
-
10}px`;
|
|
196
|
+
const leftValue = `${boundRect.left + Math.abs(bodyRect.left) + cursorItem.offsetWidth + 10}px`;
|
|
191
197
|
|
|
192
198
|
const rightValue = `${boundRect.x}px`;
|
|
193
199
|
|
|
@@ -218,20 +224,24 @@ const CharacterIcon = ({ letter }) => (
|
|
|
218
224
|
<div
|
|
219
225
|
style={{
|
|
220
226
|
fontSize: '25px',
|
|
221
|
-
lineHeight: '15px'
|
|
227
|
+
lineHeight: '15px',
|
|
222
228
|
}}
|
|
223
229
|
>
|
|
224
230
|
{letter}
|
|
225
231
|
</div>
|
|
226
232
|
);
|
|
227
233
|
|
|
234
|
+
CharacterIcon.propTypes = {
|
|
235
|
+
letter: PropTypes.string,
|
|
236
|
+
};
|
|
237
|
+
|
|
228
238
|
export default function CharactersPlugin(opts) {
|
|
229
239
|
removeDialogs();
|
|
230
240
|
return {
|
|
231
241
|
name: 'characters',
|
|
232
242
|
toolbar: {
|
|
233
243
|
icon: <CharacterIcon letter={opts.characterIcon || characterIcons[opts.language] || 'ñ'} />,
|
|
234
|
-
onClick: editor => {
|
|
244
|
+
onClick: (editor) => {
|
|
235
245
|
const callback = (char, focus) => {
|
|
236
246
|
if (char) {
|
|
237
247
|
log('[characters:insert]: ', char);
|
|
@@ -246,16 +256,16 @@ export default function CharactersPlugin(opts) {
|
|
|
246
256
|
};
|
|
247
257
|
|
|
248
258
|
insertDialog({ editor, callback, opts });
|
|
249
|
-
}
|
|
259
|
+
},
|
|
250
260
|
},
|
|
251
261
|
|
|
252
262
|
pluginStyles: (node, parentNode, p) => {
|
|
253
263
|
if (p) {
|
|
254
264
|
return {
|
|
255
265
|
position: 'absolute',
|
|
256
|
-
top: 'initial'
|
|
266
|
+
top: 'initial',
|
|
257
267
|
};
|
|
258
268
|
}
|
|
259
|
-
}
|
|
269
|
+
},
|
|
260
270
|
};
|
|
261
271
|
}
|