@pie-lib/editable-html-tip-tap 1.0.2 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/components/CharacterPicker.js +221 -0
- package/lib/components/EditableHtml.js +323 -0
- package/lib/components/MenuBar.js +693 -0
- package/lib/components/TiptapContainer.js +90 -0
- package/lib/components/buttons/done-button.js +53 -0
- package/lib/components/characters/characterUtils.js +112 -0
- package/lib/components/characters/custom-popper.js +73 -0
- package/lib/components/common/done-button.js +53 -0
- package/lib/components/icons/CssIcon.js +37 -0
- package/lib/components/icons/RespArea.js +95 -0
- package/lib/components/icons/TableIcons.js +69 -0
- package/lib/components/icons/TextAlign.js +194 -0
- package/lib/components/icons/index.js +194 -0
- package/lib/components/image/ImageToolbar.js +16 -0
- package/lib/components/image/InsertImageHandler.js +16 -0
- package/lib/components/media/MediaDialog.js +16 -0
- package/lib/components/media/MediaToolbar.js +16 -0
- package/lib/components/respArea/DragInTheBlank/DragInTheBlank.js +94 -0
- package/lib/components/respArea/DragInTheBlank/choice.js +289 -0
- package/lib/components/respArea/DragInTheBlank.js +94 -0
- package/lib/components/respArea/ExplicitConstructedResponse.js +120 -0
- package/lib/components/respArea/InlineDropdown.js +126 -0
- package/lib/components/respArea/ToolbarIcon.js +105 -0
- package/lib/components/respArea/choice.js +2 -0
- package/lib/extensions/component.js +5 -5
- package/lib/extensions/custom-toolbar-wrapper.js +2 -4
- package/lib/extensions/extended-table.js +30 -0
- package/lib/extensions/index.js +52 -0
- package/lib/extensions/media.js +5 -5
- package/lib/extensions/responseArea.js +7 -7
- package/lib/index.js +16 -1481
- package/lib/plugins/index.js +8 -80
- package/lib/styles/editorContainerStyles.js +200 -0
- package/lib/utils/size.js +34 -0
- package/package.json +1 -1
- package/src/components/CharacterPicker.jsx +185 -0
- package/src/components/EditableHtml.jsx +306 -0
- package/src/components/MenuBar.jsx +630 -0
- package/src/components/TiptapContainer.jsx +96 -0
- package/src/components/characters/characterUtils.js +127 -0
- package/src/components/image/ImageToolbar.jsx +1 -0
- package/src/components/image/InsertImageHandler.js +1 -0
- package/src/components/media/MediaDialog.js +1 -0
- package/src/components/media/MediaToolbar.jsx +1 -0
- package/src/{plugins/respArea/drag-in-the-blank → components/respArea/DragInTheBlank}/choice.jsx +1 -1
- package/src/{plugins/respArea/inline-dropdown/index.jsx → components/respArea/InlineDropdown.jsx} +1 -1
- package/src/components/respArea/ToolbarIcon.jsx +68 -0
- package/src/extensions/component.jsx +2 -2
- package/src/extensions/custom-toolbar-wrapper.jsx +6 -7
- package/src/extensions/extended-table.js +27 -0
- package/src/extensions/index.js +76 -0
- package/src/extensions/media.js +10 -4
- package/src/extensions/responseArea.js +7 -7
- package/src/index.jsx +3 -1440
- package/src/styles/editorContainerStyles.js +203 -0
- package/src/utils/size.js +32 -0
- package/src/__tests__/editor.test.jsx +0 -363
- package/src/__tests__/serialization.test.js +0 -291
- package/src/block-tags.js +0 -17
- package/src/editor.jsx +0 -1197
- package/src/extensions/characters.js +0 -46
- package/src/old-index.jsx +0 -162
- package/src/parse-html.js +0 -8
- package/src/plugins/README.md +0 -27
- package/src/plugins/characters/index.jsx +0 -284
- package/src/plugins/characters/utils.js +0 -447
- package/src/plugins/css/index.jsx +0 -340
- package/src/plugins/customPlugin/index.jsx +0 -85
- package/src/plugins/html/icons/index.jsx +0 -19
- package/src/plugins/html/index.jsx +0 -72
- package/src/plugins/image/__tests__/__snapshots__/component.test.jsx.snap +0 -51
- package/src/plugins/image/__tests__/__snapshots__/image-toolbar-logic.test.jsx.snap +0 -27
- package/src/plugins/image/__tests__/__snapshots__/image-toolbar.test.jsx.snap +0 -44
- package/src/plugins/image/__tests__/component.test.jsx +0 -41
- package/src/plugins/image/__tests__/image-toolbar-logic.test.jsx +0 -42
- package/src/plugins/image/__tests__/image-toolbar.test.jsx +0 -11
- package/src/plugins/image/__tests__/index.test.js +0 -95
- package/src/plugins/image/__tests__/insert-image-handler.test.js +0 -113
- package/src/plugins/image/__tests__/mock-change.js +0 -15
- package/src/plugins/image/alt-dialog.jsx +0 -82
- package/src/plugins/image/component.jsx +0 -343
- package/src/plugins/image/image-toolbar.jsx +0 -100
- package/src/plugins/image/index.jsx +0 -227
- package/src/plugins/image/insert-image-handler.js +0 -79
- package/src/plugins/index.jsx +0 -377
- package/src/plugins/list/__tests__/index.test.js +0 -54
- package/src/plugins/list/index.jsx +0 -305
- package/src/plugins/math/__tests__/__snapshots__/index.test.jsx.snap +0 -48
- package/src/plugins/math/__tests__/index.test.jsx +0 -245
- package/src/plugins/math/index.jsx +0 -379
- package/src/plugins/media/__tests__/index.test.js +0 -75
- package/src/plugins/media/index.jsx +0 -325
- package/src/plugins/media/media-dialog.js +0 -624
- package/src/plugins/media/media-toolbar.jsx +0 -56
- package/src/plugins/media/media-wrapper.jsx +0 -43
- package/src/plugins/rendering/index.js +0 -31
- package/src/plugins/respArea/index.jsx +0 -299
- package/src/plugins/respArea/math-templated/index.jsx +0 -104
- package/src/plugins/respArea/utils.jsx +0 -90
- package/src/plugins/table/CustomTablePlugin.js +0 -113
- package/src/plugins/table/__tests__/__snapshots__/table-toolbar.test.jsx.snap +0 -44
- package/src/plugins/table/__tests__/index.test.jsx +0 -401
- package/src/plugins/table/__tests__/table-toolbar.test.jsx +0 -42
- package/src/plugins/table/index.jsx +0 -427
- package/src/plugins/table/table-toolbar.jsx +0 -136
- package/src/plugins/textAlign/index.jsx +0 -23
- package/src/plugins/toolbar/__tests__/__snapshots__/default-toolbar.test.jsx.snap +0 -923
- package/src/plugins/toolbar/__tests__/__snapshots__/editor-and-toolbar.test.jsx.snap +0 -20
- package/src/plugins/toolbar/__tests__/__snapshots__/toolbar-buttons.test.jsx.snap +0 -36
- package/src/plugins/toolbar/__tests__/__snapshots__/toolbar.test.jsx.snap +0 -46
- package/src/plugins/toolbar/__tests__/default-toolbar.test.jsx +0 -94
- package/src/plugins/toolbar/__tests__/editor-and-toolbar.test.jsx +0 -37
- package/src/plugins/toolbar/__tests__/toolbar-buttons.test.jsx +0 -51
- package/src/plugins/toolbar/__tests__/toolbar.test.jsx +0 -106
- package/src/plugins/toolbar/default-toolbar.jsx +0 -206
- package/src/plugins/toolbar/editor-and-toolbar.jsx +0 -257
- package/src/plugins/toolbar/index.jsx +0 -23
- package/src/plugins/toolbar/toolbar-buttons.jsx +0 -138
- package/src/plugins/toolbar/toolbar.jsx +0 -338
- package/src/plugins/utils.js +0 -31
- package/src/serialization.jsx +0 -621
- /package/src/{plugins → components}/characters/custom-popper.js +0 -0
- /package/src/{plugins/toolbar → components/common}/done-button.jsx +0 -0
- /package/src/{plugins/css/icons/index.jsx → components/icons/CssIcon.jsx} +0 -0
- /package/src/{plugins/respArea/icons/index.jsx → components/icons/RespArea.jsx} +0 -0
- /package/src/{plugins/table/icons/index.jsx → components/icons/TableIcons.jsx} +0 -0
- /package/src/{plugins/textAlign/icons/index.jsx → components/icons/TextAlign.jsx} +0 -0
- /package/src/{plugins/respArea/drag-in-the-blank/index.jsx → components/respArea/DragInTheBlank/DragInTheBlank.jsx} +0 -0
- /package/src/{plugins/respArea/explicit-constructed-response/index.jsx → components/respArea/ExplicitConstructedResponse.jsx} +0 -0
|
@@ -1,379 +0,0 @@
|
|
|
1
|
-
import Functions from '@material-ui/icons/Functions';
|
|
2
|
-
import { Inline } from 'slate';
|
|
3
|
-
import { MathPreview, MathToolbar } from '@pie-lib/math-toolbar';
|
|
4
|
-
import { wrapMath, unWrapMath, mmlToLatex, renderMath } from '@pie-lib/math-rendering';
|
|
5
|
-
import React from 'react';
|
|
6
|
-
import debug from 'debug';
|
|
7
|
-
import SlatePropTypes from 'slate-prop-types';
|
|
8
|
-
import PropTypes from 'prop-types';
|
|
9
|
-
|
|
10
|
-
import { BLOCK_TAGS } from '../../block-tags';
|
|
11
|
-
import isEqual from 'lodash/isEqual';
|
|
12
|
-
|
|
13
|
-
const log = debug('@pie-lib:editable-html:plugins:math');
|
|
14
|
-
|
|
15
|
-
const TEXT_NODE = 3;
|
|
16
|
-
|
|
17
|
-
function generateAdditionalKeys(keyData = []) {
|
|
18
|
-
return keyData.map((key) => ({
|
|
19
|
-
name: key,
|
|
20
|
-
latex: key,
|
|
21
|
-
write: key,
|
|
22
|
-
label: key,
|
|
23
|
-
}));
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
// eslint-disable-next-line react/display-name
|
|
27
|
-
export const CustomToolbarComp = React.memo(
|
|
28
|
-
(props) => {
|
|
29
|
-
const { node, value, onFocus, onBlur, onClick } = props;
|
|
30
|
-
const { pluginProps } = props || {};
|
|
31
|
-
const { math } = pluginProps || {};
|
|
32
|
-
const { keypadMode, customKeys, controlledKeypadMode = true } = math || {};
|
|
33
|
-
|
|
34
|
-
const onDone = (latex) => {
|
|
35
|
-
const update = {
|
|
36
|
-
...node.data.toObject(),
|
|
37
|
-
latex,
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
const change = value.change().setNodeByKey(node.key, { data: update });
|
|
41
|
-
|
|
42
|
-
const nextText = value.document.getNextText(node.key);
|
|
43
|
-
|
|
44
|
-
change.moveFocusTo(nextText.key, 0).moveAnchorTo(nextText.key, 0);
|
|
45
|
-
|
|
46
|
-
props.onToolbarDone(change, false);
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
const onChange = (latex) => {
|
|
50
|
-
const update = {
|
|
51
|
-
...node.data.toObject(),
|
|
52
|
-
latex,
|
|
53
|
-
};
|
|
54
|
-
const change = value.change().setNodeByKey(node.key, { data: update });
|
|
55
|
-
log('call onToolbarChange:', change);
|
|
56
|
-
props.onDataChange(node.key, update);
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
const latex = node.data.get('latex');
|
|
60
|
-
|
|
61
|
-
return (
|
|
62
|
-
<MathToolbar
|
|
63
|
-
autoFocus
|
|
64
|
-
additionalKeys={generateAdditionalKeys(customKeys)}
|
|
65
|
-
latex={latex}
|
|
66
|
-
onChange={onChange}
|
|
67
|
-
onDone={onDone}
|
|
68
|
-
onBlur={onBlur}
|
|
69
|
-
onFocus={onFocus}
|
|
70
|
-
onClick={onClick}
|
|
71
|
-
keypadMode={keypadMode}
|
|
72
|
-
controlledKeypadMode={controlledKeypadMode}
|
|
73
|
-
/>
|
|
74
|
-
);
|
|
75
|
-
},
|
|
76
|
-
(prev, next) => {
|
|
77
|
-
const { node, pluginProps: { math: { keypadMode, controlledKeypadMode } = {} } = {} } = prev;
|
|
78
|
-
const {
|
|
79
|
-
node: nodeNext,
|
|
80
|
-
pluginProps: { math: { keypadMode: keypadModeNext, controlledKeypadMode: controlledKeypadModeNext } = {} } = {},
|
|
81
|
-
} = next;
|
|
82
|
-
const keypadModeChanged = keypadMode !== keypadModeNext;
|
|
83
|
-
const controlledKeypadModeChanged = controlledKeypadMode !== controlledKeypadModeNext;
|
|
84
|
-
|
|
85
|
-
const equal = node.equals(nodeNext);
|
|
86
|
-
return equal && !keypadModeChanged && !controlledKeypadModeChanged;
|
|
87
|
-
},
|
|
88
|
-
);
|
|
89
|
-
|
|
90
|
-
CustomToolbarComp.propTypes = {
|
|
91
|
-
node: SlatePropTypes.node.isRequired,
|
|
92
|
-
value: SlatePropTypes.value,
|
|
93
|
-
onToolbarDone: PropTypes.func,
|
|
94
|
-
onDataChange: PropTypes.func,
|
|
95
|
-
onFocus: PropTypes.func,
|
|
96
|
-
onClick: PropTypes.func,
|
|
97
|
-
onBlur: PropTypes.func,
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
export default function MathPlugin(opts) {
|
|
101
|
-
MathPlugin.mathMlOptions = {
|
|
102
|
-
mmlOutput: opts.mmlOutput,
|
|
103
|
-
mmlEditing: opts.mmlEditing,
|
|
104
|
-
};
|
|
105
|
-
|
|
106
|
-
return {
|
|
107
|
-
name: 'math',
|
|
108
|
-
toolbar: {
|
|
109
|
-
ariaLabel: 'Math Toolbar',
|
|
110
|
-
icon: <Functions />,
|
|
111
|
-
onClick: (value, onChange) => {
|
|
112
|
-
log('[insertMath]');
|
|
113
|
-
const math = inlineMath();
|
|
114
|
-
const change = value.change().insertInline(math);
|
|
115
|
-
onChange(change);
|
|
116
|
-
},
|
|
117
|
-
supports: (node) => node && node.object === 'inline' && node.type === 'math',
|
|
118
|
-
/**
|
|
119
|
-
* Return a react component function
|
|
120
|
-
* @param node {Slate.Node}
|
|
121
|
-
* @param value {Slate.Value}
|
|
122
|
-
* @param onDone {(change?: Slate.Change, finishEditing :boolea) => void} - a function to call once the toolbar
|
|
123
|
-
* has made any changes, call with the node.key and a data object.
|
|
124
|
-
*/
|
|
125
|
-
CustomToolbarComp,
|
|
126
|
-
},
|
|
127
|
-
schema: {
|
|
128
|
-
document: { match: [{ type: 'math' }] },
|
|
129
|
-
},
|
|
130
|
-
|
|
131
|
-
pluginStyles: (node, parentNode, p) => {
|
|
132
|
-
if (p) {
|
|
133
|
-
return {
|
|
134
|
-
position: 'absolute',
|
|
135
|
-
top: 'initial',
|
|
136
|
-
};
|
|
137
|
-
}
|
|
138
|
-
},
|
|
139
|
-
|
|
140
|
-
renderNode: (props) => {
|
|
141
|
-
if (props.node.type === 'math') {
|
|
142
|
-
log('[renderNode]: data:', props.node.data);
|
|
143
|
-
return <MathPreview {...props} />;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
* Here for rendering mathml content
|
|
148
|
-
*/
|
|
149
|
-
if (props.node.type === 'mathml') {
|
|
150
|
-
const html = props.node.data.get('html');
|
|
151
|
-
|
|
152
|
-
return <span {...props.attributes} dangerouslySetInnerHTML={{ __html: html }} />;
|
|
153
|
-
}
|
|
154
|
-
},
|
|
155
|
-
};
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
MathPlugin.ROUND_BRACKETS = 'round_brackets';
|
|
159
|
-
MathPlugin.SQUARE_BRACKETS = 'square_brackets';
|
|
160
|
-
MathPlugin.DOLLAR = 'dollar';
|
|
161
|
-
MathPlugin.DOUBLE_DOLLAR = 'double_dollar';
|
|
162
|
-
MathPlugin.mathMlOptions = {};
|
|
163
|
-
|
|
164
|
-
MathPlugin.propTypes = {
|
|
165
|
-
attributes: PropTypes.object,
|
|
166
|
-
node: SlatePropTypes.node,
|
|
167
|
-
};
|
|
168
|
-
|
|
169
|
-
export const inlineMath = () =>
|
|
170
|
-
Inline.create({
|
|
171
|
-
object: 'inline',
|
|
172
|
-
type: 'math',
|
|
173
|
-
isVoid: true,
|
|
174
|
-
data: {
|
|
175
|
-
latex: '',
|
|
176
|
-
},
|
|
177
|
-
});
|
|
178
|
-
|
|
179
|
-
const htmlDecode = (input) => {
|
|
180
|
-
const doc = new DOMParser().parseFromString(input, 'text/html');
|
|
181
|
-
|
|
182
|
-
return doc.documentElement.textContent;
|
|
183
|
-
};
|
|
184
|
-
|
|
185
|
-
const getTagName = (el) => {
|
|
186
|
-
return ((el && el.tagName) || '').toLowerCase();
|
|
187
|
-
};
|
|
188
|
-
|
|
189
|
-
/**
|
|
190
|
-
* Makes sure that strings that contain stuff like:
|
|
191
|
-
* x<y are not transformed into x by the DOMParser because it thinks
|
|
192
|
-
* that <y is the start of a dom element tag
|
|
193
|
-
* @param input
|
|
194
|
-
* @returns {*}
|
|
195
|
-
*/
|
|
196
|
-
const arrowHandlingCase = (input) => {
|
|
197
|
-
/*
|
|
198
|
-
If we have a < character followed by a letter
|
|
199
|
-
we make sure to replace it with a < sign instead
|
|
200
|
-
*/
|
|
201
|
-
return input.replace(/<([a-zA-Z]*)/g, '<$1');
|
|
202
|
-
};
|
|
203
|
-
|
|
204
|
-
function replaceLeftRight(latexInput) {
|
|
205
|
-
// for some reason, mmlToLatex parses () incorrectly - or at least in a way that our interpreter can not use them
|
|
206
|
-
// Replace '\\left.' and '\\right.' with an empty string
|
|
207
|
-
return latexInput.replace(/\\left\.\s*|\\right\.\s*/g, '');
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
const convertLatexToMathMl = ({ latex, decoded, wrapper }) => {
|
|
211
|
-
const removeEmptyMos = (mmlFromLatex) => {
|
|
212
|
-
// Regular expression to match <mo>⁡</mo> and <mo ...>⁡</mo>, which get added when using log with base
|
|
213
|
-
// not sure why they get added, but they add an extra space which is not needed
|
|
214
|
-
const regex = /<mo(?: [^>]*)?>⁡<\/mo>/g;
|
|
215
|
-
|
|
216
|
-
// Replace all occurrences of the matched patterns
|
|
217
|
-
return mmlFromLatex.replace(regex, '');
|
|
218
|
-
};
|
|
219
|
-
const handled = arrowHandlingCase(decoded);
|
|
220
|
-
|
|
221
|
-
const latexToConvert = `<span data-latex="" data-raw="${handled}">${wrapMath(handled, wrapper)}</span>`;
|
|
222
|
-
|
|
223
|
-
// use math rendering (MathJax) to convert latex to mathMl
|
|
224
|
-
let mathMlFromLatex = renderMath(latexToConvert, {
|
|
225
|
-
skipWaitForMathRenderingLib: true,
|
|
226
|
-
});
|
|
227
|
-
|
|
228
|
-
// if renderMath returned the exact same string that we sent, it just means that the conversion could not be done
|
|
229
|
-
const conversionDidNotWork = isEqual(latexToConvert, mathMlFromLatex);
|
|
230
|
-
|
|
231
|
-
mathMlFromLatex = removeEmptyMos(mathMlFromLatex);
|
|
232
|
-
|
|
233
|
-
// we convert resulted mathml to latex to check if the resulted mathMl can be converted back to latex if user wants to edit it later
|
|
234
|
-
const latexFromMathMl = mathMlFromLatex ? mmlToLatex(mathMlFromLatex) : '';
|
|
235
|
-
|
|
236
|
-
// we need to remove all the spaces from the latex to be able to compare it
|
|
237
|
-
const strippedL = latex.replace(/\s/g, '');
|
|
238
|
-
const strippedNewL = latexFromMathMl.replace(/\s/g, '');
|
|
239
|
-
|
|
240
|
-
// we check if the latex keeps his form after being converted to mathml and back to latex
|
|
241
|
-
// if it does, we can safely convert it to mathml
|
|
242
|
-
if (!isEqual(strippedL, strippedNewL)) {
|
|
243
|
-
const correctedLatex = replaceLeftRight(latexFromMathMl);
|
|
244
|
-
|
|
245
|
-
// As George requested in PD-3167, I will set the new mathML anyway, and also log differences
|
|
246
|
-
// if it doesn't, we keep the latex version
|
|
247
|
-
// eslint-disable-next-line no-console
|
|
248
|
-
console.log('This latex can not be safely converted to mathml so we will keep the latex version!!!', {
|
|
249
|
-
initialLatex: latex,
|
|
250
|
-
newLatex: latexFromMathMl,
|
|
251
|
-
correctedLatex,
|
|
252
|
-
mathML: mathMlFromLatex,
|
|
253
|
-
conversionDidNotWork,
|
|
254
|
-
});
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
return { mathMlFromLatex, conversionDidNotWork };
|
|
258
|
-
};
|
|
259
|
-
|
|
260
|
-
const convertMathMlToLatex = (mathMl) => {
|
|
261
|
-
const htmlWithRemovedSpaces = mathMl.replaceAll(' ', ' ');
|
|
262
|
-
const htmlToUse = mmlToLatex(htmlWithRemovedSpaces);
|
|
263
|
-
const latex = htmlDecode(htmlToUse);
|
|
264
|
-
|
|
265
|
-
// todo fix this in mathml-to-latex
|
|
266
|
-
return replaceLeftRight(latex);
|
|
267
|
-
};
|
|
268
|
-
|
|
269
|
-
export const serialization = {
|
|
270
|
-
deserialize(el) {
|
|
271
|
-
const tagName = getTagName(el);
|
|
272
|
-
/**
|
|
273
|
-
* This is used for when there's a wrapper over the mathml element.
|
|
274
|
-
* Because of this slate rule: "Only allow block nodes or inline and text nodes in blocks."
|
|
275
|
-
* The element that contains only the mathml is removed (along with the math) because it has
|
|
276
|
-
* an inline child and the block is of type block
|
|
277
|
-
* This is for legacy content only since our math rendering is valid for the core slate rules
|
|
278
|
-
*/
|
|
279
|
-
const hasMathChild = BLOCK_TAGS[tagName] && el.childNodes.length === 1 && getTagName(el.firstChild) === 'math';
|
|
280
|
-
log('[deserialize] name: ', tagName);
|
|
281
|
-
|
|
282
|
-
/**
|
|
283
|
-
* This is here in order to be able to render mathml content
|
|
284
|
-
*/
|
|
285
|
-
if (tagName === 'math' || (el.dataset && el.dataset.type === 'mathml') || hasMathChild) {
|
|
286
|
-
const mathMl = hasMathChild ? el.innerHTML : el.outerHTML;
|
|
287
|
-
|
|
288
|
-
if (MathPlugin.mathMlOptions.mmlEditing) {
|
|
289
|
-
const { unwrapped, wrapType } = unWrapMath(convertMathMlToLatex(mathMl));
|
|
290
|
-
|
|
291
|
-
return {
|
|
292
|
-
object: 'inline',
|
|
293
|
-
type: 'math',
|
|
294
|
-
isVoid: true,
|
|
295
|
-
nodes: [],
|
|
296
|
-
data: {
|
|
297
|
-
latex: unwrapped,
|
|
298
|
-
wrapper: wrapType,
|
|
299
|
-
},
|
|
300
|
-
};
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
return {
|
|
304
|
-
object: 'inline',
|
|
305
|
-
isVoid: true,
|
|
306
|
-
type: 'mathml',
|
|
307
|
-
data: {
|
|
308
|
-
html: mathMl,
|
|
309
|
-
},
|
|
310
|
-
};
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
if (el.nodeType === TEXT_NODE) {
|
|
314
|
-
return;
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
if (tagName !== 'span') {
|
|
318
|
-
return;
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
const hasLatex = el.hasAttribute('data-latex') || el.hasAttribute('latex');
|
|
322
|
-
|
|
323
|
-
if (hasLatex) {
|
|
324
|
-
const latex = htmlDecode(el.innerHTML);
|
|
325
|
-
const { unwrapped, wrapType } = unWrapMath(latex);
|
|
326
|
-
log('[deserialize]: noBrackets: ', unwrapped, wrapType);
|
|
327
|
-
return {
|
|
328
|
-
object: 'inline',
|
|
329
|
-
type: 'math',
|
|
330
|
-
isVoid: true,
|
|
331
|
-
nodes: [],
|
|
332
|
-
data: {
|
|
333
|
-
latex: unwrapped,
|
|
334
|
-
wrapper: wrapType,
|
|
335
|
-
},
|
|
336
|
-
};
|
|
337
|
-
}
|
|
338
|
-
},
|
|
339
|
-
serialize(object) {
|
|
340
|
-
if (object.type === 'math') {
|
|
341
|
-
const latex = object.data.get('latex');
|
|
342
|
-
const wrapper = object.data.get('wrapper');
|
|
343
|
-
const decoded = htmlDecode(arrowHandlingCase(latex));
|
|
344
|
-
|
|
345
|
-
log('[serialize] latex: ', latex);
|
|
346
|
-
|
|
347
|
-
if (MathPlugin.mathMlOptions.mmlOutput) {
|
|
348
|
-
const { mathMlFromLatex, conversionDidNotWork } = convertLatexToMathMl({ latex, decoded, wrapper });
|
|
349
|
-
|
|
350
|
-
if (conversionDidNotWork) {
|
|
351
|
-
// this means we could not convert latex to mathMl, so just return the latex version,
|
|
352
|
-
// same as we would do if mmlOutput would not be enabled
|
|
353
|
-
return (
|
|
354
|
-
<span data-latex="" data-raw={decoded}>
|
|
355
|
-
{wrapMath(decoded, wrapper)}
|
|
356
|
-
</span>
|
|
357
|
-
);
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
return <span data-type="mathml" dangerouslySetInnerHTML={{ __html: mathMlFromLatex }} />;
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
return (
|
|
364
|
-
<span data-latex="" data-raw={decoded}>
|
|
365
|
-
{wrapMath(decoded, wrapper)}
|
|
366
|
-
</span>
|
|
367
|
-
);
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
/**
|
|
371
|
-
* Here for rendering mathml content
|
|
372
|
-
*/
|
|
373
|
-
if (object.type === 'mathml') {
|
|
374
|
-
const html = object.data.get('html');
|
|
375
|
-
|
|
376
|
-
return <span data-type="mathml" dangerouslySetInnerHTML={{ __html: html }} />;
|
|
377
|
-
}
|
|
378
|
-
},
|
|
379
|
-
};
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import MediaPlugin from '../';
|
|
2
|
-
|
|
3
|
-
describe('media plugin', () => {
|
|
4
|
-
const imagePlugin = MediaPlugin('video');
|
|
5
|
-
|
|
6
|
-
describe('normalizeNode', () => {
|
|
7
|
-
it('should exit the function if the node is not of type document', () => {
|
|
8
|
-
const returnValue = imagePlugin.normalizeNode({ object: 'image' });
|
|
9
|
-
|
|
10
|
-
expect(returnValue).toEqual(undefined);
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
it('should exit there are no changes needed', () => {
|
|
14
|
-
const nodes = [
|
|
15
|
-
{
|
|
16
|
-
object: 'text',
|
|
17
|
-
text: 'Before Media',
|
|
18
|
-
},
|
|
19
|
-
{
|
|
20
|
-
type: 'video',
|
|
21
|
-
},
|
|
22
|
-
{
|
|
23
|
-
object: 'text',
|
|
24
|
-
text: 'After Media',
|
|
25
|
-
},
|
|
26
|
-
];
|
|
27
|
-
const returnValue = imagePlugin.normalizeNode({
|
|
28
|
-
object: 'document',
|
|
29
|
-
findDescendant: jest.fn((callback) => {
|
|
30
|
-
nodes.forEach((n) => callback(n));
|
|
31
|
-
}),
|
|
32
|
-
});
|
|
33
|
-
expect(returnValue).toEqual(undefined);
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
it('should return a function if there is a node with an empty text before a media element', () => {
|
|
37
|
-
const nodes = [
|
|
38
|
-
{
|
|
39
|
-
object: 'text',
|
|
40
|
-
text: '',
|
|
41
|
-
key: '1',
|
|
42
|
-
},
|
|
43
|
-
{
|
|
44
|
-
type: 'video',
|
|
45
|
-
key: '2',
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
object: 'text',
|
|
49
|
-
text: 'After Media',
|
|
50
|
-
key: '3',
|
|
51
|
-
},
|
|
52
|
-
];
|
|
53
|
-
const findDescendant = jest.fn((callback) => {
|
|
54
|
-
nodes.forEach((n) => callback(n));
|
|
55
|
-
});
|
|
56
|
-
const change = {
|
|
57
|
-
withoutNormalization: jest.fn((callback) => {
|
|
58
|
-
callback();
|
|
59
|
-
}),
|
|
60
|
-
insertTextByKey: jest.fn(),
|
|
61
|
-
};
|
|
62
|
-
const returnValue = imagePlugin.normalizeNode({
|
|
63
|
-
object: 'document',
|
|
64
|
-
findDescendant,
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
expect(returnValue).toEqual(expect.any(Function));
|
|
68
|
-
|
|
69
|
-
returnValue(change);
|
|
70
|
-
|
|
71
|
-
expect(change.withoutNormalization).toHaveBeenCalledWith(expect.any(Function));
|
|
72
|
-
expect(change.insertTextByKey).toHaveBeenCalledWith('1', 0, ' ');
|
|
73
|
-
});
|
|
74
|
-
});
|
|
75
|
-
});
|