@quadrats/common 0.6.7 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/blockquote/createBlockquote.d.ts +1 -1
- package/blockquote/createBlockquote.js +33 -33
- package/blockquote/index.cjs.js +32 -34
- package/bold/createBold.d.ts +2 -1
- package/bold/createBold.js +6 -4
- package/bold/index.cjs.js +6 -6
- package/divider/createDivider.d.ts +1 -1
- package/divider/createDivider.js +29 -29
- package/divider/index.cjs.js +29 -31
- package/embed/createEmbed.js +40 -40
- package/embed/deserializeEmbedElementToData.js +6 -6
- package/embed/index.cjs.js +54 -56
- package/embed/serializeEmbedCode.js +8 -8
- package/embed/strategies/facebook/index.cjs.js +45 -47
- package/embed/strategies/facebook/index.d.ts +5 -5
- package/embed/strategies/facebook/index.js +45 -45
- package/embed/strategies/instagram/index.cjs.js +29 -31
- package/embed/strategies/instagram/index.d.ts +3 -3
- package/embed/strategies/instagram/index.js +29 -29
- package/embed/strategies/podcast-apple/index.cjs.js +16 -18
- package/embed/strategies/podcast-apple/index.d.ts +4 -4
- package/embed/strategies/podcast-apple/index.js +16 -16
- package/embed/strategies/spotify/index.cjs.js +14 -16
- package/embed/strategies/spotify/index.d.ts +4 -4
- package/embed/strategies/spotify/index.js +14 -14
- package/embed/strategies/twitter/index.cjs.js +41 -43
- package/embed/strategies/twitter/index.d.ts +4 -4
- package/embed/strategies/twitter/index.js +41 -41
- package/embed/strategies/vimeo/index.cjs.js +14 -16
- package/embed/strategies/vimeo/index.d.ts +3 -3
- package/embed/strategies/vimeo/index.js +14 -14
- package/embed/strategies/youtube/index.cjs.js +14 -16
- package/embed/strategies/youtube/index.d.ts +3 -3
- package/embed/strategies/youtube/index.js +14 -14
- package/embed/typings.d.ts +1 -1
- package/file-uploader/_virtual/_tslib.js +3 -1
- package/file-uploader/createFileUploader.js +76 -76
- package/file-uploader/getFilesFromInput.js +24 -24
- package/file-uploader/index.cjs.js +102 -102
- package/file-uploader/typings.d.ts +6 -6
- package/footnote/createFootnote.d.ts +1 -1
- package/footnote/createFootnote.js +65 -65
- package/footnote/index.cjs.js +65 -67
- package/footnote/typings.d.ts +1 -1
- package/heading/constants.js +1 -1
- package/heading/createHeading.d.ts +1 -1
- package/heading/createHeading.js +45 -45
- package/heading/index.cjs.js +46 -48
- package/heading/typings.d.ts +1 -1
- package/highlight/createHighlight.d.ts +2 -1
- package/highlight/createHighlight.js +6 -4
- package/highlight/index.cjs.js +6 -6
- package/image/constants.js +4 -4
- package/image/createImage.js +195 -195
- package/image/getImageElementCommonProps.js +6 -6
- package/image/getImageFigureElementCommonProps.js +5 -5
- package/image/index.cjs.js +211 -213
- package/image/isHostingNotRequired.js +2 -2
- package/image/typings.d.ts +8 -8
- package/input-block/createInputBlock.js +37 -37
- package/input-block/index.cjs.js +37 -39
- package/input-widget/typings.d.ts +1 -1
- package/italic/createItalic.d.ts +2 -1
- package/italic/createItalic.js +6 -4
- package/italic/index.cjs.js +6 -6
- package/link/createLink.js +147 -147
- package/link/index.cjs.js +146 -148
- package/link/typings.d.ts +2 -2
- package/list/constants.js +4 -4
- package/list/createList.js +185 -185
- package/list/index.cjs.js +188 -190
- package/list/typings.d.ts +4 -4
- package/package.json +4 -4
- package/read-more/createReadMore.d.ts +1 -1
- package/read-more/createReadMore.js +51 -51
- package/read-more/index.cjs.js +50 -52
- package/strikethrough/createStrikethrough.d.ts +2 -1
- package/strikethrough/createStrikethrough.js +6 -4
- package/strikethrough/index.cjs.js +6 -6
- package/toggle-mark/createToggleMarkCreator.d.ts +4 -4
- package/toggle-mark/createToggleMarkCreator.js +36 -36
- package/toggle-mark/index.cjs.js +36 -38
- package/underline/createUnderline.d.ts +2 -1
- package/underline/createUnderline.js +6 -4
- package/underline/index.cjs.js +6 -6
package/image/index.cjs.js
CHANGED
|
@@ -1,229 +1,227 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
-
|
|
5
3
|
var utils = require('@quadrats/utils');
|
|
6
4
|
var core = require('@quadrats/core');
|
|
7
5
|
|
|
8
|
-
const IMAGE_TYPES = {
|
|
9
|
-
figure: 'image_figure',
|
|
10
|
-
image: 'image',
|
|
11
|
-
caption: 'image_caption',
|
|
6
|
+
const IMAGE_TYPES = {
|
|
7
|
+
figure: 'image_figure',
|
|
8
|
+
image: 'image',
|
|
9
|
+
caption: 'image_caption',
|
|
12
10
|
};
|
|
13
11
|
|
|
14
|
-
function isHostingNotRequired(src) {
|
|
15
|
-
return /^https?:\/\/.*/.test(src) || src.startsWith('data:image');
|
|
12
|
+
function isHostingNotRequired(src) {
|
|
13
|
+
return /^https?:\/\/.*/.test(src) || src.startsWith('data:image');
|
|
16
14
|
}
|
|
17
15
|
|
|
18
|
-
function getImageFigureElementCommonProps(element) {
|
|
19
|
-
const { width } = element;
|
|
20
|
-
return {
|
|
21
|
-
style: typeof width === 'number' ? { width: `${width}%` } : undefined,
|
|
22
|
-
};
|
|
16
|
+
function getImageFigureElementCommonProps(element) {
|
|
17
|
+
const { width } = element;
|
|
18
|
+
return {
|
|
19
|
+
style: typeof width === 'number' ? { width: `${width}%` } : undefined,
|
|
20
|
+
};
|
|
23
21
|
}
|
|
24
22
|
|
|
25
|
-
function getImageElementCommonProps(element, hostingResolvers) {
|
|
26
|
-
const { src, hosting } = element;
|
|
27
|
-
const resolver = !isHostingNotRequired(src) && hosting && hostingResolvers ? hostingResolvers[hosting] : undefined;
|
|
28
|
-
return {
|
|
29
|
-
src: resolver ? resolver(src) : src,
|
|
30
|
-
};
|
|
23
|
+
function getImageElementCommonProps(element, hostingResolvers) {
|
|
24
|
+
const { src, hosting } = element;
|
|
25
|
+
const resolver = !isHostingNotRequired(src) && hosting && hostingResolvers ? hostingResolvers[hosting] : undefined;
|
|
26
|
+
return {
|
|
27
|
+
src: resolver ? resolver(src) : src,
|
|
28
|
+
};
|
|
31
29
|
}
|
|
32
30
|
|
|
33
|
-
function resolveSizeSteps(steps) {
|
|
34
|
-
let sortedSteps = steps.filter(step => step > 0 && step < 100).sort();
|
|
35
|
-
if (!sortedSteps.includes(100)) {
|
|
36
|
-
sortedSteps = [...sortedSteps, 100];
|
|
37
|
-
}
|
|
38
|
-
return sortedSteps;
|
|
39
|
-
}
|
|
40
|
-
function createImage(options = {}) {
|
|
41
|
-
const { types: typesOptions, hostingResolvers, sizeSteps: unresolvedSizeSteps, isImageUrl = utils.isImageUrl, } = options;
|
|
42
|
-
const types = Object.assign(Object.assign({}, IMAGE_TYPES), typesOptions);
|
|
43
|
-
const sizeSteps = unresolvedSizeSteps && resolveSizeSteps(unresolvedSizeSteps);
|
|
44
|
-
const getAboveImageFigure = (editor, options) => core.getAboveByTypes(editor, [types.figure], options);
|
|
45
|
-
const getAboveImageCaption = (editor, options) => core.getAboveByTypes(editor, [types.caption], options);
|
|
46
|
-
const isNodesInImage = (editor, options) => core.isNodesTypeIn(editor, [types.image], options);
|
|
47
|
-
const isSelectionInImage = editor => isNodesInImage(editor);
|
|
48
|
-
const isSelectionInImageCaption = editor => core.isNodesTypeIn(editor, [types.caption]);
|
|
49
|
-
const isCollapsedOnImage = editor => !!editor.selection && core.Range.isCollapsed(editor.selection) && isSelectionInImage(editor);
|
|
50
|
-
const previousNodeIsCaption = (editor) => {
|
|
51
|
-
const previous = core.Editor.previous(editor);
|
|
52
|
-
if (!previous)
|
|
53
|
-
return false;
|
|
54
|
-
const [, previousLocation] = previous;
|
|
55
|
-
const previousWrapper = core.Editor.parent(editor, previousLocation);
|
|
56
|
-
if (!previousWrapper)
|
|
57
|
-
return false;
|
|
58
|
-
const [previousWrapperNode] = previousWrapper;
|
|
59
|
-
return previousWrapperNode.type === types.caption;
|
|
60
|
-
};
|
|
61
|
-
const createImageElement = (src, hosting) => {
|
|
62
|
-
const imageElement = {
|
|
63
|
-
type: types.image,
|
|
64
|
-
src,
|
|
65
|
-
hosting,
|
|
66
|
-
children: [{ text: '' }],
|
|
67
|
-
};
|
|
68
|
-
const captionElement = {
|
|
69
|
-
type: types.caption,
|
|
70
|
-
children: [{ text: '' }],
|
|
71
|
-
};
|
|
72
|
-
return {
|
|
73
|
-
type: types.figure,
|
|
74
|
-
width: 100,
|
|
75
|
-
children: [imageElement, captionElement],
|
|
76
|
-
};
|
|
77
|
-
};
|
|
78
|
-
const insertImage = (editor, src, options = {}) => {
|
|
79
|
-
const { hosting, at } = options;
|
|
80
|
-
const imageElement = createImageElement(src, hosting);
|
|
81
|
-
core.Transforms.insertNodes(editor, [imageElement, core.createParagraphElement()], { at });
|
|
82
|
-
};
|
|
83
|
-
const adjustWidthPercentage = (percentage) => {
|
|
84
|
-
if (percentage < 0) {
|
|
85
|
-
percentage = 0;
|
|
86
|
-
}
|
|
87
|
-
else if (percentage > 100) {
|
|
88
|
-
percentage = 100;
|
|
89
|
-
}
|
|
90
|
-
if (!sizeSteps) {
|
|
91
|
-
return percentage;
|
|
92
|
-
}
|
|
93
|
-
const lowerIndex = sizeSteps.findIndex(step => step >= percentage) - 1;
|
|
94
|
-
const upperIndex = lowerIndex + 1;
|
|
95
|
-
if (lowerIndex < 0) {
|
|
96
|
-
return sizeSteps[0];
|
|
97
|
-
}
|
|
98
|
-
const lower = sizeSteps[lowerIndex];
|
|
99
|
-
if (upperIndex === sizeSteps.length) {
|
|
100
|
-
return lower;
|
|
101
|
-
}
|
|
102
|
-
const upper = sizeSteps[upperIndex];
|
|
103
|
-
return Math.abs(percentage - lower) <= Math.abs(upper - percentage) ? lower : upper;
|
|
104
|
-
};
|
|
105
|
-
const resizeImage = (editor, [, path], width) => {
|
|
106
|
-
const [figure, figurePath] = getAboveImageFigure(editor, { at: path }) || [];
|
|
107
|
-
if (figure) {
|
|
108
|
-
width = adjustWidthPercentage(width);
|
|
109
|
-
if (figure.width !== width) {
|
|
110
|
-
const resizedElement = Object.assign(Object.assign({}, figure), { width });
|
|
111
|
-
core.Transforms.setNodes(editor, resizedElement, {
|
|
112
|
-
at: figurePath,
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
};
|
|
117
|
-
return {
|
|
118
|
-
types,
|
|
119
|
-
hostingResolvers,
|
|
120
|
-
sizeSteps,
|
|
121
|
-
isImageUrl,
|
|
122
|
-
getAboveImageFigure,
|
|
123
|
-
getAboveImageCaption,
|
|
124
|
-
isSelectionInImage,
|
|
125
|
-
isSelectionInImageCaption,
|
|
126
|
-
isCollapsedOnImage,
|
|
127
|
-
createImageElement,
|
|
128
|
-
insertImage,
|
|
129
|
-
resizeImage,
|
|
130
|
-
with(editor) {
|
|
131
|
-
const { deleteBackward, deleteForward, insertBreak, isVoid, normalizeNode, } = editor;
|
|
132
|
-
const deleteCollapsed = (origin, isEdgeMethodName) => {
|
|
133
|
-
const { selection } = editor;
|
|
134
|
-
/**
|
|
135
|
-
* Avoid from delete fragment outside caption while collapsed in caption.
|
|
136
|
-
*/
|
|
137
|
-
if (selection && core.Range.isCollapsed(selection)) {
|
|
138
|
-
const [, captionPath] = getAboveImageCaption(editor) || [];
|
|
139
|
-
if ((captionPath && core.Editor[isEdgeMethodName](editor, selection.focus, captionPath))) {
|
|
140
|
-
return;
|
|
141
|
-
}
|
|
142
|
-
// Remove image element when backwards from external
|
|
143
|
-
if (!captionPath && previousNodeIsCaption(editor)) {
|
|
144
|
-
const previous = core.Editor.previous(editor);
|
|
145
|
-
if (!previous)
|
|
146
|
-
return false;
|
|
147
|
-
const [, previousLocation] = previous;
|
|
148
|
-
const previousWrapper = core.Editor.parent(editor, previousLocation);
|
|
149
|
-
if (!previousWrapper)
|
|
150
|
-
return false;
|
|
151
|
-
const [previousWrapperNode, wrapperLocation] = previousWrapper;
|
|
152
|
-
if (previousWrapperNode.type === types.caption) {
|
|
153
|
-
const imageContainer = core.Editor.parent(editor, wrapperLocation);
|
|
154
|
-
if (imageContainer) {
|
|
155
|
-
const [imageElement, imageLocation] = imageContainer;
|
|
156
|
-
if (imageElement.type === types.figure) {
|
|
157
|
-
core.Transforms.removeNodes(editor, { at: imageLocation });
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
return;
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
origin();
|
|
165
|
-
};
|
|
166
|
-
editor.deleteBackward = (unit) => {
|
|
167
|
-
deleteCollapsed(() => deleteBackward(unit), 'isStart');
|
|
168
|
-
};
|
|
169
|
-
editor.deleteForward = (unit) => {
|
|
170
|
-
deleteCollapsed(() => deleteForward(unit), 'isEnd');
|
|
171
|
-
};
|
|
172
|
-
editor.insertBreak = () => {
|
|
173
|
-
const captionEntry = getAboveImageCaption(editor);
|
|
174
|
-
/**
|
|
175
|
-
* Avoid from splitting children of caption.
|
|
176
|
-
*/
|
|
177
|
-
if (captionEntry) {
|
|
178
|
-
const [, captionLocation] = captionEntry;
|
|
179
|
-
const imageEntry = core.Editor.parent(editor, captionLocation);
|
|
180
|
-
if (imageEntry) {
|
|
181
|
-
const [imageElement, imagePosition] = imageEntry;
|
|
182
|
-
if (imageElement.type === types.figure) {
|
|
183
|
-
core.Transforms.insertNodes(editor, core.createParagraphElement(), { at: core.Editor.after(editor, imagePosition) });
|
|
184
|
-
core.Transforms.move(editor);
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
return;
|
|
188
|
-
}
|
|
189
|
-
insertBreak();
|
|
190
|
-
};
|
|
191
|
-
editor.isVoid = element => element.type === types.image || isVoid(element);
|
|
192
|
-
editor.normalizeNode = (entry) => {
|
|
193
|
-
const [node, path] = entry;
|
|
194
|
-
if (core.Element.isElement(node)) {
|
|
195
|
-
if (node.type === types.figure) {
|
|
196
|
-
if (!isNodesInImage(editor, { at: path })) {
|
|
197
|
-
core.Transforms.removeNodes(editor, { at: path });
|
|
198
|
-
return;
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
else if (node.type === types.image) {
|
|
202
|
-
const { src, width, hosting } = node;
|
|
203
|
-
if (typeof src !== 'string'
|
|
204
|
-
|| !(width == null || typeof width === 'number')
|
|
205
|
-
|| !(hosting == null || typeof hosting === 'string')) {
|
|
206
|
-
const [, figurePath] = getAboveImageFigure(editor, { at: path }) || [];
|
|
207
|
-
if (figurePath) {
|
|
208
|
-
core.Transforms.removeNodes(editor, { at: figurePath });
|
|
209
|
-
return;
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
if (core.normalizeVoidElementChildren(editor, [node, path])) {
|
|
213
|
-
return;
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
else if (node.type === types.caption) {
|
|
217
|
-
if (core.normalizeOnlyInlineOrTextInChildren(editor, entry)) {
|
|
218
|
-
return;
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
normalizeNode(entry);
|
|
223
|
-
};
|
|
224
|
-
return editor;
|
|
225
|
-
},
|
|
226
|
-
};
|
|
31
|
+
function resolveSizeSteps(steps) {
|
|
32
|
+
let sortedSteps = steps.filter(step => step > 0 && step < 100).sort();
|
|
33
|
+
if (!sortedSteps.includes(100)) {
|
|
34
|
+
sortedSteps = [...sortedSteps, 100];
|
|
35
|
+
}
|
|
36
|
+
return sortedSteps;
|
|
37
|
+
}
|
|
38
|
+
function createImage(options = {}) {
|
|
39
|
+
const { types: typesOptions, hostingResolvers, sizeSteps: unresolvedSizeSteps, isImageUrl = utils.isImageUrl, } = options;
|
|
40
|
+
const types = Object.assign(Object.assign({}, IMAGE_TYPES), typesOptions);
|
|
41
|
+
const sizeSteps = unresolvedSizeSteps && resolveSizeSteps(unresolvedSizeSteps);
|
|
42
|
+
const getAboveImageFigure = (editor, options) => core.getAboveByTypes(editor, [types.figure], options);
|
|
43
|
+
const getAboveImageCaption = (editor, options) => core.getAboveByTypes(editor, [types.caption], options);
|
|
44
|
+
const isNodesInImage = (editor, options) => core.isNodesTypeIn(editor, [types.image], options);
|
|
45
|
+
const isSelectionInImage = editor => isNodesInImage(editor);
|
|
46
|
+
const isSelectionInImageCaption = editor => core.isNodesTypeIn(editor, [types.caption]);
|
|
47
|
+
const isCollapsedOnImage = editor => !!editor.selection && core.Range.isCollapsed(editor.selection) && isSelectionInImage(editor);
|
|
48
|
+
const previousNodeIsCaption = (editor) => {
|
|
49
|
+
const previous = core.Editor.previous(editor);
|
|
50
|
+
if (!previous)
|
|
51
|
+
return false;
|
|
52
|
+
const [, previousLocation] = previous;
|
|
53
|
+
const previousWrapper = core.Editor.parent(editor, previousLocation);
|
|
54
|
+
if (!previousWrapper)
|
|
55
|
+
return false;
|
|
56
|
+
const [previousWrapperNode] = previousWrapper;
|
|
57
|
+
return previousWrapperNode.type === types.caption;
|
|
58
|
+
};
|
|
59
|
+
const createImageElement = (src, hosting) => {
|
|
60
|
+
const imageElement = {
|
|
61
|
+
type: types.image,
|
|
62
|
+
src,
|
|
63
|
+
hosting,
|
|
64
|
+
children: [{ text: '' }],
|
|
65
|
+
};
|
|
66
|
+
const captionElement = {
|
|
67
|
+
type: types.caption,
|
|
68
|
+
children: [{ text: '' }],
|
|
69
|
+
};
|
|
70
|
+
return {
|
|
71
|
+
type: types.figure,
|
|
72
|
+
width: 100,
|
|
73
|
+
children: [imageElement, captionElement],
|
|
74
|
+
};
|
|
75
|
+
};
|
|
76
|
+
const insertImage = (editor, src, options = {}) => {
|
|
77
|
+
const { hosting, at } = options;
|
|
78
|
+
const imageElement = createImageElement(src, hosting);
|
|
79
|
+
core.Transforms.insertNodes(editor, [imageElement, core.createParagraphElement()], { at });
|
|
80
|
+
};
|
|
81
|
+
const adjustWidthPercentage = (percentage) => {
|
|
82
|
+
if (percentage < 0) {
|
|
83
|
+
percentage = 0;
|
|
84
|
+
}
|
|
85
|
+
else if (percentage > 100) {
|
|
86
|
+
percentage = 100;
|
|
87
|
+
}
|
|
88
|
+
if (!sizeSteps) {
|
|
89
|
+
return percentage;
|
|
90
|
+
}
|
|
91
|
+
const lowerIndex = sizeSteps.findIndex(step => step >= percentage) - 1;
|
|
92
|
+
const upperIndex = lowerIndex + 1;
|
|
93
|
+
if (lowerIndex < 0) {
|
|
94
|
+
return sizeSteps[0];
|
|
95
|
+
}
|
|
96
|
+
const lower = sizeSteps[lowerIndex];
|
|
97
|
+
if (upperIndex === sizeSteps.length) {
|
|
98
|
+
return lower;
|
|
99
|
+
}
|
|
100
|
+
const upper = sizeSteps[upperIndex];
|
|
101
|
+
return Math.abs(percentage - lower) <= Math.abs(upper - percentage) ? lower : upper;
|
|
102
|
+
};
|
|
103
|
+
const resizeImage = (editor, [, path], width) => {
|
|
104
|
+
const [figure, figurePath] = getAboveImageFigure(editor, { at: path }) || [];
|
|
105
|
+
if (figure) {
|
|
106
|
+
width = adjustWidthPercentage(width);
|
|
107
|
+
if (figure.width !== width) {
|
|
108
|
+
const resizedElement = Object.assign(Object.assign({}, figure), { width });
|
|
109
|
+
core.Transforms.setNodes(editor, resizedElement, {
|
|
110
|
+
at: figurePath,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
return {
|
|
116
|
+
types,
|
|
117
|
+
hostingResolvers,
|
|
118
|
+
sizeSteps,
|
|
119
|
+
isImageUrl,
|
|
120
|
+
getAboveImageFigure,
|
|
121
|
+
getAboveImageCaption,
|
|
122
|
+
isSelectionInImage,
|
|
123
|
+
isSelectionInImageCaption,
|
|
124
|
+
isCollapsedOnImage,
|
|
125
|
+
createImageElement,
|
|
126
|
+
insertImage,
|
|
127
|
+
resizeImage,
|
|
128
|
+
with(editor) {
|
|
129
|
+
const { deleteBackward, deleteForward, insertBreak, isVoid, normalizeNode, } = editor;
|
|
130
|
+
const deleteCollapsed = (origin, isEdgeMethodName) => {
|
|
131
|
+
const { selection } = editor;
|
|
132
|
+
/**
|
|
133
|
+
* Avoid from delete fragment outside caption while collapsed in caption.
|
|
134
|
+
*/
|
|
135
|
+
if (selection && core.Range.isCollapsed(selection)) {
|
|
136
|
+
const [, captionPath] = getAboveImageCaption(editor) || [];
|
|
137
|
+
if ((captionPath && core.Editor[isEdgeMethodName](editor, selection.focus, captionPath))) {
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
// Remove image element when backwards from external
|
|
141
|
+
if (!captionPath && previousNodeIsCaption(editor)) {
|
|
142
|
+
const previous = core.Editor.previous(editor);
|
|
143
|
+
if (!previous)
|
|
144
|
+
return false;
|
|
145
|
+
const [, previousLocation] = previous;
|
|
146
|
+
const previousWrapper = core.Editor.parent(editor, previousLocation);
|
|
147
|
+
if (!previousWrapper)
|
|
148
|
+
return false;
|
|
149
|
+
const [previousWrapperNode, wrapperLocation] = previousWrapper;
|
|
150
|
+
if (previousWrapperNode.type === types.caption) {
|
|
151
|
+
const imageContainer = core.Editor.parent(editor, wrapperLocation);
|
|
152
|
+
if (imageContainer) {
|
|
153
|
+
const [imageElement, imageLocation] = imageContainer;
|
|
154
|
+
if (imageElement.type === types.figure) {
|
|
155
|
+
core.Transforms.removeNodes(editor, { at: imageLocation });
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
origin();
|
|
163
|
+
};
|
|
164
|
+
editor.deleteBackward = (unit) => {
|
|
165
|
+
deleteCollapsed(() => deleteBackward(unit), 'isStart');
|
|
166
|
+
};
|
|
167
|
+
editor.deleteForward = (unit) => {
|
|
168
|
+
deleteCollapsed(() => deleteForward(unit), 'isEnd');
|
|
169
|
+
};
|
|
170
|
+
editor.insertBreak = () => {
|
|
171
|
+
const captionEntry = getAboveImageCaption(editor);
|
|
172
|
+
/**
|
|
173
|
+
* Avoid from splitting children of caption.
|
|
174
|
+
*/
|
|
175
|
+
if (captionEntry) {
|
|
176
|
+
const [, captionLocation] = captionEntry;
|
|
177
|
+
const imageEntry = core.Editor.parent(editor, captionLocation);
|
|
178
|
+
if (imageEntry) {
|
|
179
|
+
const [imageElement, imagePosition] = imageEntry;
|
|
180
|
+
if (imageElement.type === types.figure) {
|
|
181
|
+
core.Transforms.insertNodes(editor, core.createParagraphElement(), { at: core.Editor.after(editor, imagePosition) });
|
|
182
|
+
core.Transforms.move(editor);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
insertBreak();
|
|
188
|
+
};
|
|
189
|
+
editor.isVoid = element => element.type === types.image || isVoid(element);
|
|
190
|
+
editor.normalizeNode = (entry) => {
|
|
191
|
+
const [node, path] = entry;
|
|
192
|
+
if (core.Element.isElement(node)) {
|
|
193
|
+
if (node.type === types.figure) {
|
|
194
|
+
if (!isNodesInImage(editor, { at: path })) {
|
|
195
|
+
core.Transforms.removeNodes(editor, { at: path });
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
else if (node.type === types.image) {
|
|
200
|
+
const { src, width, hosting } = node;
|
|
201
|
+
if (typeof src !== 'string'
|
|
202
|
+
|| !(width == null || typeof width === 'number')
|
|
203
|
+
|| !(hosting == null || typeof hosting === 'string')) {
|
|
204
|
+
const [, figurePath] = getAboveImageFigure(editor, { at: path }) || [];
|
|
205
|
+
if (figurePath) {
|
|
206
|
+
core.Transforms.removeNodes(editor, { at: figurePath });
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
if (core.normalizeVoidElementChildren(editor, [node, path])) {
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
else if (node.type === types.caption) {
|
|
215
|
+
if (core.normalizeOnlyInlineOrTextInChildren(editor, entry)) {
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
normalizeNode(entry);
|
|
221
|
+
};
|
|
222
|
+
return editor;
|
|
223
|
+
},
|
|
224
|
+
};
|
|
227
225
|
}
|
|
228
226
|
|
|
229
227
|
exports.IMAGE_TYPES = IMAGE_TYPES;
|
package/image/typings.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Editor, QuadratsElement, GetAboveByTypesOptions, Location, NodeEntry, Text, Withable, WithElementType } from '@quadrats/core';
|
|
2
|
-
export
|
|
3
|
-
export
|
|
4
|
-
export
|
|
5
|
-
export
|
|
2
|
+
export type ImageFigureTypeKey = 'figure';
|
|
3
|
+
export type ImageTypeKey = 'image';
|
|
4
|
+
export type ImageCaptionTypeKey = 'caption';
|
|
5
|
+
export type ImageTypes = Record<ImageFigureTypeKey | ImageTypeKey | ImageCaptionTypeKey, string>;
|
|
6
6
|
export interface ImageFigureElement extends QuadratsElement, WithElementType {
|
|
7
7
|
width?: number;
|
|
8
8
|
}
|
|
@@ -30,13 +30,13 @@ export interface ImageCaptionElement extends QuadratsElement, WithElementType {
|
|
|
30
30
|
* foo: src => `https://foo.storage/${src}`
|
|
31
31
|
* };
|
|
32
32
|
*/
|
|
33
|
-
export
|
|
33
|
+
export type ImageHostingResolvers<Hosting extends string> = Record<Hosting, (url: string) => string>;
|
|
34
34
|
/**
|
|
35
35
|
* Only sizes included in steps are valid image size.
|
|
36
36
|
*/
|
|
37
|
-
export
|
|
38
|
-
export
|
|
39
|
-
export
|
|
37
|
+
export type ImageSizeSteps = ReadonlyArray<number>;
|
|
38
|
+
export type ImageGetAboveImageFigureOptions = GetAboveByTypesOptions;
|
|
39
|
+
export type ImageGetAboveImageCaptionOptions = GetAboveByTypesOptions;
|
|
40
40
|
export interface Image<Hosting extends string, T extends Editor = Editor> extends Withable {
|
|
41
41
|
/**
|
|
42
42
|
* An object which keys are `figure`, `image`, 'caption` and values are the corresponding element types.
|
|
@@ -1,43 +1,43 @@
|
|
|
1
1
|
import { Editor, Path, Transforms } from '@quadrats/core';
|
|
2
2
|
import { INPUT_BLOCK_TYPE } from './constants.js';
|
|
3
3
|
|
|
4
|
-
function createInputBlock(options = {}) {
|
|
5
|
-
const { type = INPUT_BLOCK_TYPE } = options;
|
|
6
|
-
const start = (editor, inputConfig) => {
|
|
7
|
-
const inputBlock = Object.assign(Object.assign({}, inputConfig), { type, children: [{ text: '' }] });
|
|
8
|
-
Editor.insertNode(editor, inputBlock);
|
|
9
|
-
};
|
|
10
|
-
/**
|
|
11
|
-
* Set selection to end of previous path.
|
|
12
|
-
*/
|
|
13
|
-
const remove = (editor, [, path], focus) => {
|
|
14
|
-
const previousPath = Path.previous(path);
|
|
15
|
-
const previousEndPath = Editor.end(editor, previousPath);
|
|
16
|
-
Transforms.select(editor, previousEndPath);
|
|
17
|
-
focus();
|
|
18
|
-
Transforms.removeNodes(editor, { at: path });
|
|
19
|
-
};
|
|
20
|
-
const confirm = (element, value, remove) => {
|
|
21
|
-
remove();
|
|
22
|
-
element.confirm(value);
|
|
23
|
-
};
|
|
24
|
-
return {
|
|
25
|
-
type,
|
|
26
|
-
start,
|
|
27
|
-
remove,
|
|
28
|
-
confirm,
|
|
29
|
-
with(editor) {
|
|
30
|
-
const { isVoid } = editor;
|
|
31
|
-
editor.isVoid = (element) => {
|
|
32
|
-
// invalidate unfinished input_block from storage
|
|
33
|
-
if (element.type === type
|
|
34
|
-
&& typeof element.getPlaceholder !== 'function')
|
|
35
|
-
return false;
|
|
36
|
-
return element.type === type || isVoid(element);
|
|
37
|
-
};
|
|
38
|
-
return editor;
|
|
39
|
-
},
|
|
40
|
-
};
|
|
4
|
+
function createInputBlock(options = {}) {
|
|
5
|
+
const { type = INPUT_BLOCK_TYPE } = options;
|
|
6
|
+
const start = (editor, inputConfig) => {
|
|
7
|
+
const inputBlock = Object.assign(Object.assign({}, inputConfig), { type, children: [{ text: '' }] });
|
|
8
|
+
Editor.insertNode(editor, inputBlock);
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Set selection to end of previous path.
|
|
12
|
+
*/
|
|
13
|
+
const remove = (editor, [, path], focus) => {
|
|
14
|
+
const previousPath = Path.previous(path);
|
|
15
|
+
const previousEndPath = Editor.end(editor, previousPath);
|
|
16
|
+
Transforms.select(editor, previousEndPath);
|
|
17
|
+
focus();
|
|
18
|
+
Transforms.removeNodes(editor, { at: path });
|
|
19
|
+
};
|
|
20
|
+
const confirm = (element, value, remove) => {
|
|
21
|
+
remove();
|
|
22
|
+
element.confirm(value);
|
|
23
|
+
};
|
|
24
|
+
return {
|
|
25
|
+
type,
|
|
26
|
+
start,
|
|
27
|
+
remove,
|
|
28
|
+
confirm,
|
|
29
|
+
with(editor) {
|
|
30
|
+
const { isVoid } = editor;
|
|
31
|
+
editor.isVoid = (element) => {
|
|
32
|
+
// invalidate unfinished input_block from storage
|
|
33
|
+
if (element.type === type
|
|
34
|
+
&& typeof element.getPlaceholder !== 'function')
|
|
35
|
+
return false;
|
|
36
|
+
return element.type === type || isVoid(element);
|
|
37
|
+
};
|
|
38
|
+
return editor;
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
export { createInputBlock };
|
package/input-block/index.cjs.js
CHANGED
|
@@ -1,48 +1,46 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
-
|
|
5
3
|
var core = require('@quadrats/core');
|
|
6
4
|
|
|
7
5
|
const INPUT_BLOCK_TYPE = 'input_block';
|
|
8
6
|
|
|
9
|
-
function createInputBlock(options = {}) {
|
|
10
|
-
const { type = INPUT_BLOCK_TYPE } = options;
|
|
11
|
-
const start = (editor, inputConfig) => {
|
|
12
|
-
const inputBlock = Object.assign(Object.assign({}, inputConfig), { type, children: [{ text: '' }] });
|
|
13
|
-
core.Editor.insertNode(editor, inputBlock);
|
|
14
|
-
};
|
|
15
|
-
/**
|
|
16
|
-
* Set selection to end of previous path.
|
|
17
|
-
*/
|
|
18
|
-
const remove = (editor, [, path], focus) => {
|
|
19
|
-
const previousPath = core.Path.previous(path);
|
|
20
|
-
const previousEndPath = core.Editor.end(editor, previousPath);
|
|
21
|
-
core.Transforms.select(editor, previousEndPath);
|
|
22
|
-
focus();
|
|
23
|
-
core.Transforms.removeNodes(editor, { at: path });
|
|
24
|
-
};
|
|
25
|
-
const confirm = (element, value, remove) => {
|
|
26
|
-
remove();
|
|
27
|
-
element.confirm(value);
|
|
28
|
-
};
|
|
29
|
-
return {
|
|
30
|
-
type,
|
|
31
|
-
start,
|
|
32
|
-
remove,
|
|
33
|
-
confirm,
|
|
34
|
-
with(editor) {
|
|
35
|
-
const { isVoid } = editor;
|
|
36
|
-
editor.isVoid = (element) => {
|
|
37
|
-
// invalidate unfinished input_block from storage
|
|
38
|
-
if (element.type === type
|
|
39
|
-
&& typeof element.getPlaceholder !== 'function')
|
|
40
|
-
return false;
|
|
41
|
-
return element.type === type || isVoid(element);
|
|
42
|
-
};
|
|
43
|
-
return editor;
|
|
44
|
-
},
|
|
45
|
-
};
|
|
7
|
+
function createInputBlock(options = {}) {
|
|
8
|
+
const { type = INPUT_BLOCK_TYPE } = options;
|
|
9
|
+
const start = (editor, inputConfig) => {
|
|
10
|
+
const inputBlock = Object.assign(Object.assign({}, inputConfig), { type, children: [{ text: '' }] });
|
|
11
|
+
core.Editor.insertNode(editor, inputBlock);
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Set selection to end of previous path.
|
|
15
|
+
*/
|
|
16
|
+
const remove = (editor, [, path], focus) => {
|
|
17
|
+
const previousPath = core.Path.previous(path);
|
|
18
|
+
const previousEndPath = core.Editor.end(editor, previousPath);
|
|
19
|
+
core.Transforms.select(editor, previousEndPath);
|
|
20
|
+
focus();
|
|
21
|
+
core.Transforms.removeNodes(editor, { at: path });
|
|
22
|
+
};
|
|
23
|
+
const confirm = (element, value, remove) => {
|
|
24
|
+
remove();
|
|
25
|
+
element.confirm(value);
|
|
26
|
+
};
|
|
27
|
+
return {
|
|
28
|
+
type,
|
|
29
|
+
start,
|
|
30
|
+
remove,
|
|
31
|
+
confirm,
|
|
32
|
+
with(editor) {
|
|
33
|
+
const { isVoid } = editor;
|
|
34
|
+
editor.isVoid = (element) => {
|
|
35
|
+
// invalidate unfinished input_block from storage
|
|
36
|
+
if (element.type === type
|
|
37
|
+
&& typeof element.getPlaceholder !== 'function')
|
|
38
|
+
return false;
|
|
39
|
+
return element.type === type || isVoid(element);
|
|
40
|
+
};
|
|
41
|
+
return editor;
|
|
42
|
+
},
|
|
43
|
+
};
|
|
46
44
|
}
|
|
47
45
|
|
|
48
46
|
exports.INPUT_BLOCK_TYPE = INPUT_BLOCK_TYPE;
|
|
@@ -13,4 +13,4 @@ export interface InputWidgetConfig {
|
|
|
13
13
|
confirm(value: string): void;
|
|
14
14
|
defaultValue?: string;
|
|
15
15
|
}
|
|
16
|
-
export
|
|
16
|
+
export type SetInputWidgetConfig = (value: InputWidgetConfig | null) => void;
|