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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (165) hide show
  1. package/lib/components/CharacterPicker.js +221 -0
  2. package/lib/components/CharacterPicker.js.map +1 -0
  3. package/lib/components/EditableHtml.js +323 -0
  4. package/lib/components/EditableHtml.js.map +1 -0
  5. package/lib/components/MenuBar.js +694 -0
  6. package/lib/components/MenuBar.js.map +1 -0
  7. package/lib/components/TiptapContainer.js +90 -0
  8. package/lib/components/TiptapContainer.js.map +1 -0
  9. package/lib/components/buttons/done-button.js +53 -0
  10. package/lib/components/characters/characterUtils.js +112 -0
  11. package/lib/components/characters/characterUtils.js.map +1 -0
  12. package/lib/components/characters/custom-popper.js +73 -0
  13. package/lib/components/characters/custom-popper.js.map +1 -0
  14. package/lib/components/common/done-button.js +53 -0
  15. package/lib/components/common/done-button.js.map +1 -0
  16. package/lib/components/common/toolbar-buttons.js +194 -0
  17. package/lib/components/icons/CssIcon.js +37 -0
  18. package/lib/components/icons/CssIcon.js.map +1 -0
  19. package/lib/components/icons/RespArea.js +95 -0
  20. package/lib/components/icons/RespArea.js.map +1 -0
  21. package/lib/components/icons/TableIcons.js +69 -0
  22. package/lib/components/icons/TableIcons.js.map +1 -0
  23. package/lib/components/icons/TextAlign.js +194 -0
  24. package/lib/components/icons/TextAlign.js.map +1 -0
  25. package/lib/components/icons/index.js +194 -0
  26. package/lib/components/image/AltDialog.js +129 -0
  27. package/lib/components/image/ImageToolbar.js +177 -0
  28. package/lib/components/image/ImageToolbar.js.map +1 -0
  29. package/lib/components/image/InsertImageHandler.js +115 -0
  30. package/lib/components/image/InsertImageHandler.js.map +1 -0
  31. package/lib/components/image/alt-dialog.js +2 -0
  32. package/lib/components/media/MediaDialog.js +709 -0
  33. package/lib/components/media/MediaDialog.js.map +1 -0
  34. package/lib/components/media/MediaToolbar.js +101 -0
  35. package/lib/components/media/MediaToolbar.js.map +1 -0
  36. package/lib/components/media/MediaWrapper.js +93 -0
  37. package/lib/components/respArea/DragInTheBlank/DragInTheBlank.js +94 -0
  38. package/lib/components/respArea/DragInTheBlank/DragInTheBlank.js.map +1 -0
  39. package/lib/components/respArea/DragInTheBlank/choice.js +289 -0
  40. package/lib/components/respArea/DragInTheBlank/choice.js.map +1 -0
  41. package/lib/components/respArea/DragInTheBlank.js +94 -0
  42. package/lib/components/respArea/ExplicitConstructedResponse.js +120 -0
  43. package/lib/components/respArea/ExplicitConstructedResponse.js.map +1 -0
  44. package/lib/components/respArea/InlineDropdown.js +126 -0
  45. package/lib/components/respArea/InlineDropdown.js.map +1 -0
  46. package/lib/components/respArea/ToolbarIcon.js +105 -0
  47. package/lib/components/respArea/ToolbarIcon.js.map +1 -0
  48. package/lib/components/respArea/choice.js +2 -0
  49. package/lib/constants.js.map +1 -0
  50. package/lib/extensions/component.js +5 -5
  51. package/lib/extensions/component.js.map +1 -0
  52. package/lib/extensions/css.js.map +1 -0
  53. package/lib/extensions/custom-toolbar-wrapper.js +2 -4
  54. package/lib/extensions/custom-toolbar-wrapper.js.map +1 -0
  55. package/lib/extensions/extended-table.js +30 -0
  56. package/lib/extensions/extended-table.js.map +1 -0
  57. package/lib/extensions/image.js +2 -8
  58. package/lib/extensions/image.js.map +1 -0
  59. package/lib/extensions/index.js +52 -0
  60. package/lib/extensions/index.js.map +1 -0
  61. package/lib/extensions/math.js.map +1 -0
  62. package/lib/extensions/media.js +7 -7
  63. package/lib/extensions/media.js.map +1 -0
  64. package/lib/extensions/responseArea.js +7 -7
  65. package/lib/extensions/responseArea.js.map +1 -0
  66. package/lib/index.js +16 -1481
  67. package/lib/index.js.map +1 -0
  68. package/lib/plugins/index.js +8 -80
  69. package/lib/styles/editorContainerStyles.js +200 -0
  70. package/lib/styles/editorContainerStyles.js.map +1 -0
  71. package/lib/theme.js.map +1 -0
  72. package/lib/utils/size.js +34 -0
  73. package/lib/utils/size.js.map +1 -0
  74. package/package.json +1 -1
  75. package/src/components/CharacterPicker.jsx +185 -0
  76. package/src/components/EditableHtml.jsx +306 -0
  77. package/src/components/MenuBar.jsx +630 -0
  78. package/src/components/TiptapContainer.jsx +96 -0
  79. package/src/components/characters/characterUtils.js +127 -0
  80. package/src/{plugins/image/image-toolbar.jsx → components/image/ImageToolbar.jsx} +2 -2
  81. package/src/{plugins/image/insert-image-handler.js → components/image/InsertImageHandler.js} +0 -1
  82. package/src/{plugins/media/media-dialog.js → components/media/MediaDialog.js} +2 -2
  83. package/src/{plugins/respArea/drag-in-the-blank → components/respArea/DragInTheBlank}/choice.jsx +1 -1
  84. package/src/{plugins/respArea/inline-dropdown/index.jsx → components/respArea/InlineDropdown.jsx} +1 -1
  85. package/src/components/respArea/ToolbarIcon.jsx +68 -0
  86. package/src/extensions/component.jsx +2 -2
  87. package/src/extensions/custom-toolbar-wrapper.jsx +6 -7
  88. package/src/extensions/extended-table.js +27 -0
  89. package/src/extensions/image.js +2 -2
  90. package/src/extensions/index.js +76 -0
  91. package/src/extensions/media.js +12 -7
  92. package/src/extensions/responseArea.js +7 -7
  93. package/src/index.jsx +3 -1440
  94. package/src/styles/editorContainerStyles.js +203 -0
  95. package/src/utils/size.js +32 -0
  96. package/src/__tests__/editor.test.jsx +0 -363
  97. package/src/__tests__/serialization.test.js +0 -291
  98. package/src/block-tags.js +0 -17
  99. package/src/editor.jsx +0 -1197
  100. package/src/extensions/characters.js +0 -46
  101. package/src/old-index.jsx +0 -162
  102. package/src/parse-html.js +0 -8
  103. package/src/plugins/README.md +0 -27
  104. package/src/plugins/characters/index.jsx +0 -284
  105. package/src/plugins/characters/utils.js +0 -447
  106. package/src/plugins/css/index.jsx +0 -340
  107. package/src/plugins/customPlugin/index.jsx +0 -85
  108. package/src/plugins/html/icons/index.jsx +0 -19
  109. package/src/plugins/html/index.jsx +0 -72
  110. package/src/plugins/image/__tests__/__snapshots__/component.test.jsx.snap +0 -51
  111. package/src/plugins/image/__tests__/__snapshots__/image-toolbar-logic.test.jsx.snap +0 -27
  112. package/src/plugins/image/__tests__/__snapshots__/image-toolbar.test.jsx.snap +0 -44
  113. package/src/plugins/image/__tests__/component.test.jsx +0 -41
  114. package/src/plugins/image/__tests__/image-toolbar-logic.test.jsx +0 -42
  115. package/src/plugins/image/__tests__/image-toolbar.test.jsx +0 -11
  116. package/src/plugins/image/__tests__/index.test.js +0 -95
  117. package/src/plugins/image/__tests__/insert-image-handler.test.js +0 -113
  118. package/src/plugins/image/__tests__/mock-change.js +0 -15
  119. package/src/plugins/image/component.jsx +0 -343
  120. package/src/plugins/image/index.jsx +0 -227
  121. package/src/plugins/index.jsx +0 -377
  122. package/src/plugins/list/__tests__/index.test.js +0 -54
  123. package/src/plugins/list/index.jsx +0 -305
  124. package/src/plugins/math/__tests__/__snapshots__/index.test.jsx.snap +0 -48
  125. package/src/plugins/math/__tests__/index.test.jsx +0 -245
  126. package/src/plugins/math/index.jsx +0 -379
  127. package/src/plugins/media/__tests__/index.test.js +0 -75
  128. package/src/plugins/media/index.jsx +0 -325
  129. package/src/plugins/rendering/index.js +0 -31
  130. package/src/plugins/respArea/index.jsx +0 -299
  131. package/src/plugins/respArea/math-templated/index.jsx +0 -104
  132. package/src/plugins/respArea/utils.jsx +0 -90
  133. package/src/plugins/table/CustomTablePlugin.js +0 -113
  134. package/src/plugins/table/__tests__/__snapshots__/table-toolbar.test.jsx.snap +0 -44
  135. package/src/plugins/table/__tests__/index.test.jsx +0 -401
  136. package/src/plugins/table/__tests__/table-toolbar.test.jsx +0 -42
  137. package/src/plugins/table/index.jsx +0 -427
  138. package/src/plugins/table/table-toolbar.jsx +0 -136
  139. package/src/plugins/textAlign/index.jsx +0 -23
  140. package/src/plugins/toolbar/__tests__/__snapshots__/default-toolbar.test.jsx.snap +0 -923
  141. package/src/plugins/toolbar/__tests__/__snapshots__/editor-and-toolbar.test.jsx.snap +0 -20
  142. package/src/plugins/toolbar/__tests__/__snapshots__/toolbar-buttons.test.jsx.snap +0 -36
  143. package/src/plugins/toolbar/__tests__/__snapshots__/toolbar.test.jsx.snap +0 -46
  144. package/src/plugins/toolbar/__tests__/default-toolbar.test.jsx +0 -94
  145. package/src/plugins/toolbar/__tests__/editor-and-toolbar.test.jsx +0 -37
  146. package/src/plugins/toolbar/__tests__/toolbar-buttons.test.jsx +0 -51
  147. package/src/plugins/toolbar/__tests__/toolbar.test.jsx +0 -106
  148. package/src/plugins/toolbar/default-toolbar.jsx +0 -206
  149. package/src/plugins/toolbar/editor-and-toolbar.jsx +0 -257
  150. package/src/plugins/toolbar/index.jsx +0 -23
  151. package/src/plugins/toolbar/toolbar.jsx +0 -338
  152. package/src/plugins/utils.js +0 -31
  153. package/src/serialization.jsx +0 -621
  154. /package/src/{plugins → components}/characters/custom-popper.js +0 -0
  155. /package/src/{plugins/toolbar → components/common}/done-button.jsx +0 -0
  156. /package/src/{plugins/toolbar → components/common}/toolbar-buttons.jsx +0 -0
  157. /package/src/{plugins/css/icons/index.jsx → components/icons/CssIcon.jsx} +0 -0
  158. /package/src/{plugins/respArea/icons/index.jsx → components/icons/RespArea.jsx} +0 -0
  159. /package/src/{plugins/table/icons/index.jsx → components/icons/TableIcons.jsx} +0 -0
  160. /package/src/{plugins/textAlign/icons/index.jsx → components/icons/TextAlign.jsx} +0 -0
  161. /package/src/{plugins/image/alt-dialog.jsx → components/image/AltDialog.jsx} +0 -0
  162. /package/src/{plugins/media/media-toolbar.jsx → components/media/MediaToolbar.jsx} +0 -0
  163. /package/src/{plugins/media/media-wrapper.jsx → components/media/MediaWrapper.jsx} +0 -0
  164. /package/src/{plugins/respArea/drag-in-the-blank/index.jsx → components/respArea/DragInTheBlank/DragInTheBlank.jsx} +0 -0
  165. /package/src/{plugins/respArea/explicit-constructed-response/index.jsx → components/respArea/ExplicitConstructedResponse.jsx} +0 -0
