@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/italic/createItalic.d.ts
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
import { Editor } from '@quadrats/core';
|
|
2
|
+
export declare function createItalic<E extends Editor = Editor>(variant?: string): ({ type, variant }?: import("@quadrats/common/toggle-mark").CreateToggleMarkOptions | undefined) => import("@quadrats/common/toggle-mark").ToggleMark<E>;
|
package/italic/createItalic.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { createToggleMarkCreator } from '@quadrats/common/toggle-mark';
|
|
2
2
|
import { ITALIC_TYPE } from './constants.js';
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
function createItalic(variant) {
|
|
5
|
+
return createToggleMarkCreator({
|
|
6
|
+
type: ITALIC_TYPE,
|
|
7
|
+
variant,
|
|
8
|
+
});
|
|
9
|
+
}
|
|
8
10
|
|
|
9
11
|
export { createItalic };
|
package/italic/index.cjs.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
-
|
|
5
3
|
var toggleMark = require('@quadrats/common/toggle-mark');
|
|
6
4
|
|
|
7
5
|
const ITALIC_TYPE = 'italic';
|
|
8
6
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
7
|
+
function createItalic(variant) {
|
|
8
|
+
return toggleMark.createToggleMarkCreator({
|
|
9
|
+
type: ITALIC_TYPE,
|
|
10
|
+
variant,
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
13
|
|
|
14
14
|
exports.ITALIC_TYPE = ITALIC_TYPE;
|
|
15
15
|
exports.createItalic = createItalic;
|
package/link/createLink.js
CHANGED
|
@@ -1,153 +1,153 @@
|
|
|
1
1
|
import { isUrl } from '@quadrats/utils';
|
|
2
|
-
import { Range,
|
|
2
|
+
import { Range, Editor, Element, Transforms, Text, getRangeBeforeFromAboveBlockStart, getRangeBefore, isNodesTypeIn, unwrapNodesByTypes, wrapNodesWithUnhangRange, getAboveByTypes } from '@quadrats/core';
|
|
3
3
|
import { LINK_TYPE } from './constants.js';
|
|
4
4
|
|
|
5
|
-
function createLink({ type = LINK_TYPE, isUrl: isUrl$1 = isUrl, prevUrlToLinkAfterSpaceEntered = true, wrappableVoidTypes, } = {}) {
|
|
6
|
-
const getFirstPrevTextAsUrlAndRange = (editor, at) => {
|
|
7
|
-
/**
|
|
8
|
-
* First, find all text under the same lowest above block and before entered space.
|
|
9
|
-
*/
|
|
10
|
-
const rangeBeforeFromAboveBlockStart = getRangeBeforeFromAboveBlockStart(editor, at);
|
|
11
|
-
if (rangeBeforeFromAboveBlockStart) {
|
|
12
|
-
const textFromAboveBlockStart = Editor.string(editor, rangeBeforeFromAboveBlockStart);
|
|
13
|
-
if (isUrl$1(textFromAboveBlockStart)) {
|
|
14
|
-
return {
|
|
15
|
-
at: rangeBeforeFromAboveBlockStart,
|
|
16
|
-
url: textFromAboveBlockStart,
|
|
17
|
-
};
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Last, find the first previous word as url.
|
|
22
|
-
*/
|
|
23
|
-
const beforeWordRange = getRangeBefore(editor, at, {
|
|
24
|
-
acrossPaths: true,
|
|
25
|
-
afterMatch: true,
|
|
26
|
-
match: ' ',
|
|
27
|
-
});
|
|
28
|
-
if (beforeWordRange) {
|
|
29
|
-
const beforeWordText = Editor.string(editor, beforeWordRange);
|
|
30
|
-
if (isUrl$1(beforeWordText)) {
|
|
31
|
-
return {
|
|
32
|
-
at: beforeWordRange,
|
|
33
|
-
url: beforeWordText,
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
const isSelectionInLink = editor => isNodesTypeIn(editor, [type]);
|
|
39
|
-
const insertLink = (editor, url, options = {}) => {
|
|
40
|
-
const { text = url } = options;
|
|
41
|
-
const link = {
|
|
42
|
-
type,
|
|
43
|
-
url: url.trim(),
|
|
44
|
-
children: [{ text }],
|
|
45
|
-
};
|
|
46
|
-
Transforms.insertNodes(editor, link, options);
|
|
47
|
-
};
|
|
48
|
-
const unwrapLink = (editor, options = {}) => unwrapNodesByTypes(editor, [type], options);
|
|
49
|
-
const wrapLink = (editor, url, options = {}) => {
|
|
50
|
-
const link = { type, url: url.trim(), children: [] };
|
|
51
|
-
wrapNodesWithUnhangRange(editor, link, Object.assign(Object.assign({}, options), { split: true }));
|
|
52
|
-
};
|
|
53
|
-
const upsertLink = (editor, url, options = {}) => {
|
|
54
|
-
const { at = editor.selection } = options;
|
|
55
|
-
if (!at) {
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
if (Range.isCollapsed(at)) {
|
|
59
|
-
if (wrappableVoidTypes) {
|
|
60
|
-
const [node, path] = Editor.node(editor, at.focus.path);
|
|
61
|
-
if (Text.isText(node) && !node.text) {
|
|
62
|
-
const [wrappableVoid, wrappableVoidPath] = getAboveByTypes(editor, wrappableVoidTypes, {
|
|
63
|
-
at: path,
|
|
64
|
-
}) || [];
|
|
65
|
-
if (wrappableVoid) {
|
|
66
|
-
unwrapLink(editor, { at: wrappableVoidPath });
|
|
67
|
-
wrapLink(editor, url, { at: wrappableVoidPath });
|
|
68
|
-
}
|
|
69
|
-
else {
|
|
70
|
-
insertLink(editor, url, { at });
|
|
71
|
-
Transforms.move(editor, { distance: url.length });
|
|
72
|
-
}
|
|
73
|
-
return;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
insertLink(editor, url, { at });
|
|
77
|
-
}
|
|
78
|
-
else {
|
|
79
|
-
unwrapLink(editor, { at });
|
|
80
|
-
wrapLink(editor, url, { at });
|
|
81
|
-
}
|
|
82
|
-
};
|
|
83
|
-
return {
|
|
84
|
-
type,
|
|
85
|
-
isUrl: isUrl$1,
|
|
86
|
-
getFirstPrevTextAsUrlAndRange,
|
|
87
|
-
isSelectionInLink,
|
|
88
|
-
insertLink,
|
|
89
|
-
unwrapLink,
|
|
90
|
-
wrapLink,
|
|
91
|
-
upsertLink,
|
|
92
|
-
with(editor) {
|
|
93
|
-
const { insertText, isInline, normalizeNode } = editor;
|
|
94
|
-
if (prevUrlToLinkAfterSpaceEntered) {
|
|
95
|
-
editor.insertText = (text) => {
|
|
96
|
-
var _a;
|
|
97
|
-
const { selection } = editor;
|
|
98
|
-
if (text === ' ' && selection && Range.isCollapsed(selection)) {
|
|
99
|
-
const shouldTransformedData = getFirstPrevTextAsUrlAndRange(editor, selection);
|
|
100
|
-
if (shouldTransformedData) {
|
|
101
|
-
const { at, url } = shouldTransformedData;
|
|
102
|
-
unwrapLink(editor, { at });
|
|
103
|
-
wrapLink(editor, url, {
|
|
104
|
-
at: Object.assign(Object.assign({}, at), {
|
|
105
|
-
/**
|
|
106
|
-
* Get a new selection here.
|
|
107
|
-
*/
|
|
108
|
-
focus: ((_a = editor.selection) === null || _a === void 0 ? void 0 : _a.focus) || at.focus }),
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
insertText(text);
|
|
113
|
-
};
|
|
114
|
-
}
|
|
115
|
-
editor.isInline = (element) => {
|
|
116
|
-
if (element.type !== type) {
|
|
117
|
-
return isInline(element);
|
|
118
|
-
}
|
|
119
|
-
if (!wrappableVoidTypes) {
|
|
120
|
-
return true;
|
|
121
|
-
}
|
|
122
|
-
return !element.children.some(child => Editor.isBlock(editor, child)
|
|
123
|
-
&& Editor.isVoid(editor, child)
|
|
124
|
-
&& wrappableVoidTypes.includes(child.type));
|
|
125
|
-
};
|
|
126
|
-
editor.normalizeNode = (entry) => {
|
|
127
|
-
const [node, path] = entry;
|
|
128
|
-
if (Element.isElement(node) && node.type === type) {
|
|
129
|
-
/**
|
|
130
|
-
* Remove invalid url.
|
|
131
|
-
*/
|
|
132
|
-
if (!isUrl$1(node.url)) {
|
|
133
|
-
Transforms.unwrapNodes(editor, { at: path });
|
|
134
|
-
return;
|
|
135
|
-
}
|
|
136
|
-
/**
|
|
137
|
-
* Remove empty content.
|
|
138
|
-
*/
|
|
139
|
-
if (Text.isTextList(node.children)) {
|
|
140
|
-
if (node.children.every(textNode => !textNode.text)) {
|
|
141
|
-
Transforms.unwrapNodes(editor, { at: path });
|
|
142
|
-
return;
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
normalizeNode(entry);
|
|
147
|
-
};
|
|
148
|
-
return editor;
|
|
149
|
-
},
|
|
150
|
-
};
|
|
5
|
+
function createLink({ type = LINK_TYPE, isUrl: isUrl$1 = isUrl, prevUrlToLinkAfterSpaceEntered = true, wrappableVoidTypes, } = {}) {
|
|
6
|
+
const getFirstPrevTextAsUrlAndRange = (editor, at) => {
|
|
7
|
+
/**
|
|
8
|
+
* First, find all text under the same lowest above block and before entered space.
|
|
9
|
+
*/
|
|
10
|
+
const rangeBeforeFromAboveBlockStart = getRangeBeforeFromAboveBlockStart(editor, at);
|
|
11
|
+
if (rangeBeforeFromAboveBlockStart) {
|
|
12
|
+
const textFromAboveBlockStart = Editor.string(editor, rangeBeforeFromAboveBlockStart);
|
|
13
|
+
if (isUrl$1(textFromAboveBlockStart)) {
|
|
14
|
+
return {
|
|
15
|
+
at: rangeBeforeFromAboveBlockStart,
|
|
16
|
+
url: textFromAboveBlockStart,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Last, find the first previous word as url.
|
|
22
|
+
*/
|
|
23
|
+
const beforeWordRange = getRangeBefore(editor, at, {
|
|
24
|
+
acrossPaths: true,
|
|
25
|
+
afterMatch: true,
|
|
26
|
+
match: ' ',
|
|
27
|
+
});
|
|
28
|
+
if (beforeWordRange) {
|
|
29
|
+
const beforeWordText = Editor.string(editor, beforeWordRange);
|
|
30
|
+
if (isUrl$1(beforeWordText)) {
|
|
31
|
+
return {
|
|
32
|
+
at: beforeWordRange,
|
|
33
|
+
url: beforeWordText,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
const isSelectionInLink = editor => isNodesTypeIn(editor, [type]);
|
|
39
|
+
const insertLink = (editor, url, options = {}) => {
|
|
40
|
+
const { text = url } = options;
|
|
41
|
+
const link = {
|
|
42
|
+
type,
|
|
43
|
+
url: url.trim(),
|
|
44
|
+
children: [{ text }],
|
|
45
|
+
};
|
|
46
|
+
Transforms.insertNodes(editor, link, options);
|
|
47
|
+
};
|
|
48
|
+
const unwrapLink = (editor, options = {}) => unwrapNodesByTypes(editor, [type], options);
|
|
49
|
+
const wrapLink = (editor, url, options = {}) => {
|
|
50
|
+
const link = { type, url: url.trim(), children: [] };
|
|
51
|
+
wrapNodesWithUnhangRange(editor, link, Object.assign(Object.assign({}, options), { split: true }));
|
|
52
|
+
};
|
|
53
|
+
const upsertLink = (editor, url, options = {}) => {
|
|
54
|
+
const { at = editor.selection } = options;
|
|
55
|
+
if (!at) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
if (Range.isCollapsed(at)) {
|
|
59
|
+
if (wrappableVoidTypes) {
|
|
60
|
+
const [node, path] = Editor.node(editor, at.focus.path);
|
|
61
|
+
if (Text.isText(node) && !node.text) {
|
|
62
|
+
const [wrappableVoid, wrappableVoidPath] = getAboveByTypes(editor, wrappableVoidTypes, {
|
|
63
|
+
at: path,
|
|
64
|
+
}) || [];
|
|
65
|
+
if (wrappableVoid) {
|
|
66
|
+
unwrapLink(editor, { at: wrappableVoidPath });
|
|
67
|
+
wrapLink(editor, url, { at: wrappableVoidPath });
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
insertLink(editor, url, { at });
|
|
71
|
+
Transforms.move(editor, { distance: url.length });
|
|
72
|
+
}
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
insertLink(editor, url, { at });
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
unwrapLink(editor, { at });
|
|
80
|
+
wrapLink(editor, url, { at });
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
return {
|
|
84
|
+
type,
|
|
85
|
+
isUrl: isUrl$1,
|
|
86
|
+
getFirstPrevTextAsUrlAndRange,
|
|
87
|
+
isSelectionInLink,
|
|
88
|
+
insertLink,
|
|
89
|
+
unwrapLink,
|
|
90
|
+
wrapLink,
|
|
91
|
+
upsertLink,
|
|
92
|
+
with(editor) {
|
|
93
|
+
const { insertText, isInline, normalizeNode } = editor;
|
|
94
|
+
if (prevUrlToLinkAfterSpaceEntered) {
|
|
95
|
+
editor.insertText = (text) => {
|
|
96
|
+
var _a;
|
|
97
|
+
const { selection } = editor;
|
|
98
|
+
if (text === ' ' && selection && Range.isCollapsed(selection)) {
|
|
99
|
+
const shouldTransformedData = getFirstPrevTextAsUrlAndRange(editor, selection);
|
|
100
|
+
if (shouldTransformedData) {
|
|
101
|
+
const { at, url } = shouldTransformedData;
|
|
102
|
+
unwrapLink(editor, { at });
|
|
103
|
+
wrapLink(editor, url, {
|
|
104
|
+
at: Object.assign(Object.assign({}, at), {
|
|
105
|
+
/**
|
|
106
|
+
* Get a new selection here.
|
|
107
|
+
*/
|
|
108
|
+
focus: ((_a = editor.selection) === null || _a === void 0 ? void 0 : _a.focus) || at.focus }),
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
insertText(text);
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
editor.isInline = (element) => {
|
|
116
|
+
if (element.type !== type) {
|
|
117
|
+
return isInline(element);
|
|
118
|
+
}
|
|
119
|
+
if (!wrappableVoidTypes) {
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
return !element.children.some(child => Editor.isBlock(editor, child)
|
|
123
|
+
&& Editor.isVoid(editor, child)
|
|
124
|
+
&& wrappableVoidTypes.includes(child.type));
|
|
125
|
+
};
|
|
126
|
+
editor.normalizeNode = (entry) => {
|
|
127
|
+
const [node, path] = entry;
|
|
128
|
+
if (Element.isElement(node) && node.type === type) {
|
|
129
|
+
/**
|
|
130
|
+
* Remove invalid url.
|
|
131
|
+
*/
|
|
132
|
+
if (!isUrl$1(node.url)) {
|
|
133
|
+
Transforms.unwrapNodes(editor, { at: path });
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Remove empty content.
|
|
138
|
+
*/
|
|
139
|
+
if (Text.isTextList(node.children)) {
|
|
140
|
+
if (node.children.every(textNode => !textNode.text)) {
|
|
141
|
+
Transforms.unwrapNodes(editor, { at: path });
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
normalizeNode(entry);
|
|
147
|
+
};
|
|
148
|
+
return editor;
|
|
149
|
+
},
|
|
150
|
+
};
|
|
151
151
|
}
|
|
152
152
|
|
|
153
153
|
export { createLink };
|
package/link/index.cjs.js
CHANGED
|
@@ -1,158 +1,156 @@
|
|
|
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
6
|
const LINK_TYPE = 'link';
|
|
9
7
|
|
|
10
|
-
function createLink({ type = LINK_TYPE, isUrl = utils.isUrl, prevUrlToLinkAfterSpaceEntered = true, wrappableVoidTypes, } = {}) {
|
|
11
|
-
const getFirstPrevTextAsUrlAndRange = (editor, at) => {
|
|
12
|
-
/**
|
|
13
|
-
* First, find all text under the same lowest above block and before entered space.
|
|
14
|
-
*/
|
|
15
|
-
const rangeBeforeFromAboveBlockStart = core.getRangeBeforeFromAboveBlockStart(editor, at);
|
|
16
|
-
if (rangeBeforeFromAboveBlockStart) {
|
|
17
|
-
const textFromAboveBlockStart = core.Editor.string(editor, rangeBeforeFromAboveBlockStart);
|
|
18
|
-
if (isUrl(textFromAboveBlockStart)) {
|
|
19
|
-
return {
|
|
20
|
-
at: rangeBeforeFromAboveBlockStart,
|
|
21
|
-
url: textFromAboveBlockStart,
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* Last, find the first previous word as url.
|
|
27
|
-
*/
|
|
28
|
-
const beforeWordRange = core.getRangeBefore(editor, at, {
|
|
29
|
-
acrossPaths: true,
|
|
30
|
-
afterMatch: true,
|
|
31
|
-
match: ' ',
|
|
32
|
-
});
|
|
33
|
-
if (beforeWordRange) {
|
|
34
|
-
const beforeWordText = core.Editor.string(editor, beforeWordRange);
|
|
35
|
-
if (isUrl(beforeWordText)) {
|
|
36
|
-
return {
|
|
37
|
-
at: beforeWordRange,
|
|
38
|
-
url: beforeWordText,
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
};
|
|
43
|
-
const isSelectionInLink = editor => core.isNodesTypeIn(editor, [type]);
|
|
44
|
-
const insertLink = (editor, url, options = {}) => {
|
|
45
|
-
const { text = url } = options;
|
|
46
|
-
const link = {
|
|
47
|
-
type,
|
|
48
|
-
url: url.trim(),
|
|
49
|
-
children: [{ text }],
|
|
50
|
-
};
|
|
51
|
-
core.Transforms.insertNodes(editor, link, options);
|
|
52
|
-
};
|
|
53
|
-
const unwrapLink = (editor, options = {}) => core.unwrapNodesByTypes(editor, [type], options);
|
|
54
|
-
const wrapLink = (editor, url, options = {}) => {
|
|
55
|
-
const link = { type, url: url.trim(), children: [] };
|
|
56
|
-
core.wrapNodesWithUnhangRange(editor, link, Object.assign(Object.assign({}, options), { split: true }));
|
|
57
|
-
};
|
|
58
|
-
const upsertLink = (editor, url, options = {}) => {
|
|
59
|
-
const { at = editor.selection } = options;
|
|
60
|
-
if (!at) {
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
if (core.Range.isCollapsed(at)) {
|
|
64
|
-
if (wrappableVoidTypes) {
|
|
65
|
-
const [node, path] = core.Editor.node(editor, at.focus.path);
|
|
66
|
-
if (core.Text.isText(node) && !node.text) {
|
|
67
|
-
const [wrappableVoid, wrappableVoidPath] = core.getAboveByTypes(editor, wrappableVoidTypes, {
|
|
68
|
-
at: path,
|
|
69
|
-
}) || [];
|
|
70
|
-
if (wrappableVoid) {
|
|
71
|
-
unwrapLink(editor, { at: wrappableVoidPath });
|
|
72
|
-
wrapLink(editor, url, { at: wrappableVoidPath });
|
|
73
|
-
}
|
|
74
|
-
else {
|
|
75
|
-
insertLink(editor, url, { at });
|
|
76
|
-
core.Transforms.move(editor, { distance: url.length });
|
|
77
|
-
}
|
|
78
|
-
return;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
insertLink(editor, url, { at });
|
|
82
|
-
}
|
|
83
|
-
else {
|
|
84
|
-
unwrapLink(editor, { at });
|
|
85
|
-
wrapLink(editor, url, { at });
|
|
86
|
-
}
|
|
87
|
-
};
|
|
88
|
-
return {
|
|
89
|
-
type,
|
|
90
|
-
isUrl,
|
|
91
|
-
getFirstPrevTextAsUrlAndRange,
|
|
92
|
-
isSelectionInLink,
|
|
93
|
-
insertLink,
|
|
94
|
-
unwrapLink,
|
|
95
|
-
wrapLink,
|
|
96
|
-
upsertLink,
|
|
97
|
-
with(editor) {
|
|
98
|
-
const { insertText, isInline, normalizeNode } = editor;
|
|
99
|
-
if (prevUrlToLinkAfterSpaceEntered) {
|
|
100
|
-
editor.insertText = (text) => {
|
|
101
|
-
var _a;
|
|
102
|
-
const { selection } = editor;
|
|
103
|
-
if (text === ' ' && selection && core.Range.isCollapsed(selection)) {
|
|
104
|
-
const shouldTransformedData = getFirstPrevTextAsUrlAndRange(editor, selection);
|
|
105
|
-
if (shouldTransformedData) {
|
|
106
|
-
const { at, url } = shouldTransformedData;
|
|
107
|
-
unwrapLink(editor, { at });
|
|
108
|
-
wrapLink(editor, url, {
|
|
109
|
-
at: Object.assign(Object.assign({}, at), {
|
|
110
|
-
/**
|
|
111
|
-
* Get a new selection here.
|
|
112
|
-
*/
|
|
113
|
-
focus: ((_a = editor.selection) === null || _a === void 0 ? void 0 : _a.focus) || at.focus }),
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
insertText(text);
|
|
118
|
-
};
|
|
119
|
-
}
|
|
120
|
-
editor.isInline = (element) => {
|
|
121
|
-
if (element.type !== type) {
|
|
122
|
-
return isInline(element);
|
|
123
|
-
}
|
|
124
|
-
if (!wrappableVoidTypes) {
|
|
125
|
-
return true;
|
|
126
|
-
}
|
|
127
|
-
return !element.children.some(child => core.Editor.isBlock(editor, child)
|
|
128
|
-
&& core.Editor.isVoid(editor, child)
|
|
129
|
-
&& wrappableVoidTypes.includes(child.type));
|
|
130
|
-
};
|
|
131
|
-
editor.normalizeNode = (entry) => {
|
|
132
|
-
const [node, path] = entry;
|
|
133
|
-
if (core.Element.isElement(node) && node.type === type) {
|
|
134
|
-
/**
|
|
135
|
-
* Remove invalid url.
|
|
136
|
-
*/
|
|
137
|
-
if (!isUrl(node.url)) {
|
|
138
|
-
core.Transforms.unwrapNodes(editor, { at: path });
|
|
139
|
-
return;
|
|
140
|
-
}
|
|
141
|
-
/**
|
|
142
|
-
* Remove empty content.
|
|
143
|
-
*/
|
|
144
|
-
if (core.Text.isTextList(node.children)) {
|
|
145
|
-
if (node.children.every(textNode => !textNode.text)) {
|
|
146
|
-
core.Transforms.unwrapNodes(editor, { at: path });
|
|
147
|
-
return;
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
normalizeNode(entry);
|
|
152
|
-
};
|
|
153
|
-
return editor;
|
|
154
|
-
},
|
|
155
|
-
};
|
|
8
|
+
function createLink({ type = LINK_TYPE, isUrl = utils.isUrl, prevUrlToLinkAfterSpaceEntered = true, wrappableVoidTypes, } = {}) {
|
|
9
|
+
const getFirstPrevTextAsUrlAndRange = (editor, at) => {
|
|
10
|
+
/**
|
|
11
|
+
* First, find all text under the same lowest above block and before entered space.
|
|
12
|
+
*/
|
|
13
|
+
const rangeBeforeFromAboveBlockStart = core.getRangeBeforeFromAboveBlockStart(editor, at);
|
|
14
|
+
if (rangeBeforeFromAboveBlockStart) {
|
|
15
|
+
const textFromAboveBlockStart = core.Editor.string(editor, rangeBeforeFromAboveBlockStart);
|
|
16
|
+
if (isUrl(textFromAboveBlockStart)) {
|
|
17
|
+
return {
|
|
18
|
+
at: rangeBeforeFromAboveBlockStart,
|
|
19
|
+
url: textFromAboveBlockStart,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Last, find the first previous word as url.
|
|
25
|
+
*/
|
|
26
|
+
const beforeWordRange = core.getRangeBefore(editor, at, {
|
|
27
|
+
acrossPaths: true,
|
|
28
|
+
afterMatch: true,
|
|
29
|
+
match: ' ',
|
|
30
|
+
});
|
|
31
|
+
if (beforeWordRange) {
|
|
32
|
+
const beforeWordText = core.Editor.string(editor, beforeWordRange);
|
|
33
|
+
if (isUrl(beforeWordText)) {
|
|
34
|
+
return {
|
|
35
|
+
at: beforeWordRange,
|
|
36
|
+
url: beforeWordText,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
const isSelectionInLink = editor => core.isNodesTypeIn(editor, [type]);
|
|
42
|
+
const insertLink = (editor, url, options = {}) => {
|
|
43
|
+
const { text = url } = options;
|
|
44
|
+
const link = {
|
|
45
|
+
type,
|
|
46
|
+
url: url.trim(),
|
|
47
|
+
children: [{ text }],
|
|
48
|
+
};
|
|
49
|
+
core.Transforms.insertNodes(editor, link, options);
|
|
50
|
+
};
|
|
51
|
+
const unwrapLink = (editor, options = {}) => core.unwrapNodesByTypes(editor, [type], options);
|
|
52
|
+
const wrapLink = (editor, url, options = {}) => {
|
|
53
|
+
const link = { type, url: url.trim(), children: [] };
|
|
54
|
+
core.wrapNodesWithUnhangRange(editor, link, Object.assign(Object.assign({}, options), { split: true }));
|
|
55
|
+
};
|
|
56
|
+
const upsertLink = (editor, url, options = {}) => {
|
|
57
|
+
const { at = editor.selection } = options;
|
|
58
|
+
if (!at) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
if (core.Range.isCollapsed(at)) {
|
|
62
|
+
if (wrappableVoidTypes) {
|
|
63
|
+
const [node, path] = core.Editor.node(editor, at.focus.path);
|
|
64
|
+
if (core.Text.isText(node) && !node.text) {
|
|
65
|
+
const [wrappableVoid, wrappableVoidPath] = core.getAboveByTypes(editor, wrappableVoidTypes, {
|
|
66
|
+
at: path,
|
|
67
|
+
}) || [];
|
|
68
|
+
if (wrappableVoid) {
|
|
69
|
+
unwrapLink(editor, { at: wrappableVoidPath });
|
|
70
|
+
wrapLink(editor, url, { at: wrappableVoidPath });
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
insertLink(editor, url, { at });
|
|
74
|
+
core.Transforms.move(editor, { distance: url.length });
|
|
75
|
+
}
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
insertLink(editor, url, { at });
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
unwrapLink(editor, { at });
|
|
83
|
+
wrapLink(editor, url, { at });
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
return {
|
|
87
|
+
type,
|
|
88
|
+
isUrl,
|
|
89
|
+
getFirstPrevTextAsUrlAndRange,
|
|
90
|
+
isSelectionInLink,
|
|
91
|
+
insertLink,
|
|
92
|
+
unwrapLink,
|
|
93
|
+
wrapLink,
|
|
94
|
+
upsertLink,
|
|
95
|
+
with(editor) {
|
|
96
|
+
const { insertText, isInline, normalizeNode } = editor;
|
|
97
|
+
if (prevUrlToLinkAfterSpaceEntered) {
|
|
98
|
+
editor.insertText = (text) => {
|
|
99
|
+
var _a;
|
|
100
|
+
const { selection } = editor;
|
|
101
|
+
if (text === ' ' && selection && core.Range.isCollapsed(selection)) {
|
|
102
|
+
const shouldTransformedData = getFirstPrevTextAsUrlAndRange(editor, selection);
|
|
103
|
+
if (shouldTransformedData) {
|
|
104
|
+
const { at, url } = shouldTransformedData;
|
|
105
|
+
unwrapLink(editor, { at });
|
|
106
|
+
wrapLink(editor, url, {
|
|
107
|
+
at: Object.assign(Object.assign({}, at), {
|
|
108
|
+
/**
|
|
109
|
+
* Get a new selection here.
|
|
110
|
+
*/
|
|
111
|
+
focus: ((_a = editor.selection) === null || _a === void 0 ? void 0 : _a.focus) || at.focus }),
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
insertText(text);
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
editor.isInline = (element) => {
|
|
119
|
+
if (element.type !== type) {
|
|
120
|
+
return isInline(element);
|
|
121
|
+
}
|
|
122
|
+
if (!wrappableVoidTypes) {
|
|
123
|
+
return true;
|
|
124
|
+
}
|
|
125
|
+
return !element.children.some(child => core.Editor.isBlock(editor, child)
|
|
126
|
+
&& core.Editor.isVoid(editor, child)
|
|
127
|
+
&& wrappableVoidTypes.includes(child.type));
|
|
128
|
+
};
|
|
129
|
+
editor.normalizeNode = (entry) => {
|
|
130
|
+
const [node, path] = entry;
|
|
131
|
+
if (core.Element.isElement(node) && node.type === type) {
|
|
132
|
+
/**
|
|
133
|
+
* Remove invalid url.
|
|
134
|
+
*/
|
|
135
|
+
if (!isUrl(node.url)) {
|
|
136
|
+
core.Transforms.unwrapNodes(editor, { at: path });
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Remove empty content.
|
|
141
|
+
*/
|
|
142
|
+
if (core.Text.isTextList(node.children)) {
|
|
143
|
+
if (node.children.every(textNode => !textNode.text)) {
|
|
144
|
+
core.Transforms.unwrapNodes(editor, { at: path });
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
normalizeNode(entry);
|
|
150
|
+
};
|
|
151
|
+
return editor;
|
|
152
|
+
},
|
|
153
|
+
};
|
|
156
154
|
}
|
|
157
155
|
|
|
158
156
|
exports.LINK_TYPE = LINK_TYPE;
|
package/link/typings.d.ts
CHANGED
|
@@ -5,8 +5,8 @@ export interface LinkElement extends QuadratsElement, WithElementType {
|
|
|
5
5
|
export interface LinkInsertLinkOptions extends TransformsInsertNodesOptions {
|
|
6
6
|
text?: string;
|
|
7
7
|
}
|
|
8
|
-
export
|
|
9
|
-
export
|
|
8
|
+
export type LinkUnwrapLinkOptions = UnwrapNodeByTypesOptions;
|
|
9
|
+
export type LinkWrapLinkOptions = Omit<TransformsWrapNodesOptions, 'split'>;
|
|
10
10
|
export interface LinkUpsertLinkOptions {
|
|
11
11
|
at?: Range;
|
|
12
12
|
}
|