@blocklet/editor 2.0.81 → 2.0.83

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.
@@ -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 default Bookmark;
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, { onClick: () => window.open(url, '_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 }) }))] })] }));
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, { onClick: () => window.open(url, '_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})` } })] }));
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.div `
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 default Bookmark;
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
- decorate(_editor: LexicalEditor, config: EditorConfig): JSX.Element;
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
- decorate(_editor, config) {
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.81",
3
+ "version": "2.0.83",
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.81",
43
+ "@blocklet/pdf": "2.0.83",
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": "67a40ce5fb0eba89e415501e77c175a380be3322"
116
+ "gitHead": "ffe6740390580b8e886bb350a92c30c0b86fa62a"
117
117
  }