@blocklet/editor 2.0.81 → 2.0.82
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/ext/BookmarkPlugin/Bookmark.d.ts +5 -2
- package/lib/ext/BookmarkPlugin/Bookmark.js +23 -5
- package/lib/ext/BookmarkPlugin/BookmarkNode.d.ts +4 -2
- package/lib/ext/BookmarkPlugin/BookmarkNode.js +18 -4
- package/lib/main/plugins/MarkdownTransformers/index.d.ts +1 -0
- package/lib/main/plugins/MarkdownTransformers/index.js +20 -0
- package/package.json +3 -3
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
2
|
import type { BookmarkInfo } from './BookmarkNode';
|
|
3
|
-
declare function Bookmark({ url, title, description, image, favicon, loading }: BookmarkInfo): JSX.Element;
|
|
4
|
-
export
|
|
3
|
+
export declare function Bookmark({ url, title, description, image, favicon, loading }: BookmarkInfo): JSX.Element;
|
|
4
|
+
export declare function BookmarkLoader({ url, onLoaded }: {
|
|
5
|
+
url: string;
|
|
6
|
+
onLoaded: (info: BookmarkInfo) => void;
|
|
7
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -2,6 +2,9 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import styled from '@emotion/styled';
|
|
3
3
|
import { Icon } from '@iconify/react';
|
|
4
4
|
import { Box, CircularProgress } from '@mui/material';
|
|
5
|
+
import { useRequest } from 'ahooks';
|
|
6
|
+
import { useEditorConfig } from '../../config';
|
|
7
|
+
import { fetchOpenGraphInfo } from '../utils';
|
|
5
8
|
const isGithubRepo = (url) => {
|
|
6
9
|
const reg = /^https?:\/\/github.com\//;
|
|
7
10
|
return reg.test(url);
|
|
@@ -14,7 +17,7 @@ const getHost = (url) => {
|
|
|
14
17
|
return url;
|
|
15
18
|
}
|
|
16
19
|
};
|
|
17
|
-
function Bookmark({ url, title, description, image, favicon, loading }) {
|
|
20
|
+
export function Bookmark({ url, title, description, image, favicon, loading }) {
|
|
18
21
|
// title 显示:
|
|
19
22
|
// - 有 title 值则直接显示
|
|
20
23
|
// - loading 状态显示 "Fetching preview"
|
|
@@ -24,18 +27,20 @@ function Bookmark({ url, title, description, image, favicon, loading }) {
|
|
|
24
27
|
return (_jsxs(Box, { className: "be-bookmark-title be-bookmark-ellipsis", sx: { display: 'flex', alignItems: 'center', gap: 1 }, children: [loading && _jsx(CircularProgress, { size: 14, sx: { color: 'grey.400' } }), _jsx(Box, { component: "span", sx: { color: loading ? 'grey.700' : 'inherit' }, children: previewTitle })] }));
|
|
25
28
|
};
|
|
26
29
|
if (isGithubRepo(url)) {
|
|
27
|
-
return (_jsxs(Root, {
|
|
30
|
+
return (_jsxs(Root, { href: url, target: "_blank", className: "github-bookmark", children: [image && (_jsxs("div", { className: "be-github-image", children: [_jsx(Image, { src: image }), _jsx(Icon, { icon: "mdi:github", style: { fontSize: 18 }, className: "be-github-image-icon" })] })), _jsxs("div", { className: "be-bookmark-texts", children: [renderTitle(), description && _jsx("div", { className: "be-bookmark-description be-bookmark-clamp2", children: description }), loading && (_jsx(Box, { className: "be-bookmark-url-content", sx: { pt: 1 }, children: _jsx("div", { className: "be-bookmark-url be-bookmark-ellipsis", children: url }) }))] })] }));
|
|
28
31
|
}
|
|
29
|
-
return (_jsxs(Root, {
|
|
32
|
+
return (_jsxs(Root, { href: url, target: "_blank", children: [_jsxs("div", { className: "be-bookmark-texts", children: [renderTitle(), _jsx("div", { className: "be-bookmark-description be-bookmark-clamp2", children: description }), _jsxs("div", { className: "be-bookmark-url-content", children: [favicon && _jsx("img", { src: favicon, alt: "favicon", className: "be-bookmark-favicon" }), _jsx("div", { className: "be-bookmark-url be-bookmark-ellipsis", children: url })] })] }), image && _jsx("div", { className: "be-bookmark-image", style: { backgroundImage: `url(${image})` } })] }));
|
|
30
33
|
}
|
|
31
|
-
const Root = styled.
|
|
34
|
+
const Root = styled.a `
|
|
32
35
|
box-sizing: border-box;
|
|
33
36
|
display: inline-flex;
|
|
34
37
|
width: 100%;
|
|
35
38
|
margin: 8px 0;
|
|
36
39
|
border: 1px solid rgba(55, 53, 47, 0.16);
|
|
37
40
|
overflow: hidden;
|
|
41
|
+
color: inherit;
|
|
38
42
|
border-radius: 4px;
|
|
43
|
+
text-decoration: none;
|
|
39
44
|
cursor: pointer;
|
|
40
45
|
|
|
41
46
|
:hover {
|
|
@@ -153,4 +158,17 @@ const Image = styled.img `
|
|
|
153
158
|
left: 0;
|
|
154
159
|
object-fit: cover;
|
|
155
160
|
`;
|
|
156
|
-
export
|
|
161
|
+
export function BookmarkLoader({ url, onLoaded }) {
|
|
162
|
+
const { openGraphEndpoint } = useEditorConfig();
|
|
163
|
+
const { data, loading } = useRequest(async () => {
|
|
164
|
+
if (!openGraphEndpoint) {
|
|
165
|
+
return null;
|
|
166
|
+
}
|
|
167
|
+
const openGraphInfo = await fetchOpenGraphInfo(openGraphEndpoint, url);
|
|
168
|
+
if (openGraphInfo) {
|
|
169
|
+
onLoaded(openGraphInfo);
|
|
170
|
+
}
|
|
171
|
+
return openGraphInfo;
|
|
172
|
+
});
|
|
173
|
+
return _jsx(Bookmark, { url: url, title: "", loading: loading || !data, ...data });
|
|
174
|
+
}
|
|
@@ -8,6 +8,7 @@ export interface BookmarkInfo {
|
|
|
8
8
|
image?: string;
|
|
9
9
|
favicon?: string;
|
|
10
10
|
loading?: boolean;
|
|
11
|
+
selfLoad?: boolean;
|
|
11
12
|
}
|
|
12
13
|
export type SerializedBookmarkNode = Spread<{
|
|
13
14
|
bookmark: BookmarkInfo;
|
|
@@ -26,8 +27,9 @@ export declare class BookmarkNode extends DecoratorBlockNode {
|
|
|
26
27
|
updateDOM(): false;
|
|
27
28
|
getId(): string;
|
|
28
29
|
getTextContent(_includeInert?: boolean | undefined, _includeDirectionless?: false | undefined): string;
|
|
29
|
-
|
|
30
|
+
setBookmark(bookmark: BookmarkInfo): void;
|
|
31
|
+
decorate(editor: LexicalEditor, config: EditorConfig): JSX.Element;
|
|
30
32
|
isInline(): false;
|
|
31
33
|
}
|
|
32
|
-
export declare function $createBookmarkNode(bookmark: BookmarkInfo): BookmarkNode;
|
|
34
|
+
export declare function $createBookmarkNode(bookmark: BookmarkInfo | string): BookmarkNode;
|
|
33
35
|
export declare function $isBookmarkNode(node: BookmarkNode | LexicalNode | null | undefined): node is BookmarkNode;
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { BlockWithAlignableContents } from '@lexical/react/LexicalBlockWithAlignableContents';
|
|
3
3
|
import { DecoratorBlockNode } from '@lexical/react/LexicalDecoratorBlockNode';
|
|
4
|
-
import Bookmark from './Bookmark';
|
|
5
|
-
function BookmarkComponent({ className, format, nodeKey, bookmark }) {
|
|
4
|
+
import { Bookmark, BookmarkLoader } from './Bookmark';
|
|
5
|
+
function BookmarkComponent({ className, format, nodeKey, bookmark, onLoaded }) {
|
|
6
|
+
if (bookmark.selfLoad) {
|
|
7
|
+
return (_jsx(BlockWithAlignableContents, { className: className, format: format, nodeKey: nodeKey, children: _jsx(BookmarkLoader, { url: bookmark.url, onLoaded: onLoaded }) }));
|
|
8
|
+
}
|
|
6
9
|
return (_jsx(BlockWithAlignableContents, { className: className, format: format, nodeKey: nodeKey, children: _jsx(Bookmark, { url: bookmark.url, title: bookmark.title, description: bookmark.description, image: bookmark.image, favicon: bookmark.favicon, loading: bookmark.loading }) }));
|
|
7
10
|
}
|
|
8
11
|
function convertBookmarkElement(domNode) {
|
|
@@ -76,19 +79,30 @@ export class BookmarkNode extends DecoratorBlockNode {
|
|
|
76
79
|
getTextContent(_includeInert, _includeDirectionless) {
|
|
77
80
|
return this.__bookmark.url;
|
|
78
81
|
}
|
|
79
|
-
|
|
82
|
+
setBookmark(bookmark) {
|
|
83
|
+
const writable = this.getWritable();
|
|
84
|
+
writable.__bookmark = bookmark;
|
|
85
|
+
}
|
|
86
|
+
decorate(editor, config) {
|
|
80
87
|
const embedBlockTheme = config.theme.embedBlock || {};
|
|
81
88
|
const className = {
|
|
82
89
|
base: embedBlockTheme.base || '',
|
|
83
90
|
focus: embedBlockTheme.focus || '',
|
|
84
91
|
};
|
|
85
|
-
return (_jsx(BookmarkComponent, { className: className, format: this.__format, nodeKey: this.getKey(), bookmark: this.__bookmark
|
|
92
|
+
return (_jsx(BookmarkComponent, { className: className, format: this.__format, nodeKey: this.getKey(), bookmark: this.__bookmark, onLoaded: (bookmark) => {
|
|
93
|
+
editor.update(() => {
|
|
94
|
+
this.setBookmark({ ...bookmark, url: this.__bookmark.url, selfLoad: false });
|
|
95
|
+
});
|
|
96
|
+
} }));
|
|
86
97
|
}
|
|
87
98
|
isInline() {
|
|
88
99
|
return false;
|
|
89
100
|
}
|
|
90
101
|
}
|
|
91
102
|
export function $createBookmarkNode(bookmark) {
|
|
103
|
+
if (typeof bookmark === 'string') {
|
|
104
|
+
return new BookmarkNode({ url: bookmark, title: '', loading: true, selfLoad: true });
|
|
105
|
+
}
|
|
92
106
|
return new BookmarkNode(bookmark);
|
|
93
107
|
}
|
|
94
108
|
export function $isBookmarkNode(node) {
|
|
@@ -11,4 +11,5 @@ export declare const IMAGE: TextMatchTransformer;
|
|
|
11
11
|
export declare const EQUATION: TextMatchTransformer;
|
|
12
12
|
export declare const TWEET: ElementTransformer;
|
|
13
13
|
export declare const TABLE: ElementTransformer;
|
|
14
|
+
export declare const BOOKMARK: TextMatchTransformer;
|
|
14
15
|
export declare const PLAYGROUND_TRANSFORMERS: Array<Transformer>;
|
|
@@ -12,6 +12,7 @@ import { $createParagraphNode, $createTextNode, $isElementNode, $isParagraphNode
|
|
|
12
12
|
import { $createEquationNode, $isEquationNode, EquationNode } from '../../nodes/EquationNode';
|
|
13
13
|
import { $createImageNode, $isImageNode, ImageNode } from '../../nodes/ImageNode';
|
|
14
14
|
import { $createTweetNode, $isTweetNode, TweetNode } from '../../nodes/TweetNode';
|
|
15
|
+
import { $createBookmarkNode, $isBookmarkNode, BookmarkNode } from '../../../ext/BookmarkPlugin/BookmarkNode';
|
|
15
16
|
export const HR = {
|
|
16
17
|
dependencies: [HorizontalRuleNode],
|
|
17
18
|
export: (node) => {
|
|
@@ -184,7 +185,26 @@ const mapToTableCells = (textContent) => {
|
|
|
184
185
|
}
|
|
185
186
|
return match[1].split('|').map((text) => createTableCell(text));
|
|
186
187
|
};
|
|
188
|
+
export const BOOKMARK = {
|
|
189
|
+
dependencies: [BookmarkNode],
|
|
190
|
+
export: (node, exportChildren, exportFormat) => {
|
|
191
|
+
if (!$isBookmarkNode(node)) {
|
|
192
|
+
return null;
|
|
193
|
+
}
|
|
194
|
+
return `[[]](${node.getId()})`;
|
|
195
|
+
},
|
|
196
|
+
importRegExp: /(?:\[\[([^[]+)\])(?:\((?:([^()\s]+)(?:\s"((?:[^"]*\\")*[^"]*)"\s*)?)\))/,
|
|
197
|
+
regExp: /(?:\[\[([^[]+)\])(?:\((?:([^()\s]+)(?:\s"((?:[^"]*\\")*[^"]*)"\s*)?)\))$/,
|
|
198
|
+
replace: (textNode, match) => {
|
|
199
|
+
const [, , linkUrl] = match;
|
|
200
|
+
const bookmarkNode = $createBookmarkNode(linkUrl);
|
|
201
|
+
textNode.replace(bookmarkNode);
|
|
202
|
+
},
|
|
203
|
+
trigger: ')',
|
|
204
|
+
type: 'text-match',
|
|
205
|
+
};
|
|
187
206
|
export const PLAYGROUND_TRANSFORMERS = [
|
|
207
|
+
BOOKMARK,
|
|
188
208
|
TABLE,
|
|
189
209
|
HR,
|
|
190
210
|
IMAGE,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blocklet/editor",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.82",
|
|
4
4
|
"main": "lib/index.js",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"dev": "npm run storybook",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"@arcblock/ux": "^2.10.6",
|
|
41
41
|
"@blocklet/embed": "^0.1.11",
|
|
42
42
|
"@blocklet/pages-kit": "^0.2.377",
|
|
43
|
-
"@blocklet/pdf": "2.0.
|
|
43
|
+
"@blocklet/pdf": "2.0.82",
|
|
44
44
|
"@excalidraw/excalidraw": "^0.14.2",
|
|
45
45
|
"@iconify/iconify": "^3.0.1",
|
|
46
46
|
"@iconify/icons-tabler": "^1.2.95",
|
|
@@ -113,5 +113,5 @@
|
|
|
113
113
|
"react": "*",
|
|
114
114
|
"react-dom": "*"
|
|
115
115
|
},
|
|
116
|
-
"gitHead": "
|
|
116
|
+
"gitHead": "3726449a47f54674d489b95b6ae6895412c3ebc2"
|
|
117
117
|
}
|