@@ -1,340 +0,0 @@
1
- import React from 'react';
2
- import ReactDOM from 'react-dom';
3
- import List from '@material-ui/core/List';
4
- import { Leaf, Mark } from 'slate';
5
- import Immutable from 'immutable';
6
- import ListItem from '@material-ui/core/ListItem';
7
- import isEmpty from 'lodash/isEmpty';
8
- import debug from 'debug';
9
- import CssIcon from './icons';
10
-
11
- const log = debug('@pie-lib:editable-html:plugins:characters');
12
-
13
- export const removeDialogs = () => {
14
- const prevDialogs = document.querySelectorAll('.insert-css-dialog');
15
-
16
- log('[characters:removeDialogs]');
17
- prevDialogs.forEach((s) => s.remove());
18
- };
19
-
20
- const insertDialog = ({ editorDOM, value, callback, opts, textNode, parentNode }) => {
21
- const newEl = document.createElement('div');
22
-
23
- log('[characters:insertDialog]');
24
-
25
- removeDialogs();
26
-
27
- newEl.className = 'insert-css-dialog';
28
-
29
- let popoverEl;
30
-
31
- const closePopOver = () => {
32
- if (popoverEl) {
33
- popoverEl.remove();
34
- }
35
- };
36
-
37
- let firstCallMade = false;
38
-
39
- const listener = (e) => {
40
- // this will be triggered right after setting it because
41
- // this toolbar is added on the mousedown event
42
- // so right after mouseup, the click will be triggered
43
- if (firstCallMade) {
44
- const focusIsInModals = newEl.contains(e.target) || (popoverEl && popoverEl.contains(e.target));
45
- const focusIsInEditor = editorDOM.contains(e.target);
46
-
47
- if (!(focusIsInModals || focusIsInEditor)) {
48
- handleClose();
49
- }
50
- } else {
51
- firstCallMade = true;
52
- }
53
- };
54
-
55
- const handleClose = () => {
56
- callback(undefined, true);
57
- newEl.remove();
58
- closePopOver();
59
- document.body.removeEventListener('click', listener);
60
- };
61
-
62
- const handleChange = (name) => {
63
- callback(name, true);
64
- newEl.remove();
65
- closePopOver();
66
- document.body.removeEventListener('click', listener);
67
- };
68
-
69
- const selectedText = textNode.text.slice(value.selection.anchorOffset, value.selection.focusOffset);
70
- const parentNodeClass = parentNode?.data?.get('attributes')?.class;
71
- const createHTML = (name) => {
72
- let html = `<span class="${name}">${selectedText}</span>`;
73
-
74
- if (parentNode) {
75
- let tag;
76
-
77
- if (parentNode?.object === 'inline') {
78
- tag = 'span';
79
- }
80
-
81
- if (parentNode?.object === 'block') {
82
- tag = 'div';
83
- }
84
-
85
- html = `<${tag} class="${parentNodeClass}">${parentNode.text.slice(
86
- 0,
87
- value.selection.anchorOffset,
88
- )}${html}${parentNode.text.slice(value.selection.focusOffset)}</${tag}>`;
89
- }
90
-
91
- return html;
92
- };
93
-
94
- const el = (
95
- <div
96
- style={{ background: 'white', height: 500, padding: 20, overflow: 'hidden', display: 'flex', flexFlow: 'column' }}
97
- >
98
- <h2>Please choose a css class</h2>
99
- {parentNodeClass && <div>The current parent has this class {parentNodeClass}</div>}
100
- <List component="nav" style={{ overflow: 'scroll' }}>
101
- {opts.names.map((name, i) => (
102
- <ListItem key={`rule-${i}`} button onClick={() => handleChange(name)}>
103
- <div style={{ marginRight: 20 }}>{name}</div>
104
- <div
105
- dangerouslySetInnerHTML={{
106
- __html: createHTML(name),
107
- }}
108
- />
109
- </ListItem>
110
- ))}
111
- </List>
112
- </div>
113
- );
114
-
115
- ReactDOM.render(el, newEl, () => {
116
- const cursorItem = document.querySelector(`[data-key="${value.anchorKey}"]`);
117
-
118
- if (cursorItem) {
119
- const bodyRect = editorDOM.parentElement.parentElement.parentElement.getBoundingClientRect();
120
- const boundRect = cursorItem.getBoundingClientRect();
121
-
122
- editorDOM.parentElement.parentElement.parentElement.appendChild(newEl);
123
-
124
- newEl.style.maxWidth = '500px';
125
- newEl.style.position = 'absolute';
126
- newEl.style.top = 0;
127
- newEl.style.zIndex = 99999;
128
-
129
- const leftValue = `${boundRect.left + Math.abs(bodyRect.left) + cursorItem.offsetWidth + 10}px`;
130
-
131
- const rightValue = `${boundRect.x}px`;
132
-
133
- newEl.style.left = leftValue;
134
-
135
- const leftAlignedWidth = newEl.offsetWidth;
136
-
137
- newEl.style.left = 'unset';
138
- newEl.style.right = rightValue;
139
-
140
- const rightAlignedWidth = newEl.offsetWidth;
141
-
142
- newEl.style.left = 'unset';
143
- newEl.style.right = 'unset';
144
-
145
- if (leftAlignedWidth >= rightAlignedWidth) {
146
- newEl.style.left = leftValue;
147
- } else {
148
- newEl.style.right = rightValue;
149
- }
150
-
151
- document.body.addEventListener('click', listener);
152
- }
153
- });
154
- };
155
-
156
- const findParentNodeInfo = (value, textNode) => {
157
- const closestInline = value.document.getClosestInline(value.selection.endKey);
158
- const closestBlock = value.document.getClosestBlock(value.selection.endKey);
159
- let nodeToUse = null;
160
-
161
- if (closestInline?.nodes?.find((n) => n.key === textNode.key)) {
162
- nodeToUse = closestInline;
163
- }
164
-
165
- if (closestBlock?.nodes?.find((n) => n.key === textNode.key)) {
166
- nodeToUse = closestBlock;
167
- }
168
-
169
- return nodeToUse;
170
- };
171
-
172
- /**
173
- * Find the node that has a class attribute and return it.
174
- * Keeping this in case the implementation of classes needs to be changed
175
- * @param value
176
- * @param opts
177
- * @returns {*}
178
- */
179
- const getNodeWithClass = (value, opts) => {
180
- const blocksAtRange = value.document.getBlocksAtRangeAsArray(value.selection);
181
- const inlinesAtRange = value.document.getInlinesAtRangeAsArray(value.selection);
182
- const blockData = blocksAtRange[0]?.data.toJSON() || {};
183
- const inlineData = inlinesAtRange[0]?.data.toJSON() || {};
184
-
185
- if (!blockData.attributes?.class && !inlineData.attributes?.class) {
186
- return null;
187
- }
188
-
189
- const { class: blockClass } = blockData.attributes || {};
190
- const { class: inlineClass } = inlineData.attributes || {};
191
- const inlineHasClass = opts.names.find((name) => inlineClass.includes(name));
192
-
193
- if (inlineHasClass) {
194
- return inlinesAtRange[0];
195
- }
196
-
197
- const blockHasClass = opts.names.find((name) => blockClass.includes(name));
198
-
199
- if (blockHasClass) {
200
- return blocksAtRange[0];
201
- }
202
-
203
- return null;
204
- };
205
-
206
- /**
207
- * Plugin in order to be able to add a css clas that is provided through the model
208
- * on a text element. Works like a mark (bold, italic etc.).
209
- * @param opts
210
- * @constructor
211
- */
212
- export default function CSSPlugin(opts) {
213
- const plugin = {
214
- name: 'extraCSSRules',
215
- toolbar: {
216
- isMark: true,
217
- icon: <CssIcon />,
218
- ariaLabel: 'CSS editor',
219
- type: 'css',
220
- onToggle: (change) => {
221
- const type = 'css';
222
- const hasMark = change.value.activeMarks.find((entry) => {
223
- return entry.type === type;
224
- });
225
-
226
- if (hasMark) {
227
- change.removeMark(hasMark);
228
- } else {
229
- const newMark = Mark.create(type);
230
-
231
- change.addMark(newMark);
232
- }
233
-
234
- return change;
235
- },
236
- onClick: (value, onChange, getFocusedValue) => {
237
- const type = 'css';
238
- const hasMark = value.activeMarks.find((entry) => {
239
- return entry.type === type;
240
- });
241
-
242
- let change = value.change();
243
-
244
- if (hasMark) {
245
- change.removeMark(hasMark);
246
- onChange(change);
247
- return;
248
- }
249
-
250
- // keeping this if implementation needs to be changed to regular blocks instead of marks
251
- // let nodeWithClass = getNodeWithClass(value, opts);
252
- //
253
- // if (nodeWithClass) {
254
- // const nodeAttributes = nodeWithClass.data.get('attributes');
255
- //
256
- // opts.names.forEach((name) => {
257
- // if (nodeAttributes.class.includes(name)) {
258
- // nodeAttributes.class = nodeAttributes.class.replace(name, '');
259
- // }
260
- // });
261
- //
262
- // // keeping only one space between classes
263
- // nodeAttributes.class = nodeAttributes.class.replace(/ +/g, ' ');
264
- //
265
- // nodeWithClass.data.set('attributes', nodeAttributes);
266
- //
267
- // let change = value.change();
268
- // change.replaceNodeByKey(nodeWithClass.key, nodeWithClass);
269
- //
270
- // onChange(change);
271
- // return;
272
- // }
273
-
274
- const editorDOM = document.querySelector(`[data-key="${value.document.key}"]`);
275
- let valueToUse = value;
276
-
277
- const callback = (className, focus) => {
278
- if (getFocusedValue) {
279
- valueToUse = getFocusedValue() || valueToUse;
280
- }
281
-
282
- if (className) {
283
- let change = valueToUse.change();
284
-
285
- const newMark = Mark.create({
286
- object: 'mark',
287
- type: 'css',
288
- data: {
289
- attributes: {
290
- class: className,
291
- },
292
- },
293
- });
294
-
295
- change.addMark(newMark);
296
- // keeping this if implementation needs to be changed to regular blocks instead of marks
297
- // change = change.wrapInline({ type: 'span', data: { attributes: { class: className } } });
298
- //
299
- // // change = change.splitBlockAtRange(adaptedRange);
300
- // //
301
- // // const newBlock = change.value.document.getFurthestBlock(change.value.selection.endKey);
302
- // //
303
- // // change = change.setNodeByKey(newBlock.key, { data: { attributes: { class: className } } });
304
- //
305
- // valueToUse = change.value;
306
- // log('[characters:insert]: ', value);
307
- onChange(change);
308
- }
309
-
310
- log('[characters:click]');
311
-
312
- if (focus) {
313
- setTimeout(() => {
314
- if (editorDOM) {
315
- editorDOM.focus();
316
- }
317
- }, 0);
318
- }
319
- };
320
- const textNode = value.document.getTextsAtRangeAsArray(value.selection)[0];
321
-
322
- if (textNode) {
323
- const parentNode = findParentNodeInfo(value, textNode, opts);
324
-
325
- insertDialog({ editorDOM, value: valueToUse, callback, opts, textNode, parentNode });
326
- }
327
- },
328
- },
329
- renderMark(props) {
330
- if (props.mark.type === 'css') {
331
- const { data } = props.mark || {};
332
- const jsonData = data?.toJSON() || {};
333
-
334
- return <span {...jsonData.attributes}>{props.children}</span>;
335
- }
336
- },
337
- };
338
-
339
- return plugin;
340
- }
@@ -1,85 +0,0 @@
1
- import React from 'react';
2
- import { htmlToValue } from '../../serialization';
3
-
4
- // We're possibly going to have to support content types, so starting it as an enum
5
- export const CONTENT_TYPE = {
6
- FRAGMENT: 'FRAGMENT',
7
- };
8
-
9
- // We're possibly going to have to support multiple icon types, so starting it as an enum
10
- export const ICON_TYPE = {
11
- SVG: 'SVG',
12
- };
13
-
14
- const getIcon = (customPluginProps) => {
15
- const svg = customPluginProps.icon;
16
-
17
- switch (customPluginProps.iconType) {
18
- case ICON_TYPE.SVG:
19
- return <span style={{ width: 28, height: 28 }} dangerouslySetInnerHTML={{ __html: svg }} />;
20
- default:
21
- return <span>{customPluginProps.iconAlt}</span>;
22
- }
23
- };
24
-
25
- export default function CustomPlugin(type, customPluginProps) {
26
- const toolbar = {
27
- icon: getIcon(customPluginProps),
28
- onClick: (value, onChange, getFocusedValue) => {
29
- const editorDOM = document.querySelector(`[data-key="${value.document.key}"]`);
30
- let valueToUse = value;
31
- const callback = ({ customContent, contentType }, focus) => {
32
- valueToUse = getFocusedValue();
33
-
34
- switch (contentType) {
35
- case CONTENT_TYPE.FRAGMENT:
36
- default: {
37
- const contentValue = htmlToValue(customContent);
38
- const change = valueToUse.change().insertFragment(contentValue.document);
39
-
40
- valueToUse = change.value;
41
- onChange(change);
42
-
43
- break;
44
- }
45
- }
46
-
47
- if (focus) {
48
- if (editorDOM) {
49
- editorDOM.focus();
50
- }
51
- }
52
- };
53
-
54
- // NOTE: the emitted event (custom event named by client) will be suffixed with "PIE-"
55
- window.dispatchEvent(
56
- new CustomEvent(`PIE-${customPluginProps.event}`, {
57
- detail: {
58
- ...customPluginProps,
59
- callback,
60
- },
61
- }),
62
- );
63
- },
64
- supports: (node) => node.object === 'inline' && node.type === type,
65
- };
66
-
67
- return {
68
- name: type,
69
- toolbar,
70
- renderNode(props) {
71
- if (props.node.type === type) {
72
- const { node } = props;
73
- const { data } = node;
74
- const jsonData = data.toJSON();
75
- const { customContent, contentType } = jsonData;
76
-
77
- switch (contentType) {
78
- case CONTENT_TYPE.FRAGMENT:
79
- default:
80
- return customContent;
81
- }
82
- }
83
- },
84
- };
85
- }
@@ -1,19 +0,0 @@
1
- import React from 'react';
2
- import { withStyles } from '@material-ui/core/styles';
3
-
4
- const styles = (theme) => ({
5
- icon: {
6
- fontFamily: 'Cerebri Sans, Arial, sans-serif',
7
- fontSize: theme.typography.fontSize,
8
- fontWeight: 'bold',
9
- lineHeight: '14px',
10
- position: 'relative',
11
- whiteSpace: 'nowrap',
12
- },
13
- });
14
-
15
- const HtmlModeIcon = ({ classes, isHtmlMode }) => (
16
- <div className={classes.icon}>{isHtmlMode ? 'Exit <HTML> mode' : '<HTML>'}</div>
17
- );
18
-
19
- export default withStyles(styles)(HtmlModeIcon);
@@ -1,72 +0,0 @@
1
- import React from 'react';
2
- import HtmlModeIcon from './icons';
3
- import { htmlToValue, valueToHtml } from './../../serialization';
4
-
5
- const toggleToRichText = (value, onChange, dismiss) => {
6
- const plainText = value.document.text;
7
- const slateValue = dismiss ? value : htmlToValue(plainText);
8
-
9
- const change = value
10
- .change()
11
- .selectAll()
12
- .delete()
13
- .insertFragment(slateValue.document);
14
- onChange(change);
15
- };
16
-
17
- export default function HtmlPlugin(opts) {
18
- const { isHtmlMode, isEditedInHtmlMode, toggleHtmlMode, handleAlertDialog, currentValue } = opts || {};
19
-
20
- const handleHtmlModeOn = (value, onChange) => {
21
- const dialogProps = {
22
- title: 'Warning',
23
- text: 'Returning to rich text mode without saving will cause edits to be lost.',
24
- onConfirmText: 'Dismiss changes',
25
- onCloseText: 'Continue Editing',
26
- onConfirm: () => {
27
- handleAlertDialog(false);
28
- toggleToRichText(currentValue, onChange, true);
29
- toggleHtmlMode();
30
- },
31
- onClose: () => {
32
- handleAlertDialog(false);
33
- },
34
- };
35
-
36
- handleAlertDialog(true, dialogProps);
37
- };
38
-
39
- const handleHtmlModeOff = (value, onChange) => {
40
- const change = value
41
- .change()
42
- .selectAll()
43
- .delete()
44
- .insertText(valueToHtml(value));
45
- onChange(change);
46
- };
47
-
48
- return {
49
- name: 'html',
50
- toolbar: {
51
- icon: <HtmlModeIcon isHtmlMode={isHtmlMode} />,
52
- ariaLabel: 'Html editor',
53
- buttonStyles: {
54
- margin: '0 20px 0 auto',
55
- },
56
- type: 'html',
57
- onClick: (value, onChange) => {
58
- if (isHtmlMode) {
59
- if (isEditedInHtmlMode) {
60
- handleHtmlModeOn(value, onChange);
61
- } else {
62
- toggleToRichText(value, onChange);
63
- toggleHtmlMode();
64
- }
65
- } else {
66
- handleHtmlModeOff(value, onChange);
67
- toggleHtmlMode();
68
- }
69
- },
70
- },
71
- };
72
- }
@@ -1,51 +0,0 @@
1
- // Jest Snapshot v1, https://goo.gl/fbAQLP
2
-
3
- exports[`renders correctly 1`] = `
4
- Array [
5
- <span>
6
-  
7
- </span>,
8
- <div
9
- className=""
10
- style={
11
- Object {
12
- "justifyContent": "flex-start",
13
- }
14
- }
15
- >
16
- <div
17
- className="MuiLinearProgress-root-1 MuiLinearProgress-colorPrimary-2 MuiLinearProgress-indeterminate-5"
18
- mode="determinate"
19
- role="progressbar"
20
- >
21
- <div
22
- className="MuiLinearProgress-bar-11 MuiLinearProgress-barColorPrimary-12 MuiLinearProgress-bar1Indeterminate-14"
23
- style={Object {}}
24
- />
25
- <div
26
- className="MuiLinearProgress-bar-11 MuiLinearProgress-barColorPrimary-12 MuiLinearProgress-bar2Indeterminate-17"
27
- style={Object {}}
28
- />
29
- </div>
30
- <div>
31
- <img
32
- className=""
33
- onLoad={[Function]}
34
- style={
35
- Object {
36
- "height": "50px",
37
- "objectFit": "contain",
38
- "width": "50px",
39
- }
40
- }
41
- />
42
- <div
43
- className="resize"
44
- />
45
- </div>
46
- </div>,
47
- <span>
48
-  
49
- </span>,
50
- ]
51
- `;
@@ -1,27 +0,0 @@
1
- // Jest Snapshot v1, https://goo.gl/fbAQLP
2
-
3
- exports[`ImageToolbar onChange renders 1`] = `
4
- <div>
5
- <AlignmentButton
6
- active={false}
7
- alignment="left"
8
- onClick={[Function]}
9
- />
10
- <AlignmentButton
11
- active={false}
12
- alignment="center"
13
- onClick={[Function]}
14
- />
15
- <AlignmentButton
16
- active={false}
17
- alignment="right"
18
- onClick={[Function]}
19
- />
20
- <span
21
- className="undefined"
22
- onMouseDown={[Function]}
23
- >
24
- Alt text
25
- </span>
26
- </div>
27
- `;
@@ -1,44 +0,0 @@
1
- // Jest Snapshot v1, https://goo.gl/fbAQLP
2
-
3
- exports[`renders correctly 1`] = `
4
- <div
5
- className="ImageToolbar-holder-1 holder"
6
- >
7
- <button
8
- aria-label="left"
9
- aria-pressed={false}
10
- className="RawMarkButton-button-4"
11
- onKeyDown={[Function]}
12
- onMouseDown={[Function]}
13
- tabIndex={0}
14
- >
15
- left
16
- </button>
17
- <button
18
- aria-label="center"
19
- aria-pressed={false}
20
- className="RawMarkButton-button-4"
21
- onKeyDown={[Function]}
22
- onMouseDown={[Function]}
23
- tabIndex={0}
24
- >
25
- center
26
- </button>
27
- <button
28
- aria-label="right"
29
- aria-pressed={false}
30
- className="RawMarkButton-button-4"
31
- onKeyDown={[Function]}
32
- onMouseDown={[Function]}
33
- tabIndex={0}
34
- >
35
- right
36
- </button>
37
- <span
38
- className="ImageToolbar-disabled-2 ImageToolbar-altButton-3"
39
- onMouseDown={[Function]}
40
- >
41
- Alt text
42
- </span>
43
- </div>
44
- `;
@@ -1,41 +0,0 @@
1
- import { Data, Block } from 'slate';
2
- import { Component } from '../component';
3
- import React from 'react';
4
- import renderer from 'react-test-renderer';
5
-
6
- it('renders correctly', () => {
7
- const node = Block.fromJSON({
8
- type: 'image',
9
- data: Data.create({
10
- width: 50,
11
- height: 50,
12
- }),
13
- });
14
-
15
- const editor = {
16
- value: {},
17
- change: jest.fn(),
18
- };
19
-
20
- const onDelete = jest.fn();
21
-
22
- const classes = {
23
- active: 'active',
24
- loading: 'loading',
25
- pendingDelete: 'pendingDelete',
26
- };
27
-
28
- const tree = renderer
29
- .create(<Component node={node} editor={editor} classes={classes} onDelete={onDelete} />, {
30
- createNodeMock: (el) => {
31
- if (el.type === 'img') {
32
- return {
33
- naturalWidth: 100,
34
- naturalHeight: 100,
35
- };
36
- }
37
- },
38
- })
39
- .toJSON();
40
- expect(tree).toMatchSnapshot();
41
- });