@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,42 +0,0 @@
1
- import { configure, shallow } from 'enzyme';
2
-
3
- import { Data, Block, Value } from 'slate';
4
- import { ImageToolbar } from '../image-toolbar';
5
- import MockChange from './mock-change';
6
- import React from 'react';
7
-
8
- describe('ImageToolbar', () => {
9
- let onChange;
10
-
11
- beforeEach(() => {
12
- onChange = jest.fn();
13
- });
14
-
15
- const mkWrapper = (extras) => {
16
- const props = {
17
- onChange,
18
- classes: {},
19
- ...extras,
20
- };
21
-
22
- return shallow(<ImageToolbar {...props} />);
23
- };
24
-
25
- describe('onChange', () => {
26
- it('renders', function() {
27
- return expect(mkWrapper()).toMatchSnapshot();
28
- });
29
-
30
- it('calls onChange with alignment', () => {
31
- const w = mkWrapper();
32
- w.instance().onAlignmentClick('center');
33
- expect(onChange).toHaveBeenCalledWith({ alignment: 'center' });
34
- });
35
-
36
- it('calls onChange with alt text', () => {
37
- const w = mkWrapper();
38
- w.instance().onAltTextDone('alt text');
39
- expect(onChange).toHaveBeenCalledWith({ alt: 'alt text' }, true);
40
- });
41
- });
42
- });
@@ -1,11 +0,0 @@
1
- import React from 'react';
2
- import Toolbar from '../image-toolbar';
3
- import renderer from 'react-test-renderer';
4
- import { Data, Block, Value } from 'slate';
5
-
6
- it('renders correctly', () => {
7
- const classes = { holder: 'holder' };
8
-
9
- const tree = renderer.create(<Toolbar percent={50} classes={classes} onChange={jest.fn()} />).toJSON();
10
- expect(tree).toMatchSnapshot();
11
- });
@@ -1,95 +0,0 @@
1
- import MockChange, { MockDocument } from './mock-change';
2
-
3
- import { Data } from 'slate';
4
- import ImageToolbar from '../';
5
-
6
- describe('image plugin', () => {
7
- let value = {};
8
-
9
- const imageSupport = {
10
- delete: jest.fn(),
11
- add: jest.fn(),
12
- };
13
-
14
- const imagePlugin = ImageToolbar({
15
- onDelete: (src, done) => {
16
- imageSupport.delete(src, (e) => {
17
- done(e, value);
18
- });
19
- },
20
- insertImageRequested: (node, getHandler) => {
21
- const handler = getHandler(() => value);
22
- imageSupport.add(handler);
23
- },
24
- });
25
-
26
- describe('normalizeNode', () => {
27
- it('should exit the function if the node is not of type document', () => {
28
- const returnValue = imagePlugin.normalizeNode({ object: 'image' });
29
-
30
- expect(returnValue).toEqual(undefined);
31
- });
32
-
33
- it('should exit if the function if there are no changes needed', () => {
34
- const nodes = [
35
- {
36
- object: 'text',
37
- text: 'Before Image',
38
- },
39
- {
40
- type: 'image',
41
- },
42
- {
43
- object: 'text',
44
- text: 'After Image',
45
- },
46
- ];
47
- const returnValue = imagePlugin.normalizeNode({
48
- object: 'document',
49
- findDescendant: jest.fn((callback) => {
50
- nodes.forEach((n) => callback(n));
51
- }),
52
- });
53
- expect(returnValue).toEqual(undefined);
54
- });
55
-
56
- it('should return a function if there is a node with an empty text before an image', () => {
57
- const nodes = [
58
- {
59
- object: 'text',
60
- text: '',
61
- key: '1',
62
- },
63
- {
64
- type: 'image',
65
- key: '2',
66
- },
67
- {
68
- object: 'text',
69
- text: 'After Image',
70
- key: '3',
71
- },
72
- ];
73
- const findDescendant = jest.fn((callback) => {
74
- nodes.forEach((n) => callback(n));
75
- });
76
- const change = {
77
- withoutNormalization: jest.fn((callback) => {
78
- callback();
79
- }),
80
- insertTextByKey: jest.fn(),
81
- };
82
- const returnValue = imagePlugin.normalizeNode({
83
- object: 'document',
84
- findDescendant,
85
- });
86
-
87
- expect(returnValue).toEqual(expect.any(Function));
88
-
89
- returnValue(change);
90
-
91
- expect(change.withoutNormalization).toHaveBeenCalledWith(expect.any(Function));
92
- expect(change.insertTextByKey).toHaveBeenCalledWith('1', 0, ' ');
93
- });
94
- });
95
- });
@@ -1,113 +0,0 @@
1
- import MockChange, { MockDocument } from './mock-change';
2
-
3
- import { Data } from 'slate';
4
- import InsertImageHandler from '../insert-image-handler';
5
-
6
- expect.extend({
7
- toMatchData: (received, argument) => {
8
- const argData = Data.create(argument);
9
- const pass = argData.equals(received.data);
10
- if (pass) {
11
- return {
12
- message: () => `expected ${received.toJSON()} not to be divisible by ${argData.toJSON()}`,
13
- pass: true,
14
- };
15
- } else {
16
- return {
17
- message: () => `expected ${received.toJSON()} to be divisible by ${argData.toJSON()}`,
18
- pass: false,
19
- };
20
- }
21
- },
22
- });
23
- describe('insert image handler', () => {
24
- let change, document, value;
25
- beforeEach(() => {
26
- document = new MockDocument();
27
- change = new MockChange();
28
- value = {
29
- change: () => change,
30
- document,
31
- };
32
- });
33
-
34
- const block = { key: 1 };
35
- const onChange = jest.fn();
36
-
37
- const handler = new InsertImageHandler(
38
- block,
39
- () => {},
40
- () => value,
41
- onChange,
42
- );
43
-
44
- test('it constructs', () => {
45
- expect(handler).not.toEqual(undefined);
46
- });
47
-
48
- describe('fileChosen', () => {
49
- let fileReader;
50
- beforeEach(() => {
51
- fileReader = {
52
- readAsDataURL: jest.fn(),
53
- };
54
-
55
- global.FileReader = () => fileReader;
56
- handler.fileChosen({});
57
- });
58
-
59
- test('calls readAsDataURL', () => {
60
- expect(fileReader.readAsDataURL).toBeCalledWith({});
61
- });
62
-
63
- test('calls onChange with src -> dataUrl', () => {
64
- fileReader.result = 'dataURL';
65
- fileReader.onload();
66
- expect(change.setNodeByKey).toBeCalledWith(block.key, expect.anything());
67
- expect(change.setNodeByKey.mock.calls[0][1]).toMatchData({
68
- src: 'dataURL',
69
- });
70
- expect(onChange).toBeCalledWith(change);
71
- });
72
- });
73
-
74
- describe('progress', () => {
75
- test('calls change w/ percent', () => {
76
- handler.progress(40, 40, 100);
77
- expect(change.setNodeByKey).toBeCalledWith(block.key, expect.anything());
78
-
79
- expect(change.setNodeByKey.mock.calls[0][1].data.toJS()).toMatchObject({
80
- percent: 40,
81
- });
82
- });
83
- });
84
-
85
- describe('done', () => {
86
- test('calls setNodeByKey', () => {
87
- handler.done(null, 'src');
88
-
89
- expect(change.setNodeByKey).toBeCalledWith(block.key, expect.anything());
90
-
91
- expect(change.setNodeByKey.mock.calls[0][1].data.toJS()).toMatchObject({
92
- src: 'src',
93
- loaded: true,
94
- percent: 100,
95
- });
96
- });
97
- });
98
-
99
- describe('cancel', () => {
100
- beforeEach(() => {
101
- document.getChild = jest.fn().mockReturnValue({ data: Data.create({}), key: block.key });
102
- handler.cancel();
103
- });
104
-
105
- test('calls onChange', () => {
106
- expect(onChange).toBeCalled();
107
- });
108
-
109
- test('calls removeNodeByKey', () => {
110
- expect(change.removeNodeByKey).toBeCalledWith(block.key);
111
- });
112
- });
113
- });
@@ -1,15 +0,0 @@
1
- import { Data } from 'slate';
2
-
3
- export default function MockChange() {
4
- this.setNodeByKey = jest.fn().mockReturnValue(this);
5
- this.removeNodeByKey = jest.fn().mockReturnValue(this);
6
- this.insertInline = jest.fn().mockReturnValue(this);
7
- this.moveFocusTo = jest.fn().mockReturnValue(this);
8
- this.moveAnchorTo = jest.fn().mockReturnValue(this);
9
- }
10
-
11
- export function MockDocument() {
12
- this.getChild = jest.fn().mockReturnValue({ data: Data.create({}) });
13
-
14
- this.getDescendant = jest.fn();
15
- }
@@ -1,343 +0,0 @@
1
- import LinearProgress from '@material-ui/core/LinearProgress';
2
- import PropTypes from 'prop-types';
3
- import React from 'react';
4
- import classNames from 'classnames';
5
- import debug from 'debug';
6
- import { withStyles } from '@material-ui/core/styles';
7
- import SlatePropTypes from 'slate-prop-types';
8
-
9
- const log = debug('@pie-lib:editable-html:plugins:image:component');
10
-
11
- const size = (s) => (s ? `${s}px` : 'auto');
12
-
13
- export class Component extends React.Component {
14
- static propTypes = {
15
- node: SlatePropTypes.node.isRequired,
16
- editor: PropTypes.shape({
17
- change: PropTypes.func.isRequired,
18
- value: PropTypes.object,
19
- }).isRequired,
20
- classes: PropTypes.object.isRequired,
21
- attributes: PropTypes.object,
22
- onFocus: PropTypes.func,
23
- onBlur: PropTypes.func,
24
- maxImageWidth: PropTypes.number,
25
- maxImageHeight: PropTypes.number,
26
- };
27
-
28
- getWidth = (percent) => {
29
- const multiplier = percent / 100;
30
- return this.img.naturalWidth * multiplier;
31
- };
32
-
33
- getHeight = (percent) => {
34
- const multiplier = percent / 100;
35
- return this.img.naturalHeight * multiplier;
36
- };
37
-
38
- getPercentFromWidth = (width) => {
39
- var floored = (width / this.img.naturalWidth) * 4;
40
- return parseInt(floored.toFixed(0) * 25, 10);
41
- };
42
-
43
- applySizeData = () => {
44
- const { node, editor } = this.props;
45
-
46
- let update = node.data;
47
-
48
- const w = update.get('width');
49
- if (w) {
50
- update = update.set('resizePercent', this.getPercentFromWidth(w));
51
- }
52
-
53
- log('[applySizeData] update: ', update);
54
-
55
- if (!update.equals(node.data)) {
56
- editor.change((c) => c.setNodeByKey(node.key, { data: update }));
57
- }
58
- };
59
-
60
- initialiseResize = () => {
61
- window.addEventListener('mousemove', this.startResizing, false);
62
- window.addEventListener('mouseup', this.stopResizing, false);
63
- };
64
-
65
- componentDidMount() {
66
- this.applySizeData();
67
-
68
- const resizeHandle = this.resize;
69
-
70
- if (resizeHandle) {
71
- resizeHandle.addEventListener('mousedown', this.initialiseResize, false);
72
- }
73
- }
74
-
75
- componentDidUpdate() {
76
- this.applySizeData();
77
- }
78
-
79
- getSize(data) {
80
- return {
81
- width: size(data.get('width')),
82
- height: size(data.get('height')),
83
- objectFit: 'contain',
84
- };
85
- }
86
-
87
- loadImage = () => {
88
- let { maxImageWidth, maxImageHeight } = this.props || {};
89
- maxImageWidth = maxImageWidth || 700;
90
- maxImageHeight = maxImageHeight || 900;
91
-
92
- const box = this.img;
93
-
94
- //on first load
95
- if (!box.style.width || box.style.width === 'auto') {
96
- const dimensions = {
97
- width: (box && box.naturalWidth) || 100,
98
- height: (box && box.naturalHeight) || 100,
99
- };
100
-
101
- const { width, height } = this.updateImageDimensions(
102
- dimensions,
103
- {
104
- width: dimensions.width < maxImageWidth ? dimensions.width : maxImageWidth,
105
- height: dimensions.height < maxImageHeight ? dimensions.height : maxImageHeight,
106
- },
107
- true,
108
- );
109
-
110
- box.style.width = `${width}px`;
111
- box.style.height = `${height}px`;
112
-
113
- this.setState({
114
- dimensions: { height: height, width: width },
115
- });
116
-
117
- const { node, editor } = this.props;
118
-
119
- let update = node.data;
120
-
121
- update = update.set('width', width);
122
- update = update.set('height', height);
123
-
124
- if (!update.equals(node.data)) {
125
- editor.change((c) => c.setNodeByKey(node.key, { data: update }));
126
- }
127
- }
128
- };
129
-
130
- startResizing = (e) => {
131
- const bounds = e.target.getBoundingClientRect();
132
- const box = this.img;
133
- const dimensions = {
134
- width: (box && box.naturalWidth) || 100,
135
- height: (box && box.naturalHeight) || 100,
136
- };
137
-
138
- const { width, height } = this.updateImageDimensions(
139
- dimensions,
140
- {
141
- width: e.clientX - bounds.left,
142
- height: e.clientY - bounds.top,
143
- },
144
- true,
145
- );
146
-
147
- const hasMinimumWidth = width > 50 && height > 50;
148
- const hasDimensionsConstraints = width <= 700 && height <= 900;
149
-
150
- if (hasMinimumWidth && hasDimensionsConstraints && box) {
151
- box.style.width = `${width}px`;
152
- box.style.height = `${height}px`;
153
-
154
- this.setState({
155
- dimensions: { height: height, width: width },
156
- });
157
-
158
- const { node, editor } = this.props;
159
-
160
- let update = node.data;
161
-
162
- update = update.set('width', width);
163
- update = update.set('height', height);
164
-
165
- if (!update.equals(node.data)) {
166
- editor.change((c) => c.setNodeByKey(node.key, { data: update }));
167
- }
168
- }
169
- };
170
-
171
- stopResizing = () => {
172
- window.removeEventListener('mousemove', this.startResizing, false);
173
- window.removeEventListener('mouseup', this.stopResizing, false);
174
- };
175
-
176
- updateImageDimensions = (initialDim, nextDim, keepAspectRatio, resizeType) => {
177
- // if we want to keep image aspect ratio
178
- if (keepAspectRatio) {
179
- const imageAspectRatio = initialDim.width / initialDim.height;
180
-
181
- if (resizeType === 'height') {
182
- // if we want to change image height => we update the width accordingly
183
- return {
184
- width: nextDim.height * imageAspectRatio,
185
- height: nextDim.height,
186
- };
187
- }
188
-
189
- // if we want to change image width => we update the height accordingly
190
- return {
191
- width: nextDim.width,
192
- height: nextDim.width / imageAspectRatio,
193
- };
194
- }
195
-
196
- // if we don't want to keep aspect ratio, we just update both values
197
- return {
198
- width: nextDim.width,
199
- height: nextDim.height,
200
- };
201
- };
202
-
203
- render() {
204
- const { node, editor, classes, attributes, onFocus } = this.props;
205
- const active = editor.value.isFocused && editor.value.selection.hasEdgeIn(node);
206
- const src = node.data.get('src');
207
- const loaded = node.data.get('loaded') !== false;
208
- const deleteStatus = node.data.get('deleteStatus');
209
- const alignment = node.data.get('alignment');
210
- const percent = node.data.get('percent');
211
- const alt = node.data.get('alt');
212
- let justifyContent;
213
-
214
- switch (alignment) {
215
- case 'left':
216
- justifyContent = 'flex-start';
217
- break;
218
-
219
- case 'center':
220
- justifyContent = 'center';
221
- break;
222
-
223
- case 'right':
224
- justifyContent = 'flex-end';
225
- break;
226
-
227
- default:
228
- justifyContent = 'flex-start';
229
- break;
230
- }
231
- log('[render] node.data:', node.data);
232
-
233
- const size = this.getSize(node.data);
234
-
235
- log('[render] style:', size);
236
-
237
- const className = classNames(
238
- classes.root,
239
- !loaded && classes.loading,
240
- deleteStatus === 'pending' && classes.pendingDelete,
241
- );
242
-
243
- const progressClasses = classNames(classes.progress, loaded && classes.hideProgress);
244
-
245
- return [
246
- <span key={'sp1'}>&nbsp;</span>,
247
- <div key={'comp'} onFocus={onFocus} className={className} style={{ justifyContent }}>
248
- <LinearProgress mode="determinate" value={percent > 0 ? percent : 0} className={progressClasses} />
249
- <div className={classes.imageContainer}>
250
- <img
251
- {...attributes}
252
- className={classNames(classes.image, active && classes.active)}
253
- ref={(ref) => {
254
- this.img = ref;
255
- }}
256
- src={src}
257
- style={size}
258
- onLoad={this.loadImage}
259
- alt={alt}
260
- />
261
- <div
262
- ref={(ref) => {
263
- this.resize = ref;
264
- }}
265
- className={classNames(classes.resize, 'resize')}
266
- />
267
- </div>
268
- </div>,
269
- <span key={'sp2'}>&nbsp;</span>,
270
- ];
271
- }
272
- }
273
-
274
- const styles = (theme) => ({
275
- portal: {
276
- position: 'absolute',
277
- opacity: 0,
278
- transition: 'opacity 200ms linear',
279
- },
280
- floatingButtonRow: {
281
- backgroundColor: theme.palette.background.paper,
282
- borderRadius: '1px',
283
- display: 'flex',
284
- padding: '10px',
285
- border: `solid 1px ${theme.palette.grey[200]}`,
286
- boxShadow:
287
- '0px 1px 5px 0px rgba(0, 0, 0, 0.2), 0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 3px 1px -2px rgba(0, 0, 0, 0.12)',
288
- },
289
- progress: {
290
- position: 'absolute',
291
- left: '0',
292
- width: 'fit-content',
293
- top: '0%',
294
- transition: 'opacity 200ms linear',
295
- },
296
- hideProgress: {
297
- opacity: 0,
298
- },
299
- loading: {
300
- opacity: 0.3,
301
- },
302
- pendingDelete: {
303
- opacity: 0.3,
304
- },
305
- root: {
306
- position: 'relative',
307
- border: `solid 1px ${theme.palette.common.white}`,
308
- display: 'flex',
309
- transition: 'opacity 200ms linear',
310
- },
311
- delete: {
312
- position: 'absolute',
313
- right: 0,
314
- },
315
- imageContainer: {
316
- position: 'relative',
317
- width: 'fit-content',
318
- display: 'flex',
319
- alignItems: 'center',
320
-
321
- '&&:hover > .resize': {
322
- display: 'block',
323
- },
324
- },
325
- active: {
326
- border: `solid 1px ${theme.palette.primary.main}`,
327
- },
328
- resize: {
329
- backgroundColor: theme.palette.primary.main,
330
- cursor: 'col-resize',
331
- height: '35px',
332
- width: '5px',
333
- borderRadius: 8,
334
- marginLeft: '5px',
335
- marginRight: '10px',
336
- display: 'none',
337
- },
338
- drawableHeight: {
339
- minHeight: 350,
340
- },
341
- });
342
-
343
- export default withStyles(styles)(Component);