@wangeditor-next/plugin-link-card 3.0.0 → 6.2.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/dist/basic-modules/src/constants/icon-svg.d.ts +2 -0
- package/dist/basic-modules/src/locale/en.d.ts +2 -0
- package/dist/basic-modules/src/locale/zh-CN.d.ts +2 -0
- package/dist/basic-modules/src/modules/header/parse-elem-html.d.ts +2 -2
- package/dist/basic-modules/src/modules/text-style/custom-types.d.ts +2 -0
- package/dist/basic-modules/src/modules/text-style/menu/EmphasisDotMenu.d.ts +11 -0
- package/dist/basic-modules/src/modules/text-style/menu/WavyUnderlineMenu.d.ts +11 -0
- package/dist/basic-modules/src/modules/text-style/menu/index.d.ts +10 -0
- package/dist/basic-modules/src/modules/text-style/render-style.d.ts +2 -1
- package/dist/basic-modules/src/modules/text-style/style-constants.d.ts +35 -0
- package/dist/basic-modules/src/modules/text-style/style-to-html.d.ts +2 -1
- package/dist/basic-modules/src/utils/dom.d.ts +1 -1
- package/dist/code-highlight/src/utils/dom.d.ts +1 -1
- package/dist/core/src/config/interface.d.ts +32 -2
- package/dist/core/src/editor/interface.d.ts +16 -3
- package/dist/core/src/index.d.ts +4 -2
- package/dist/core/src/render/helper.d.ts +1 -2
- package/dist/core/src/to-html/index.d.ts +12 -0
- package/dist/core/src/utils/dom.d.ts +1 -1
- package/dist/editor/src/Boot.d.ts +2 -2
- package/dist/editor/src/index.d.ts +7 -0
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/list-module/src/locale/en.d.ts +3 -0
- package/dist/list-module/src/locale/zh-CN.d.ts +3 -0
- package/dist/list-module/src/module/custom-types.d.ts +13 -0
- package/dist/list-module/src/module/helpers.d.ts +14 -4
- package/dist/list-module/src/module/html-transform.d.ts +10 -0
- package/dist/list-module/src/module/menu/BaseMenu.d.ts +2 -2
- package/dist/list-module/src/module/outline-actions.d.ts +9 -0
- package/dist/list-module/src/module/parse-elem-html.d.ts +1 -2
- package/dist/list-module/src/module/plugin.d.ts +1 -1
- package/dist/list-module/src/utils/maps.d.ts +2 -1
- package/dist/table-module/src/module/menu/CellProperty.d.ts +2 -1
- package/dist/table-module/src/module/menu/TableProperty.d.ts +2 -1
- package/dist/table-module/src/module/render-elem/selection-overlay.d.ts +21 -0
- package/dist/table-module/src/module/weak-maps.d.ts +3 -2
- package/dist/table-module/src/utils/dom.d.ts +1 -1
- package/dist/table-module/src/utils/options.d.ts +3 -12
- package/dist/upload-image-module/src/utils/dom.d.ts +1 -1
- package/dist/video-module/src/utils/dom.d.ts +1 -1
- package/package.json +3 -3
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
*/
|
|
10
10
|
export declare const BOLD_SVG = "<svg viewBox=\"0 0 1024 1024\"><path d=\"M707.872 484.64A254.88 254.88 0 0 0 768 320c0-141.152-114.848-256-256-256H192v896h384c141.152 0 256-114.848 256-256a256.096 256.096 0 0 0-124.128-219.36zM384 192h101.504c55.968 0 101.504 57.408 101.504 128s-45.536 128-101.504 128H384V192z m159.008 640H384v-256h159.008c58.464 0 106.016 57.408 106.016 128s-47.552 128-106.016 128z\"></path></svg>";
|
|
11
11
|
export declare const UNDER_LINE_SVG = "<svg viewBox=\"0 0 1024 1024\"><path d=\"M704 64l128 0 0 416c0 159.072-143.264 288-320 288s-320-128.928-320-288l0-416 128 0 0 416c0 40.16 18.24 78.688 51.36 108.512 36.896 33.216 86.848 51.488 140.64 51.488s103.744-18.304 140.64-51.488c33.12-29.792 51.36-68.352 51.36-108.512l0-416zM192 832l640 0 0 128-640 0z\"></path></svg>";
|
|
12
|
+
export declare const WAVY_UNDERLINE_SVG = "<svg viewBox=\"0 0 1024 1024\"><path d=\"M64 704c64-96 128-96 192 0s128 96 192 0 128-96 192 0 128 96 192 0 128-96 192 0v128c-64 96-128 96-192 0s-128-96-192 0-128 96-192 0-128-96-192 0-128 96-192 0V704z\"></path></svg>";
|
|
13
|
+
export declare const EMPHASIS_DOT_SVG = "<svg viewBox=\"0 0 1024 1024\"><path d=\"M256 128h128v512H256zM448 128h128v512H448zM640 128h128v512H640z\"></path><path d=\"M320 832m-64 0a64 64 0 1 0 128 0 64 64 0 0 0-128 0zM512 832m-64 0a64 64 0 1 0 128 0 64 64 0 0 0-128 0zM704 832m-64 0a64 64 0 1 0 128 0 64 64 0 0 0-128 0z\"></path></svg>";
|
|
12
14
|
export declare const ITALIC_SVG = "<svg viewBox=\"0 0 1024 1024\"><path d=\"M896 64v64h-128L448 896h128v64H128v-64h128L576 128h-128V64z\"></path></svg>";
|
|
13
15
|
export declare const THROUGH_SVG = "<svg viewBox=\"0 0 1024 1024\"><path d=\"M1024 512v64h-234.496c27.52 38.496 42.496 82.688 42.496 128 0 70.88-36.672 139.04-100.576 186.976C672.064 935.488 594.144 960 512 960s-160.064-24.512-219.424-69.024C228.64 843.04 192 774.88 192 704h128c0 69.376 87.936 128 192 128s192-58.624 192-128-87.936-128-192-128H0v-64h299.52a385.984 385.984 0 0 1-6.944-5.024C228.64 459.04 192 390.88 192 320s36.672-139.04 100.576-186.976C351.936 88.512 429.856 64 512 64s160.064 24.512 219.424 69.024C795.328 180.96 832 249.12 832 320h-128c0-69.376-87.936-128-192-128s-192 58.624-192 128 87.936 128 192 128c78.976 0 154.048 22.688 212.48 64H1024z\"></path></svg>";
|
|
14
16
|
export declare const CODE_SVG = "<svg viewBox=\"0 0 1024 1024\"><path d=\"M576 736l96 96 320-320L672 192l-96 96 224 224zM448 288l-96-96L32 512l320 320 96-96-224-224z\"></path></svg>";
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import { IDomEditor } from '@wangeditor-next/core';
|
|
6
6
|
import { Descendant } from 'slate';
|
|
7
7
|
import { DOMElement } from '../../utils/dom';
|
|
8
|
-
import { Header1Element, Header2Element, Header3Element, Header4Element, Header5Element } from './custom-types';
|
|
8
|
+
import { Header1Element, Header2Element, Header3Element, Header4Element, Header5Element, Header6Element } from './custom-types';
|
|
9
9
|
export declare const parseHeader1HtmlConf: {
|
|
10
10
|
selector: string;
|
|
11
11
|
parseElemHtml: (elem: DOMElement, children: Descendant[], editor: IDomEditor) => Header1Element;
|
|
@@ -28,5 +28,5 @@ export declare const parseHeader5HtmlConf: {
|
|
|
28
28
|
};
|
|
29
29
|
export declare const parseHeader6HtmlConf: {
|
|
30
30
|
selector: string;
|
|
31
|
-
parseElemHtml: (elem: DOMElement, children: Descendant[], editor: IDomEditor) =>
|
|
31
|
+
parseElemHtml: (elem: DOMElement, children: Descendant[], editor: IDomEditor) => Header6Element;
|
|
32
32
|
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @description lower dot emphasis menu
|
|
3
|
+
*/
|
|
4
|
+
import BaseMenu from './BaseMenu';
|
|
5
|
+
declare class EmphasisDotMenu extends BaseMenu {
|
|
6
|
+
readonly mark = "emphasisDot";
|
|
7
|
+
readonly title: string;
|
|
8
|
+
readonly iconSvg = "<svg viewBox=\"0 0 1024 1024\"><path d=\"M256 128h128v512H256zM448 128h128v512H448zM640 128h128v512H640z\"></path><path d=\"M320 832m-64 0a64 64 0 1 0 128 0 64 64 0 0 0-128 0zM512 832m-64 0a64 64 0 1 0 128 0 64 64 0 0 0-128 0zM704 832m-64 0a64 64 0 1 0 128 0 64 64 0 0 0-128 0z\"></path></svg>";
|
|
9
|
+
readonly hotkey = "";
|
|
10
|
+
}
|
|
11
|
+
export default EmphasisDotMenu;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @description wavy underline menu
|
|
3
|
+
*/
|
|
4
|
+
import BaseMenu from './BaseMenu';
|
|
5
|
+
declare class WavyUnderlineMenu extends BaseMenu {
|
|
6
|
+
readonly mark = "wavyUnderline";
|
|
7
|
+
readonly title: string;
|
|
8
|
+
readonly iconSvg = "<svg viewBox=\"0 0 1024 1024\"><path d=\"M64 704c64-96 128-96 192 0s128 96 192 0 128-96 192 0 128 96 192 0 128-96 192 0v128c-64 96-128 96-192 0s-128-96-192 0-128 96-192 0-128-96-192 0-128 96-192 0V704z\"></path></svg>";
|
|
9
|
+
readonly hotkey = "";
|
|
10
|
+
}
|
|
11
|
+
export default WavyUnderlineMenu;
|
|
@@ -5,11 +5,13 @@
|
|
|
5
5
|
import BoldMenu from './BoldMenu';
|
|
6
6
|
import ClearStyleMenu from './ClearStyleMenu';
|
|
7
7
|
import CodeMenu from './CodeMenu';
|
|
8
|
+
import EmphasisDotMenu from './EmphasisDotMenu';
|
|
8
9
|
import ItalicMenu from './ItalicMenu';
|
|
9
10
|
import SubMenu from './SubMenu';
|
|
10
11
|
import SupMenu from './SupMenu';
|
|
11
12
|
import ThroughMenu from './ThroughMenu';
|
|
12
13
|
import UnderlineMenu from './UnderlineMenu';
|
|
14
|
+
import WavyUnderlineMenu from './WavyUnderlineMenu';
|
|
13
15
|
export declare const boldMenuConf: {
|
|
14
16
|
key: string;
|
|
15
17
|
factory(): BoldMenu;
|
|
@@ -30,6 +32,14 @@ export declare const underlineMenuConf: {
|
|
|
30
32
|
key: string;
|
|
31
33
|
factory(): UnderlineMenu;
|
|
32
34
|
};
|
|
35
|
+
export declare const wavyUnderlineMenuConf: {
|
|
36
|
+
key: string;
|
|
37
|
+
factory(): WavyUnderlineMenu;
|
|
38
|
+
};
|
|
39
|
+
export declare const emphasisDotMenuConf: {
|
|
40
|
+
key: string;
|
|
41
|
+
factory(): EmphasisDotMenu;
|
|
42
|
+
};
|
|
33
43
|
export declare const supMenuConf: {
|
|
34
44
|
key: string;
|
|
35
45
|
factory(): SupMenu;
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* @description render text style
|
|
3
3
|
* @author wangfupeng
|
|
4
4
|
*/
|
|
5
|
+
import { IDomEditor } from '@wangeditor-next/core';
|
|
5
6
|
import { Descendant } from 'slate';
|
|
6
7
|
import { VNode } from 'snabbdom';
|
|
7
8
|
/**
|
|
@@ -10,4 +11,4 @@ import { VNode } from 'snabbdom';
|
|
|
10
11
|
* @param vnode vnode
|
|
11
12
|
* @returns vnode
|
|
12
13
|
*/
|
|
13
|
-
export declare function renderStyle(node: Descendant, vnode: VNode): VNode;
|
|
14
|
+
export declare function renderStyle(node: Descendant, vnode: VNode, editor?: IDomEditor): VNode;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @description CSS values shared by text-style render and HTML serialization
|
|
3
|
+
*/
|
|
4
|
+
export declare const UNDERLINE_OFFSET = "0.15em";
|
|
5
|
+
export declare const WAVY_UNDERLINE_OFFSET = "0.3em";
|
|
6
|
+
export declare const WAVY_UNDERLINE_WITH_EMPHASIS_OFFSET = "0.8em";
|
|
7
|
+
export declare const EMPHASIS_DOT_WITH_WAVY_LINE_HEIGHT = "2";
|
|
8
|
+
export declare const UNDERLINE_OFFSET_CLASS = "w-e-text-style-underline-offset";
|
|
9
|
+
export declare const WAVY_UNDERLINE_CLASS = "w-e-text-style-wavy-underline";
|
|
10
|
+
export declare const WAVY_UNDERLINE_WITH_EMPHASIS_CLASS = "w-e-text-style-wavy-underline-with-emphasis";
|
|
11
|
+
export declare const EMPHASIS_DOT_CLASS = "w-e-text-style-emphasis-dot";
|
|
12
|
+
export declare const EMPHASIS_DOT_WITH_WAVY_CLASS = "w-e-text-style-emphasis-dot-with-wavy";
|
|
13
|
+
export declare const WAVY_UNDERLINE_STYLE: {
|
|
14
|
+
textDecorationLine: string;
|
|
15
|
+
textDecorationStyle: string;
|
|
16
|
+
textUnderlineOffset: string;
|
|
17
|
+
};
|
|
18
|
+
export declare const WAVY_UNDERLINE_STYLE_HTML = "text-decoration-line: underline; text-decoration-style: wavy; text-underline-offset: 0.3em;";
|
|
19
|
+
export declare const WAVY_UNDERLINE_WITH_EMPHASIS_STYLE: {
|
|
20
|
+
textUnderlineOffset: string;
|
|
21
|
+
textDecorationLine: string;
|
|
22
|
+
textDecorationStyle: string;
|
|
23
|
+
};
|
|
24
|
+
export declare const WAVY_UNDERLINE_WITH_EMPHASIS_STYLE_HTML = "text-decoration-line: underline; text-decoration-style: wavy; text-underline-offset: 0.8em;";
|
|
25
|
+
export declare const EMPHASIS_DOT_STYLE: {
|
|
26
|
+
textEmphasisStyle: string;
|
|
27
|
+
textEmphasisPosition: string;
|
|
28
|
+
};
|
|
29
|
+
export declare const EMPHASIS_DOT_STYLE_HTML = "text-emphasis-style: filled dot; text-emphasis-position: under left;";
|
|
30
|
+
export declare const EMPHASIS_DOT_WITH_WAVY_STYLE: {
|
|
31
|
+
lineHeight: string;
|
|
32
|
+
textEmphasisStyle: string;
|
|
33
|
+
textEmphasisPosition: string;
|
|
34
|
+
};
|
|
35
|
+
export declare const EMPHASIS_DOT_WITH_WAVY_STYLE_HTML = "text-emphasis-style: filled dot; text-emphasis-position: under left; line-height: 2;";
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* @description text to html
|
|
3
3
|
* @author wangfupeng
|
|
4
4
|
*/
|
|
5
|
+
import { IDomEditor } from '@wangeditor-next/core';
|
|
5
6
|
import { Descendant } from 'slate';
|
|
6
7
|
/**
|
|
7
8
|
* style to html
|
|
@@ -9,4 +10,4 @@ import { Descendant } from 'slate';
|
|
|
9
10
|
* @param textHtml text html
|
|
10
11
|
* @returns styled html
|
|
11
12
|
*/
|
|
12
|
-
export declare function styleToHtml(textNode: Descendant, textHtml: string): string;
|
|
13
|
+
export declare function styleToHtml(textNode: Descendant, textHtml: string, editor?: IDomEditor): string;
|
|
@@ -10,7 +10,7 @@ import DOMText = globalThis.Text;
|
|
|
10
10
|
import DOMRange = globalThis.Range;
|
|
11
11
|
import DOMSelection = globalThis.Selection;
|
|
12
12
|
import DOMStaticRange = globalThis.StaticRange;
|
|
13
|
-
export { Dom7Array } from 'dom7';
|
|
13
|
+
export type { Dom7Array } from 'dom7';
|
|
14
14
|
export default $;
|
|
15
15
|
/**
|
|
16
16
|
* 判断 str 是不是纯字符串,而不是 html tag
|
|
@@ -10,6 +10,6 @@ import DOMText = globalThis.Text;
|
|
|
10
10
|
import DOMRange = globalThis.Range;
|
|
11
11
|
import DOMSelection = globalThis.Selection;
|
|
12
12
|
import DOMStaticRange = globalThis.StaticRange;
|
|
13
|
-
export { Dom7Array } from 'dom7';
|
|
13
|
+
export type { Dom7Array } from 'dom7';
|
|
14
14
|
export default $;
|
|
15
15
|
export { DOMComment, DOMElement, DOMNode, DOMRange, DOMSelection, DOMStaticRange, DOMText, };
|
|
@@ -2,13 +2,41 @@
|
|
|
2
2
|
* @description config interface
|
|
3
3
|
* @author wangfupeng
|
|
4
4
|
*/
|
|
5
|
-
import type { ImageElement } from 'packages/basic-modules/src/modules/image/custom-types';
|
|
6
|
-
import type { VideoElement } from 'packages/video-module/src/module/custom-types';
|
|
7
5
|
import type { Descendant, Node, NodeEntry, Range } from 'slate';
|
|
8
6
|
import type { IDomEditor } from '../editor/interface';
|
|
9
7
|
import type { IMenuGroup } from '../menus/interface';
|
|
10
8
|
import type { IUploadConfig } from '../upload/interface';
|
|
11
9
|
import type { DOMElement } from '../utils/dom';
|
|
10
|
+
type EmptyText = {
|
|
11
|
+
text: '';
|
|
12
|
+
};
|
|
13
|
+
type ImageElement = {
|
|
14
|
+
type: 'image';
|
|
15
|
+
src: string;
|
|
16
|
+
alt?: string;
|
|
17
|
+
href?: string;
|
|
18
|
+
width?: string;
|
|
19
|
+
height?: string;
|
|
20
|
+
style?: {
|
|
21
|
+
width?: string;
|
|
22
|
+
height?: string;
|
|
23
|
+
};
|
|
24
|
+
children: EmptyText[];
|
|
25
|
+
};
|
|
26
|
+
type VideoElement = {
|
|
27
|
+
type: 'video';
|
|
28
|
+
key?: string;
|
|
29
|
+
src: string;
|
|
30
|
+
poster?: string;
|
|
31
|
+
align?: 'left' | 'center' | 'right';
|
|
32
|
+
width?: string;
|
|
33
|
+
height?: string;
|
|
34
|
+
style?: {
|
|
35
|
+
width?: string;
|
|
36
|
+
height?: string;
|
|
37
|
+
};
|
|
38
|
+
children: EmptyText[];
|
|
39
|
+
};
|
|
12
40
|
interface IHoverbarConf {
|
|
13
41
|
[key: string]: {
|
|
14
42
|
match?: (editor: IDomEditor, n: Node) => boolean;
|
|
@@ -127,6 +155,8 @@ interface ICodeBlockConfig {
|
|
|
127
155
|
export interface IMenuConfig {
|
|
128
156
|
bold: ISingleMenuConfig;
|
|
129
157
|
underline: ISingleMenuConfig;
|
|
158
|
+
wavyUnderline: ISingleMenuConfig;
|
|
159
|
+
emphasisDot: ISingleMenuConfig;
|
|
130
160
|
italic: ISingleMenuConfig;
|
|
131
161
|
through: ISingleMenuConfig;
|
|
132
162
|
code: ISingleMenuConfig;
|
|
@@ -2,15 +2,28 @@
|
|
|
2
2
|
* @description editor interface
|
|
3
3
|
* @author wangfupeng
|
|
4
4
|
*/
|
|
5
|
-
import { NodeEntryWithContext } from '@wangeditor-next/table-module/src/utils';
|
|
6
5
|
import ee from 'event-emitter';
|
|
7
|
-
import { Ancestor, Editor, Element, Location, Node } from 'slate';
|
|
6
|
+
import { Ancestor, Editor, Element, Location, Node, NodeEntry } from 'slate';
|
|
8
7
|
import { AlertType, IEditorConfig, IMenuConfig, ISingleMenuConfig } from '../config/interface';
|
|
9
8
|
import { IPositionStyle } from '../menus/interface';
|
|
10
9
|
import { DOMElement } from '../utils/dom';
|
|
11
10
|
export type ElementWithId = Element & {
|
|
12
11
|
id: string;
|
|
13
12
|
};
|
|
13
|
+
export type TableSelectionEntry = [
|
|
14
|
+
NodeEntry<Element & {
|
|
15
|
+
type: unknown;
|
|
16
|
+
rowSpan?: number;
|
|
17
|
+
colSpan?: number;
|
|
18
|
+
hidden?: boolean;
|
|
19
|
+
}>,
|
|
20
|
+
{
|
|
21
|
+
rtl: number;
|
|
22
|
+
ltr: number;
|
|
23
|
+
ttb: number;
|
|
24
|
+
btt: number;
|
|
25
|
+
}
|
|
26
|
+
];
|
|
14
27
|
type MoveOptions = Parameters<Editor['move']>[0];
|
|
15
28
|
export type getMenuConfigReturnType<K> = K extends keyof IMenuConfig ? IMenuConfig[K] : ISingleMenuConfig;
|
|
16
29
|
/**
|
|
@@ -59,7 +72,7 @@ export interface IDomEditor extends Editor {
|
|
|
59
72
|
move(distance: number, reverse?: boolean): void;
|
|
60
73
|
moveReverse: (distance: number) => void;
|
|
61
74
|
restoreSelection: () => void;
|
|
62
|
-
getTableSelection?: () =>
|
|
75
|
+
getTableSelection?: () => TableSelectionEntry[][] | null;
|
|
63
76
|
getSelectionPosition: () => Partial<IPositionStyle>;
|
|
64
77
|
getNodePosition: (node: Node) => Partial<IPositionStyle>;
|
|
65
78
|
isSelectedAll: () => boolean;
|
package/dist/core/src/index.d.ts
CHANGED
|
@@ -7,11 +7,12 @@ import type { IDomEditor } from './editor/interface';
|
|
|
7
7
|
import type { IRegisterMenuConf } from './menus/index';
|
|
8
8
|
import type { IParseElemHtmlConf, IPreParseHtmlConf, ParseStyleHtmlFnType } from './parse-html/index';
|
|
9
9
|
import type { IRenderElemConf, RenderStyleFnType } from './render/index';
|
|
10
|
-
import type { IElemToHtmlConf, styleToHtmlFnType } from './to-html/index';
|
|
10
|
+
import type { HtmlTransformFnType, IElemToHtmlConf, styleToHtmlFnType } from './to-html/index';
|
|
11
11
|
import createUploaderRuntime from './upload/createUploader';
|
|
12
12
|
import type { IUploadConfig } from './upload/interface';
|
|
13
13
|
export * from './create/index';
|
|
14
|
-
export type { ClassStylePolicy, IClassStyleUnsupportedPayload, IEditorConfig, IToolbarConfig, IUploadImageConfig, IUploadVideoConfig, StyleClassTokenType, TextStyleMode, } from './config/interface';
|
|
14
|
+
export type { ClassStylePolicy, IClassStyleUnsupportedPayload, IEditorConfig, ISingleMenuConfig, IToolbarConfig, IUploadImageConfig, IUploadVideoConfig, StyleClassTokenType, TextStyleMode, } from './config/interface';
|
|
15
|
+
export { EditorEvents } from './config/interface';
|
|
15
16
|
export * from './config/style-mode';
|
|
16
17
|
export * from './editor/dom-editor';
|
|
17
18
|
export * from './editor/interface';
|
|
@@ -35,6 +36,7 @@ export interface IModuleConf {
|
|
|
35
36
|
renderStyle: RenderStyleFnType;
|
|
36
37
|
renderElems: Array<IRenderElemConf>;
|
|
37
38
|
styleToHtml: styleToHtmlFnType;
|
|
39
|
+
htmlTransform?: HtmlTransformFnType;
|
|
38
40
|
elemsToHtml: Array<IElemToHtmlConf>;
|
|
39
41
|
preParseHtml: Array<IPreParseHtmlConf>;
|
|
40
42
|
parseStyleHtml: ParseStyleHtmlFnType;
|
|
@@ -2,6 +2,5 @@
|
|
|
2
2
|
* @description formats helper
|
|
3
3
|
* @author wangfupeng
|
|
4
4
|
*/
|
|
5
|
-
|
|
6
|
-
export declare function genElemId(type: ElementType, id: string): string;
|
|
5
|
+
export declare function genElemId(type: string, id: string): string;
|
|
7
6
|
export declare function genTextId(id: string): string;
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { Descendant, Element as SlateElement } from 'slate';
|
|
6
6
|
import { IDomEditor } from '../editor/interface';
|
|
7
|
+
import type { INodeToHtmlOptions } from './node2html';
|
|
7
8
|
export type styleToHtmlFnType = (node: Descendant, elemHtml: string, editor?: IDomEditor) => string;
|
|
8
9
|
export declare const STYLE_TO_HTML_FN_LIST: styleToHtmlFnType[];
|
|
9
10
|
/**
|
|
@@ -11,6 +12,17 @@ export declare const STYLE_TO_HTML_FN_LIST: styleToHtmlFnType[];
|
|
|
11
12
|
* @param fn 处理 toHtml 文本样式的函数
|
|
12
13
|
*/
|
|
13
14
|
export declare function registerStyleToHtmlHandler(fn: styleToHtmlFnType): void;
|
|
15
|
+
/**
|
|
16
|
+
* Transform the HTML fragments of the document's top-level nodes.
|
|
17
|
+
*
|
|
18
|
+
* Element serializers intentionally stay node-local. Modules that need
|
|
19
|
+
* neighboring blocks to produce valid HTML (for example semantic lists) use
|
|
20
|
+
* this hook after every node has been serialized.
|
|
21
|
+
*/
|
|
22
|
+
export type HtmlTransformFnType = (htmlList: string[], nodes: Descendant[], editor: IDomEditor, options: INodeToHtmlOptions) => string[];
|
|
23
|
+
export declare const HTML_TRANSFORM_HANDLER_LIST: HtmlTransformFnType[];
|
|
24
|
+
export declare function registerHtmlTransformHandler(fn: HtmlTransformFnType): void;
|
|
25
|
+
export declare function transformHtml(htmlList: string[], nodes: Descendant[], editor: IDomEditor, options?: INodeToHtmlOptions): string[];
|
|
14
26
|
interface IElemToHtmlRes {
|
|
15
27
|
html: string;
|
|
16
28
|
prefix?: string;
|
|
@@ -10,7 +10,7 @@ import DOMText = globalThis.Text;
|
|
|
10
10
|
import DOMRange = globalThis.Range;
|
|
11
11
|
import DOMSelection = globalThis.Selection;
|
|
12
12
|
import DOMStaticRange = globalThis.StaticRange;
|
|
13
|
-
export { Dom7Array } from 'dom7';
|
|
13
|
+
export type { Dom7Array } from 'dom7';
|
|
14
14
|
export default $;
|
|
15
15
|
export declare enum NodeType {
|
|
16
16
|
ELEMENT_NODE = 1,
|
|
@@ -2,9 +2,8 @@
|
|
|
2
2
|
* @description Editor View class
|
|
3
3
|
* @author wangfupeng
|
|
4
4
|
*/
|
|
5
|
-
import type { IEditorConfig, IElemToHtmlConf, IModuleConf, IParseElemHtmlConf, IPreParseHtmlConf, IRegisterMenuConf, IRenderElemConf, IToolbarConfig, ParseStyleHtmlFnType, RenderStyleFnType, styleToHtmlFnType } from '@wangeditor-next/core';
|
|
5
|
+
import type { HtmlTransformFnType, IEditorConfig, IElemToHtmlConf, IModuleConf, IParseElemHtmlConf, IPreParseHtmlConf, IRegisterMenuConf, IRenderElemConf, ISingleMenuConfig, IToolbarConfig, ParseStyleHtmlFnType, RenderStyleFnType, styleToHtmlFnType } from '@wangeditor-next/core';
|
|
6
6
|
import { IDomEditor } from '@wangeditor-next/core';
|
|
7
|
-
import type { ISingleMenuConfig } from 'packages/core/src/config/interface';
|
|
8
7
|
type PluginType = <T extends IDomEditor>(editor: T) => T;
|
|
9
8
|
declare class Boot {
|
|
10
9
|
constructor();
|
|
@@ -23,6 +22,7 @@ declare class Boot {
|
|
|
23
22
|
static registerRenderStyle(fn: RenderStyleFnType): void;
|
|
24
23
|
static registerElemToHtml(elemToHtmlConf: IElemToHtmlConf): void;
|
|
25
24
|
static registerStyleToHtml(fn: styleToHtmlFnType): void;
|
|
25
|
+
static registerHtmlTransform(fn: HtmlTransformFnType): void;
|
|
26
26
|
static registerPreParseHtml(preParseHtmlConf: IPreParseHtmlConf): void;
|
|
27
27
|
static registerParseElemHtml(parseElemHtmlConf: IParseElemHtmlConf): void;
|
|
28
28
|
static registerParseStyleHtml(fn: ParseStyleHtmlFnType): void;
|
|
@@ -3,6 +3,13 @@
|
|
|
3
3
|
* @author wangfupeng
|
|
4
4
|
*/
|
|
5
5
|
import './assets/index.less';
|
|
6
|
+
import '@wangeditor-next/core/dist/css/style.css';
|
|
7
|
+
import '@wangeditor-next/basic-modules/dist/css/style.css';
|
|
8
|
+
import '@wangeditor-next/code-highlight/dist/css/style.css';
|
|
9
|
+
import '@wangeditor-next/list-module/dist/css/style.css';
|
|
10
|
+
import '@wangeditor-next/table-module/dist/css/style.css';
|
|
11
|
+
import '@wangeditor-next/upload-image-module/dist/css/style.css';
|
|
12
|
+
import '@wangeditor-next/video-module/dist/css/style.css';
|
|
6
13
|
import './utils/browser-polyfill';
|
|
7
14
|
import './utils/node-polyfill';
|
|
8
15
|
import './locale/index';
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("@wangeditor-next/editor"),require("snabbdom")):"function"==typeof define&&define.amd?define(["@wangeditor-next/editor","snabbdom"],t):(e="undefined"!=typeof globalThis?globalThis:e||self).WangEditorLinkCardPlugin=t(e.
|
|
1
|
+
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("@wangeditor-next/editor"),require("snabbdom")):"function"==typeof define&&define.amd?define(["@wangeditor-next/editor","snabbdom"],t):(e="undefined"!=typeof globalThis?globalThis:e||self).WangEditorLinkCardPlugin=t(e.wangEditor,e.snabbdom)}(this,function(e,t){"use strict";e.i18nAddResources("en",{linkCard:{toCard:"To Card"}}),e.i18nAddResources("zh-CN",{linkCard:{toCard:"转为卡片"}});var n={type:"link-card",elemToHtml:function(e,t){var n=e,r=n.title,i=void 0===r?"":r,o=n.link,a=void 0===o?"":o,c=n.iconImgSrc,l=void 0===c?"":c;return'<div data-w-e-type="link-card" data-w-e-is-void data-title="'.concat(i,'" data-link="').concat(a,'" data-iconImgSrc="').concat(l,'">\n <div class="info-container">\n <div class="title-container"><p>').concat(i,'</p></div>\n <div class="link-container"><span>').concat(a,'</span></div>\n </div>\n <div class="icon-container">\n <img src="').concat(l,'"/>\n </div>\n </div>')}};function r(e,t,n,r){return new(n||(n=Promise))(function(i,o){function a(e){try{l(r.next(e))}catch(e){o(e)}}function c(e){try{l(r.throw(e))}catch(e){o(e)}}function l(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n(function(e){e(t)})).then(a,c)}l((r=r.apply(e,t||[])).next())})}function i(e,t){var n,r,i,o={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]},a=Object.create(("function"==typeof Iterator?Iterator:Object).prototype);return a.next=c(0),a.throw=c(1),a.return=c(2),"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function c(c){return function(l){return function(c){if(n)throw new TypeError("Generator is already executing.");for(;a&&(a=0,c[0]&&(o=0)),o;)try{if(n=1,r&&(i=2&c[0]?r.return:c[0]?r.throw||((i=r.return)&&i.call(r),0):r.next)&&!(i=i.call(r,c[1])).done)return i;switch(r=0,i&&(c=[2&c[0],i.value]),c[0]){case 0:case 1:i=c;break;case 4:return o.label++,{value:c[1],done:!1};case 5:o.label++,r=c[1],c=[0];continue;case 7:c=o.ops.pop(),o.trys.pop();continue;default:if(!(i=o.trys,(i=i.length>0&&i[i.length-1])||6!==c[0]&&2!==c[0])){o=0;continue}if(3===c[0]&&(!i||c[1]>i[0]&&c[1]<i[3])){o.label=c[1];break}if(6===c[0]&&o.label<i[1]){o.label=i[1],i=c;break}if(i&&o.label<i[2]){o.label=i[2],o.ops.push(c);break}i[2]&&o.ops.pop(),o.trys.pop();continue}c=t.call(e,o)}catch(e){c=[6,e],r=0}finally{n=i=0}if(5&c[0])throw c[1];return{value:c[0]?c[1]:void 0,done:!0}}([c,l])}}}"function"==typeof SuppressedError&&SuppressedError;var o=function(){function t(){this.title=e.t("linkCard.toCard"),this.iconSvg="",this.tag="button"}return t.prototype.getSelectedLinkElem=function(t){var n=e.DomEditor.getSelectedNodeByType(t,"link");return null==n?null:n},t.prototype.getValue=function(e){return""},t.prototype.isActive=function(e){return!1},t.prototype.isDisabled=function(e){return null==e.selection||null==this.getSelectedLinkElem(e)},t.prototype.exec=function(t,n){return r(this,void 0,void 0,function(){var n,r,o,a,c,l,u,d,s,f;return i(this,function(i){switch(i.label){case 0:if(this.isDisabled(t))return[2];if(null==(n=this.getSelectedLinkElem(t)))return[2];if("function"!=typeof(r=t.getMenuConfig("convertToLinkCard").getLinkCardInfo))return[2];o=n.url,a=e.SlateNode.string(n),i.label=1;case 1:return i.trys.push([1,3,,4]),[4,r(a,o)];case 2:return c=i.sent(),l=c.title,u=c.iconImgSrc,d=e.DomEditor.findPath(t,n),e.SlateTransforms.removeNodes(t,{at:d}),e.SlateTransforms.splitNodes(t,{always:!0}),s={type:"link-card",link:o,title:l,iconImgSrc:u,children:[{text:""}]},e.SlateTransforms.insertNodes(t,s),[3,4];case 3:return f=i.sent(),console.error("Convert to link-cart error",f),[3,4];case 4:return[2]}})})},t}();return{editorPlugin:function(t){var n=t.isVoid,r=t.normalizeNode,i=t;return i.isVoid=function(t){return"link-card"===e.DomEditor.getNodeType(t)||n(t)},i.normalizeNode=function(t){var n=function(e,t){var n="function"==typeof Symbol&&e[Symbol.iterator];if(!n)return e;var r,i,o=n.call(e),a=[];try{for(;(void 0===t||t-- >0)&&!(r=o.next()).done;)a.push(r.value)}catch(e){i={error:e}}finally{try{r&&!r.done&&(n=o.return)&&n.call(o)}finally{if(i)throw i.error}}return a}(t,2),o=n[0],a=n[1];if("link-card"!==e.DomEditor.getNodeType(o))return r([o,a]);var c=(i.children||[])[a[0]+1]||{},l=e.DomEditor.getNodeType(c);if("paragraph"!==l&&"blockquote"!==l&&!l.startsWith("header")){var u=[a[0]+1];e.SlateTransforms.insertNodes(i,{type:"paragraph",children:[{text:""}]},{at:u})}},i},renderElems:[{type:"link-card",renderElem:function(n,r,i){var o=e.DomEditor.isNodeSelected(i,n),a=n,c=a.title,l=a.link,u=a.iconImgSrc,d=t.h("div",{props:{className:"w-e-textarea-link-card-text-container"}},[t.h("p",{props:{className:"w-e-link-card-title"}},c),t.h("span",{props:{className:"w-e-link-card-url",title:l}},l)]),s=t.h("div",{props:{className:"w-e-textarea-link-card-icon-container"}},[t.h("img",{props:{src:u||"data:image/png;base64,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"}})]);return t.h("div",{props:{contentEditable:!1,className:"w-e-textarea-link-card-container"},dataset:{selected:o?"true":"",href:l},on:{mousedown:function(e){return e.preventDefault()},click:function(e){o||window.open(l,"_blank","noopener,noreferrer")}}},[d,s])}}],elemsToHtml:[n],parseElemsHtml:[{selector:'div[data-w-e-type="link-card"]',parseElemHtml:function(e,t,n){return{type:"link-card",link:e.getAttribute("data-link")||"",title:e.getAttribute("data-title")||"",iconImgSrc:e.getAttribute("data-iconImgSrc")||"",children:[{text:""}]}}}],menus:[{key:"convertToLinkCard",factory:function(){return new o},config:{getLinkCardInfo:function(e,t){return r(this,void 0,void 0,function(){return i(this,function(t){return[2,new Promise(function(t){setTimeout(function(){t({title:e,iconImgSrc:""})},100)})]})})}}}]}});
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/module/local.ts","../src/module/elem-to-html.ts","../src/module/menu/ConvertToLinkCard.ts","../src/module/index.ts","../src/module/plugin.ts","../src/module/render-elem.ts","../src/module/parse-elem-html.ts","../src/module/menu/index.ts","../src/module/menu/config.ts"],"sourcesContent":["/**\n * @description 多语言\n * @author wangfupeng\n */\n\nimport { i18nAddResources } from '@wangeditor-next/editor'\n\ni18nAddResources('en', {\n linkCard: {\n toCard: 'To Card',\n // delete: 'Delete',\n },\n})\n\ni18nAddResources('zh-CN', {\n linkCard: {\n toCard: '转为卡片',\n // delete: '删除',\n },\n})\n","/**\n * @description elem to html\n * @author wangfupeng\n */\n\nimport { SlateElement } from '@wangeditor-next/editor'\n\nimport { LinkCardElement } from './custom-types'\n\n// 生成 html 的函数\nfunction linkCardToHtml(elem: SlateElement, _childrenHtml: string): string {\n const { title = '', link = '', iconImgSrc = '' } = elem as LinkCardElement\n const html = `<div data-w-e-type=\"link-card\" data-w-e-is-void data-title=\"${title}\" data-link=\"${link}\" data-iconImgSrc=\"${iconImgSrc}\">\n <div class=\"info-container\">\n <div class=\"title-container\"><p>${title}</p></div>\n <div class=\"link-container\"><span>${link}</span></div>\n </div>\n <div class=\"icon-container\">\n <img src=\"${iconImgSrc}\"/>\n </div>\n </div>`\n\n return html\n}\n\n// 配置\nconst conf = {\n type: 'link-card', // 节点 type ,重要!!!\n elemToHtml: linkCardToHtml,\n}\n\nexport default conf\n","/**\n * @description convert link elem to link-card\n * @author wangfupeng\n */\n\nimport {\n DomEditor,\n IButtonMenu, IDomEditor,\n SlateNode,\n SlateTransforms,\n t,\n} from '@wangeditor-next/editor'\n\nimport { LinkCardElement, LinkElement } from '../custom-types'\n\nclass ConvertToLinkCard implements IButtonMenu {\n readonly title = t('linkCard.toCard')\n\n readonly iconSvg = '' // 无 icon\n\n readonly tag = 'button'\n\n private getSelectedLinkElem(editor: IDomEditor): LinkElement | null {\n const node = DomEditor.getSelectedNodeByType(editor, 'link')\n\n if (node == null) { return null }\n return node as LinkElement\n }\n\n getValue(_editor: IDomEditor): string | boolean {\n return ''\n }\n\n isActive(_editor: IDomEditor): boolean {\n // 无需 active\n return false\n }\n\n isDisabled(editor: IDomEditor): boolean {\n if (editor.selection == null) { return true }\n\n const linkElem = this.getSelectedLinkElem(editor)\n\n if (linkElem == null) {\n // 选区未处于 link node ,则禁用\n return true\n }\n return false\n }\n\n async exec(editor: IDomEditor, _value: string | boolean) {\n if (this.isDisabled(editor)) { return }\n\n const linkElem = this.getSelectedLinkElem(editor)\n\n if (linkElem == null) { return }\n\n const { getLinkCardInfo } = editor.getMenuConfig('convertToLinkCard')\n\n if (typeof getLinkCardInfo !== 'function') { return }\n\n const { url } = linkElem\n const text = SlateNode.string(linkElem)\n\n try {\n const { title, iconImgSrc } = await getLinkCardInfo(text, url) // 异步生成 link-card 信息\n\n const linkPath = DomEditor.findPath(editor, linkElem)\n\n SlateTransforms.removeNodes(editor, { at: linkPath })\n SlateTransforms.splitNodes(editor, { always: true })\n\n const linkCard: LinkCardElement = {\n type: 'link-card',\n link: url,\n title,\n iconImgSrc,\n children: [{ text: '' }],\n }\n\n SlateTransforms.insertNodes(editor, linkCard)\n } catch (err) {\n console.error('Convert to link-cart error', err)\n }\n }\n}\n\nexport default ConvertToLinkCard\n","/**\n * @description module entry\n * @author wangfupeng\n */\n\nimport './local' // 多语言\n\nimport { IModuleConf } from '@wangeditor-next/editor'\n\nimport elemToHtmlConf from './elem-to-html'\nimport { convertToLinkCardMenuConf } from './menu/index'\nimport parseHtmlConf from './parse-elem-html'\nimport withLinkCard from './plugin'\nimport renderElemConf from './render-elem'\n\nconst module: Partial<IModuleConf> = {\n editorPlugin: withLinkCard,\n renderElems: [renderElemConf],\n elemsToHtml: [elemToHtmlConf],\n parseElemsHtml: [parseHtmlConf],\n menus: [convertToLinkCardMenuConf],\n}\n\nexport default module\n","/**\n * @description link-card plugin\n * @author wangfupeng\n */\n\nimport { DomEditor, IDomEditor, SlateTransforms } from '@wangeditor-next/editor'\n\nfunction withLinkCard<T extends IDomEditor>(editor: T) {\n const { isVoid, normalizeNode } = editor\n const newEditor = editor\n\n // 重写 isVoid\n newEditor.isVoid = elem => {\n const type = DomEditor.getNodeType(elem)\n\n if (type === 'link-card') {\n return true\n }\n\n return isVoid(elem)\n }\n\n // 重新 normalize\n newEditor.normalizeNode = ([node, path]) => {\n const type = DomEditor.getNodeType(node)\n\n if (type !== 'link-card') {\n // 未命中 link-card ,执行默认的 normalizeNode\n return normalizeNode([node, path])\n }\n\n // editor 顶级 node\n const topLevelNodes = newEditor.children || []\n\n // --------------------- link-card 后面必须跟一个 p header blockquote(否则后面无法继续输入文字) ---------------------\n const nextNode = topLevelNodes[path[0] + 1] || {}\n const nextNodeType = DomEditor.getNodeType(nextNode)\n\n if (\n nextNodeType !== 'paragraph'\n && nextNodeType !== 'blockquote'\n && !nextNodeType.startsWith('header')\n ) {\n // link-card node 后面不是 p 或 header ,则插入一个空 p\n const p = { type: 'paragraph', children: [{ text: '' }] }\n const insertPath = [path[0] + 1]\n\n SlateTransforms.insertNodes(newEditor, p, {\n at: insertPath, // 在 link-card 后面插入\n })\n }\n }\n\n return newEditor\n}\n\nexport default withLinkCard\n","/**\n * @description render elem\n * @author wangfupeng\n */\n\nimport { DomEditor, IDomEditor, SlateElement } from '@wangeditor-next/editor'\nimport { h, VNode } from 'snabbdom'\n\nimport { LinkCardElement } from './custom-types'\n\nconst DEFAULT_ICON_IMG_SRC = 'data:image/png;base64,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'\n\nfunction renderLinkCard(elem: SlateElement, children: VNode[] | null, editor: IDomEditor): VNode {\n const selected = DomEditor.isNodeSelected(editor, elem) // 当前节点是否选中\n const { title, link, iconImgSrc } = elem as LinkCardElement\n\n // 文字部分\n const infoVnode = h(\n 'div',\n {\n props: {\n className: 'w-e-textarea-link-card-text-container',\n },\n },\n [\n h('p', { props: { className: 'w-e-link-card-title' } }, title),\n h('span', {\n props: {\n className: 'w-e-link-card-url',\n title: link,\n },\n }, link),\n ],\n )\n\n // 图片部分\n const iconVnode = h(\n 'div',\n {\n props: {\n className: 'w-e-textarea-link-card-icon-container',\n },\n },\n [h('img', { props: { src: iconImgSrc || DEFAULT_ICON_IMG_SRC } })],\n )\n\n // 容器\n const vnode = h(\n 'div',\n {\n props: {\n contentEditable: false,\n className: 'w-e-textarea-link-card-container',\n },\n dataset: {\n selected: selected ? 'true' : '', // 标记为 选中\n href: link,\n },\n on: {\n mousedown: event => event.preventDefault(),\n click: _event => {\n if (!selected) {\n window.open(link, '_blank', 'noopener,noreferrer')\n }\n },\n },\n },\n [infoVnode, iconVnode],\n )\n\n return vnode\n}\n\nconst conf = {\n type: 'link-card', // 节点 type ,重要!!!\n renderElem: renderLinkCard,\n}\n\nexport default conf\n","/**\n * @description parse elem html\n * @author wangfupeng\n */\n\nimport { IDomEditor, SlateDescendant, SlateElement } from '@wangeditor-next/editor'\n\nimport { DOMElement } from '../utils/dom'\nimport { LinkCardElement } from './custom-types'\n\nfunction parseHtml(\n elem: DOMElement,\n _children: SlateDescendant[],\n _editor: IDomEditor,\n): SlateElement {\n const link = elem.getAttribute('data-link') || ''\n const title = elem.getAttribute('data-title') || ''\n const iconImgSrc = elem.getAttribute('data-iconImgSrc') || ''\n\n return {\n type: 'link-card',\n link,\n title,\n iconImgSrc,\n children: [{ text: '' }], // void node 必须有一个空白 text\n } as LinkCardElement\n}\n\nconst parseHtmlConf = {\n selector: 'div[data-w-e-type=\"link-card\"]',\n parseElemHtml: parseHtml,\n}\n\nexport default parseHtmlConf\n","/**\n * @description menu index\n * @author wangfupeng\n */\n\nimport { genConvertToLinkCardConfig } from './config'\nimport ConvertToLinkCard from './ConvertToLinkCard'\n\nexport const convertToLinkCardMenuConf = {\n key: 'convertToLinkCard',\n factory() {\n return new ConvertToLinkCard()\n },\n\n // 默认的菜单菜单配置,将存储在 editorConfig.MENU_CONF[key] 中\n // 创建编辑器时,可通过 editorConfig.MENU_CONF[key] = {...} 来修改\n config: genConvertToLinkCardConfig(),\n}\n","/**\n * @description menu config\n * @author wangfupeng\n */\n\nexport function genConvertToLinkCardConfig() {\n return {\n /**\n * 异步获取 link-card 信息(可能需要在服务端获取)\n * @param linkText link text\n * @param linkUrl link url\n * @returns link-card info\n */\n async getLinkCardInfo(\n linkText: string,\n _linkUrl: string,\n ): Promise<{ title: string; iconImgSrc: string }> {\n // 该函数,用户自定义配置\n // 1. 使用 iframe 加载 linkUrl 来获取 title 和 iconImgSrc\n // 2. 但有些网页禁止跨域 iframe 加载(即 X-Frame-Options),此时需要在服务端获取\n\n return new Promise(resolve => {\n setTimeout(() => {\n const info = { title: linkText, iconImgSrc: '' }\n\n resolve(info)\n }, 100)\n })\n },\n }\n}\n"],"names":["i18nAddResources","linkCard","toCard","conf","type","elemToHtml","elem","_childrenHtml","_a","_b","title","_c","link","_d","iconImgSrc","concat","ConvertToLinkCard","this","t","iconSvg","tag","prototype","getSelectedLinkElem","editor","node","DomEditor","getSelectedNodeByType","getValue","_editor","isActive","isDisabled","selection","exec","_value","linkElem","getLinkCardInfo","getMenuConfig","url","text","SlateNode","string","sent","linkPath","findPath","SlateTransforms","removeNodes","at","splitNodes","always","children","insertNodes","console","error","err_1","editorPlugin","isVoid","normalizeNode","newEditor","getNodeType","__read","path","nextNode","nextNodeType","startsWith","insertPath","renderElems","renderElem","selected","isNodeSelected","infoVnode","h","props","className","iconVnode","src","contentEditable","dataset","href","on","mousedown","event","preventDefault","click","_event","window","open","elemsToHtml","elemToHtmlConf","parseElemsHtml","selector","parseElemHtml","_children","getAttribute","menus","key","factory","config","linkText","_linkUrl","Promise","resolve","setTimeout"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/module/local.ts","../src/module/elem-to-html.ts","../src/module/menu/ConvertToLinkCard.ts","../src/module/index.ts","../src/module/plugin.ts","../src/module/render-elem.ts","../src/module/parse-elem-html.ts","../src/module/menu/index.ts","../src/module/menu/config.ts"],"sourcesContent":["/**\n * @description 多语言\n * @author wangfupeng\n */\n\nimport { i18nAddResources } from '@wangeditor-next/editor'\n\ni18nAddResources('en', {\n linkCard: {\n toCard: 'To Card',\n // delete: 'Delete',\n },\n})\n\ni18nAddResources('zh-CN', {\n linkCard: {\n toCard: '转为卡片',\n // delete: '删除',\n },\n})\n","/**\n * @description elem to html\n * @author wangfupeng\n */\n\nimport { SlateElement } from '@wangeditor-next/editor'\n\nimport { LinkCardElement } from './custom-types'\n\n// 生成 html 的函数\nfunction linkCardToHtml(elem: SlateElement, _childrenHtml: string): string {\n const { title = '', link = '', iconImgSrc = '' } = elem as LinkCardElement\n const html = `<div data-w-e-type=\"link-card\" data-w-e-is-void data-title=\"${title}\" data-link=\"${link}\" data-iconImgSrc=\"${iconImgSrc}\">\n <div class=\"info-container\">\n <div class=\"title-container\"><p>${title}</p></div>\n <div class=\"link-container\"><span>${link}</span></div>\n </div>\n <div class=\"icon-container\">\n <img src=\"${iconImgSrc}\"/>\n </div>\n </div>`\n\n return html\n}\n\n// 配置\nconst conf = {\n type: 'link-card', // 节点 type ,重要!!!\n elemToHtml: linkCardToHtml,\n}\n\nexport default conf\n","/**\n * @description convert link elem to link-card\n * @author wangfupeng\n */\n\nimport {\n DomEditor,\n IButtonMenu, IDomEditor,\n SlateNode,\n SlateTransforms,\n t,\n} from '@wangeditor-next/editor'\n\nimport { LinkCardElement, LinkElement } from '../custom-types'\n\nclass ConvertToLinkCard implements IButtonMenu {\n readonly title = t('linkCard.toCard')\n\n readonly iconSvg = '' // 无 icon\n\n readonly tag = 'button'\n\n private getSelectedLinkElem(editor: IDomEditor): LinkElement | null {\n const node = DomEditor.getSelectedNodeByType(editor, 'link')\n\n if (node == null) { return null }\n return node as LinkElement\n }\n\n getValue(_editor: IDomEditor): string | boolean {\n return ''\n }\n\n isActive(_editor: IDomEditor): boolean {\n // 无需 active\n return false\n }\n\n isDisabled(editor: IDomEditor): boolean {\n if (editor.selection == null) { return true }\n\n const linkElem = this.getSelectedLinkElem(editor)\n\n if (linkElem == null) {\n // 选区未处于 link node ,则禁用\n return true\n }\n return false\n }\n\n async exec(editor: IDomEditor, _value: string | boolean) {\n if (this.isDisabled(editor)) { return }\n\n const linkElem = this.getSelectedLinkElem(editor)\n\n if (linkElem == null) { return }\n\n const { getLinkCardInfo } = editor.getMenuConfig('convertToLinkCard')\n\n if (typeof getLinkCardInfo !== 'function') { return }\n\n const { url } = linkElem\n const text = SlateNode.string(linkElem)\n\n try {\n const { title, iconImgSrc } = await getLinkCardInfo(text, url) // 异步生成 link-card 信息\n\n const linkPath = DomEditor.findPath(editor, linkElem)\n\n SlateTransforms.removeNodes(editor, { at: linkPath })\n SlateTransforms.splitNodes(editor, { always: true })\n\n const linkCard: LinkCardElement = {\n type: 'link-card',\n link: url,\n title,\n iconImgSrc,\n children: [{ text: '' }],\n }\n\n SlateTransforms.insertNodes(editor, linkCard)\n } catch (err) {\n console.error('Convert to link-cart error', err)\n }\n }\n}\n\nexport default ConvertToLinkCard\n","/**\n * @description module entry\n * @author wangfupeng\n */\n\nimport './local' // 多语言\n\nimport { IModuleConf } from '@wangeditor-next/editor'\n\nimport elemToHtmlConf from './elem-to-html'\nimport { convertToLinkCardMenuConf } from './menu/index'\nimport parseHtmlConf from './parse-elem-html'\nimport withLinkCard from './plugin'\nimport renderElemConf from './render-elem'\n\nconst module: Partial<IModuleConf> = {\n editorPlugin: withLinkCard,\n renderElems: [renderElemConf],\n elemsToHtml: [elemToHtmlConf],\n parseElemsHtml: [parseHtmlConf],\n menus: [convertToLinkCardMenuConf],\n}\n\nexport default module\n","/**\n * @description link-card plugin\n * @author wangfupeng\n */\n\nimport { DomEditor, IDomEditor, SlateTransforms } from '@wangeditor-next/editor'\n\nfunction withLinkCard<T extends IDomEditor>(editor: T) {\n const { isVoid, normalizeNode } = editor\n const newEditor = editor\n\n // 重写 isVoid\n newEditor.isVoid = elem => {\n const type = DomEditor.getNodeType(elem)\n\n if (type === 'link-card') {\n return true\n }\n\n return isVoid(elem)\n }\n\n // 重新 normalize\n newEditor.normalizeNode = ([node, path]) => {\n const type = DomEditor.getNodeType(node)\n\n if (type !== 'link-card') {\n // 未命中 link-card ,执行默认的 normalizeNode\n return normalizeNode([node, path])\n }\n\n // editor 顶级 node\n const topLevelNodes = newEditor.children || []\n\n // --------------------- link-card 后面必须跟一个 p header blockquote(否则后面无法继续输入文字) ---------------------\n const nextNode = topLevelNodes[path[0] + 1] || {}\n const nextNodeType = DomEditor.getNodeType(nextNode)\n\n if (\n nextNodeType !== 'paragraph'\n && nextNodeType !== 'blockquote'\n && !nextNodeType.startsWith('header')\n ) {\n // link-card node 后面不是 p 或 header ,则插入一个空 p\n const p = { type: 'paragraph', children: [{ text: '' }] }\n const insertPath = [path[0] + 1]\n\n SlateTransforms.insertNodes(newEditor, p, {\n at: insertPath, // 在 link-card 后面插入\n })\n }\n }\n\n return newEditor\n}\n\nexport default withLinkCard\n","/**\n * @description render elem\n * @author wangfupeng\n */\n\nimport { DomEditor, IDomEditor, SlateElement } from '@wangeditor-next/editor'\nimport { h, VNode } from 'snabbdom'\n\nimport { LinkCardElement } from './custom-types'\n\nconst DEFAULT_ICON_IMG_SRC = 'data:image/png;base64,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'\n\nfunction renderLinkCard(elem: SlateElement, children: VNode[] | null, editor: IDomEditor): VNode {\n const selected = DomEditor.isNodeSelected(editor, elem) // 当前节点是否选中\n const { title, link, iconImgSrc } = elem as LinkCardElement\n\n // 文字部分\n const infoVnode = h(\n 'div',\n {\n props: {\n className: 'w-e-textarea-link-card-text-container',\n },\n },\n [\n h('p', { props: { className: 'w-e-link-card-title' } }, title),\n h('span', {\n props: {\n className: 'w-e-link-card-url',\n title: link,\n },\n }, link),\n ],\n )\n\n // 图片部分\n const iconVnode = h(\n 'div',\n {\n props: {\n className: 'w-e-textarea-link-card-icon-container',\n },\n },\n [h('img', { props: { src: iconImgSrc || DEFAULT_ICON_IMG_SRC } })],\n )\n\n // 容器\n const vnode = h(\n 'div',\n {\n props: {\n contentEditable: false,\n className: 'w-e-textarea-link-card-container',\n },\n dataset: {\n selected: selected ? 'true' : '', // 标记为 选中\n href: link,\n },\n on: {\n mousedown: event => event.preventDefault(),\n click: _event => {\n if (!selected) {\n window.open(link, '_blank', 'noopener,noreferrer')\n }\n },\n },\n },\n [infoVnode, iconVnode],\n )\n\n return vnode\n}\n\nconst conf = {\n type: 'link-card', // 节点 type ,重要!!!\n renderElem: renderLinkCard,\n}\n\nexport default conf\n","/**\n * @description parse elem html\n * @author wangfupeng\n */\n\nimport { IDomEditor, SlateDescendant, SlateElement } from '@wangeditor-next/editor'\n\nimport { DOMElement } from '../utils/dom'\nimport { LinkCardElement } from './custom-types'\n\nfunction parseHtml(\n elem: DOMElement,\n _children: SlateDescendant[],\n _editor: IDomEditor,\n): SlateElement {\n const link = elem.getAttribute('data-link') || ''\n const title = elem.getAttribute('data-title') || ''\n const iconImgSrc = elem.getAttribute('data-iconImgSrc') || ''\n\n return {\n type: 'link-card',\n link,\n title,\n iconImgSrc,\n children: [{ text: '' }], // void node 必须有一个空白 text\n } as LinkCardElement\n}\n\nconst parseHtmlConf = {\n selector: 'div[data-w-e-type=\"link-card\"]',\n parseElemHtml: parseHtml,\n}\n\nexport default parseHtmlConf\n","/**\n * @description menu index\n * @author wangfupeng\n */\n\nimport { genConvertToLinkCardConfig } from './config'\nimport ConvertToLinkCard from './ConvertToLinkCard'\n\nexport const convertToLinkCardMenuConf = {\n key: 'convertToLinkCard',\n factory() {\n return new ConvertToLinkCard()\n },\n\n // 默认的菜单菜单配置,将存储在 editorConfig.MENU_CONF[key] 中\n // 创建编辑器时,可通过 editorConfig.MENU_CONF[key] = {...} 来修改\n config: genConvertToLinkCardConfig(),\n}\n","/**\n * @description menu config\n * @author wangfupeng\n */\n\nexport function genConvertToLinkCardConfig() {\n return {\n /**\n * 异步获取 link-card 信息(可能需要在服务端获取)\n * @param linkText link text\n * @param linkUrl link url\n * @returns link-card info\n */\n async getLinkCardInfo(\n linkText: string,\n _linkUrl: string,\n ): Promise<{ title: string; iconImgSrc: string }> {\n // 该函数,用户自定义配置\n // 1. 使用 iframe 加载 linkUrl 来获取 title 和 iconImgSrc\n // 2. 但有些网页禁止跨域 iframe 加载(即 X-Frame-Options),此时需要在服务端获取\n\n return new Promise(resolve => {\n setTimeout(() => {\n const info = { title: linkText, iconImgSrc: '' }\n\n resolve(info)\n }, 100)\n })\n },\n }\n}\n"],"names":["i18nAddResources","linkCard","toCard","conf","type","elemToHtml","elem","_childrenHtml","_a","_b","title","_c","link","_d","iconImgSrc","concat","ConvertToLinkCard","this","t","iconSvg","tag","prototype","getSelectedLinkElem","editor","node","DomEditor","getSelectedNodeByType","getValue","_editor","isActive","isDisabled","selection","exec","_value","linkElem","getLinkCardInfo","getMenuConfig","url","text","SlateNode","string","sent","linkPath","findPath","SlateTransforms","removeNodes","at","splitNodes","always","children","insertNodes","console","error","err_1","editorPlugin","isVoid","normalizeNode","newEditor","getNodeType","__read","path","nextNode","nextNodeType","startsWith","insertPath","renderElems","renderElem","selected","isNodeSelected","infoVnode","h","props","className","iconVnode","src","contentEditable","dataset","href","on","mousedown","event","preventDefault","click","_event","window","open","elemsToHtml","elemToHtmlConf","parseElemsHtml","selector","parseElemHtml","_children","getAttribute","menus","key","factory","config","linkText","_linkUrl","Promise","resolve","setTimeout"],"mappings":"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"}
|
|
@@ -4,11 +4,24 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { Text } from 'slate';
|
|
6
6
|
export type OrderedListType = '1' | 'a' | 'A' | 'i' | 'I';
|
|
7
|
+
/**
|
|
8
|
+
* An outline keeps the established list-item wire format and records the
|
|
9
|
+
* heading semantics as additive metadata.
|
|
10
|
+
*/
|
|
11
|
+
export type HeadingType = 'header1' | 'header2' | 'header3' | 'header4' | 'header5' | 'header6';
|
|
7
12
|
export type ListItemElement = {
|
|
8
13
|
type: 'list-item';
|
|
9
14
|
ordered: boolean;
|
|
10
15
|
level: number;
|
|
11
16
|
start?: number;
|
|
12
17
|
orderType?: OrderedListType;
|
|
18
|
+
headingType?: HeadingType;
|
|
19
|
+
listMode?: 'outline';
|
|
20
|
+
listRestart?: number;
|
|
13
21
|
children: Text[];
|
|
14
22
|
};
|
|
23
|
+
export type OutlineListItemElement = ListItemElement & {
|
|
24
|
+
ordered: true;
|
|
25
|
+
headingType: HeadingType;
|
|
26
|
+
listMode: 'outline';
|
|
27
|
+
};
|
|
@@ -1,15 +1,25 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @description
|
|
3
|
-
* @author wangfupeng
|
|
2
|
+
* @description list helpers
|
|
4
3
|
*/
|
|
5
4
|
import { IDomEditor } from '@wangeditor-next/core';
|
|
6
|
-
import {
|
|
5
|
+
import { Node } from 'slate';
|
|
6
|
+
import { HeadingType, ListItemElement, OrderedListType, OutlineListItemElement } from './custom-types';
|
|
7
|
+
export declare function isListNode(node: Node): node is ListItemElement;
|
|
8
|
+
export declare const isLegacyListItem: typeof isListNode;
|
|
9
|
+
export declare function isHeadingType(value: unknown): value is HeadingType;
|
|
10
|
+
export declare function getHeadingType(node: Node): HeadingType | null;
|
|
11
|
+
export declare function getListIndent(node: Node): number;
|
|
12
|
+
export declare function getListMode(node: Node): 'standard' | 'outline';
|
|
13
|
+
export declare function isOutlineListNode(node: Node): node is OutlineListItemElement;
|
|
14
|
+
export declare function getOutlineLevel(node: Node): number;
|
|
7
15
|
export declare function getNormalizedOrderedListStart(elem: ListItemElement): number;
|
|
8
16
|
export declare function getNormalizedOrderedListType(elem: ListItemElement): OrderedListType;
|
|
9
17
|
export declare function hasSameListConfig(a: ListItemElement, b: ListItemElement): boolean;
|
|
18
|
+
export declare function getOrderedItemNumber(editor: IDomEditor, elem: ListItemElement): number;
|
|
19
|
+
export declare function getOutlineNumber(editor: IDomEditor, elem: ListItemElement): string;
|
|
10
20
|
/**
|
|
11
21
|
* 获取上一个同一 level 的 list item
|
|
12
|
-
* @param editor
|
|
22
|
+
* @param editor editor
|
|
13
23
|
* @param elem elem
|
|
14
24
|
*/
|
|
15
25
|
export declare function getBrotherListNodeByLevel(editor: IDomEditor, elem: ListItemElement, level?: number): ListItemElement | null;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @description compose semantic outline HTML from additive list-item metadata
|
|
3
|
+
*/
|
|
4
|
+
import { HtmlTransformFnType } from '@wangeditor-next/core';
|
|
5
|
+
/**
|
|
6
|
+
* List-item serialization remains backward compatible for ordinary lists.
|
|
7
|
+
* Only outline list items need document-level composition to create valid
|
|
8
|
+
* `ol > li > hN` structure.
|
|
9
|
+
*/
|
|
10
|
+
export declare const transformListHtml: HtmlTransformFnType;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @description base
|
|
2
|
+
* @description list menu base class
|
|
3
3
|
* @author wangfupeng
|
|
4
4
|
*/
|
|
5
5
|
import { IButtonMenu, IDomEditor } from '@wangeditor-next/core';
|
|
@@ -11,7 +11,7 @@ declare abstract class BaseMenu implements IButtonMenu {
|
|
|
11
11
|
abstract readonly title: string;
|
|
12
12
|
abstract readonly iconSvg: string;
|
|
13
13
|
readonly tag = "button";
|
|
14
|
-
private
|
|
14
|
+
private isTargetListNode;
|
|
15
15
|
getValue(_editor: IDomEditor): string | boolean;
|
|
16
16
|
isActive(editor: IDomEditor): boolean;
|
|
17
17
|
isDisabled(editor: IDomEditor): boolean;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @description outline numbering marker actions
|
|
3
|
+
*/
|
|
4
|
+
import { IDomEditor } from '@wangeditor-next/core';
|
|
5
|
+
import { ListItemElement } from './custom-types';
|
|
6
|
+
export declare function continueOutlineNumbering(editor: IDomEditor, node: ListItemElement): void;
|
|
7
|
+
export declare function restartOutlineNumbering(editor: IDomEditor, node: ListItemElement): void;
|
|
8
|
+
export declare function hideOutlineActionPanel(editor: IDomEditor): void;
|
|
9
|
+
export declare function showOutlineActionPanel(editor: IDomEditor, node: ListItemElement, marker: HTMLElement): void;
|
|
@@ -3,4 +3,5 @@
|
|
|
3
3
|
* @author wangfupeng
|
|
4
4
|
*/
|
|
5
5
|
import { IDomEditor } from '@wangeditor-next/core';
|
|
6
|
-
|
|
6
|
+
import { BaseElement } from 'slate';
|
|
7
|
+
export declare const ELEM_TO_EDITOR: WeakMap<BaseElement, IDomEditor>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { IButtonMenu, IDomEditor } from '@wangeditor-next/core';
|
|
2
|
+
import { NodeEntry } from 'slate';
|
|
2
3
|
import TableProperty, { FieldName } from './TableProperty';
|
|
3
4
|
declare class CellProperty extends TableProperty implements IButtonMenu {
|
|
4
5
|
readonly title: string;
|
|
@@ -8,6 +9,6 @@ declare class CellProperty extends TableProperty implements IButtonMenu {
|
|
|
8
9
|
readonly modalWidth = 360;
|
|
9
10
|
readonly menu = "cell";
|
|
10
11
|
readonly propertyFields: FieldName[];
|
|
11
|
-
getModalContentNode(editor: IDomEditor):
|
|
12
|
+
getModalContentNode(editor: IDomEditor): NodeEntry;
|
|
12
13
|
}
|
|
13
14
|
export default CellProperty;
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* @author hsuna
|
|
4
4
|
*/
|
|
5
5
|
import { IButtonMenu, IDomEditor } from '@wangeditor-next/core';
|
|
6
|
+
import { NodeEntry } from 'slate';
|
|
6
7
|
export type FieldName = 'borderStyle' | 'borderColor' | 'borderWidth' | 'backgroundColor' | 'textAlign' | 'verticalAlign';
|
|
7
8
|
type SelectOption = {
|
|
8
9
|
value: string;
|
|
@@ -35,7 +36,7 @@ declare class TableProperty implements IButtonMenu {
|
|
|
35
36
|
isActive(_editor: IDomEditor): boolean;
|
|
36
37
|
isDisabled(editor: IDomEditor): boolean;
|
|
37
38
|
exec(_editor: IDomEditor, _value: string | boolean): void;
|
|
38
|
-
getModalContentNode(editor: IDomEditor):
|
|
39
|
+
getModalContentNode(editor: IDomEditor): NodeEntry;
|
|
39
40
|
getModalPositionNode(_editor: IDomEditor): null;
|
|
40
41
|
getModalContentElem(editor: IDomEditor): Element | null;
|
|
41
42
|
getPanelContentElem(editor: any, { mark, selectedColor, callback }: {
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { VNode } from 'snabbdom';
|
|
2
|
+
export type SelectionRect = {
|
|
3
|
+
top: number;
|
|
4
|
+
right: number;
|
|
5
|
+
bottom: number;
|
|
6
|
+
left: number;
|
|
7
|
+
};
|
|
8
|
+
export type SelectionPerimeterSide = 'top' | 'right' | 'bottom' | 'left';
|
|
9
|
+
export type SelectionPerimeterSegment = {
|
|
10
|
+
side: SelectionPerimeterSide;
|
|
11
|
+
offset: number;
|
|
12
|
+
start: number;
|
|
13
|
+
end: number;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Returns the physical perimeter of a set of non-overlapping cell rectangles. Opposing edges
|
|
17
|
+
* cancel only where they overlap, so partially exposed sides of merged cells remain precise.
|
|
18
|
+
*/
|
|
19
|
+
export declare function getSelectionPerimeterSegments(rects: SelectionRect[]): SelectionPerimeterSegment[];
|
|
20
|
+
export declare function drawSelectionOverlay(elm: Node | undefined): void;
|
|
21
|
+
export declare function renderSelectionOverlay(): VNode;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { BaseEditor, BaseElement } from 'slate';
|
|
1
2
|
import { NodeEntryWithContext } from '../utils';
|
|
2
3
|
/** Weak reference between the `Editor` and the selected elements */
|
|
3
|
-
export declare const EDITOR_TO_SELECTION: WeakMap<
|
|
4
|
+
export declare const EDITOR_TO_SELECTION: WeakMap<BaseEditor, NodeEntryWithContext[][]>;
|
|
4
5
|
/** Weak reference between the `Editor` and a set of the selected elements */
|
|
5
|
-
export declare const EDITOR_TO_SELECTION_SET: WeakMap<
|
|
6
|
+
export declare const EDITOR_TO_SELECTION_SET: WeakMap<BaseEditor, WeakSet<BaseElement>>;
|
|
@@ -10,7 +10,7 @@ import DOMText = globalThis.Text;
|
|
|
10
10
|
import DOMRange = globalThis.Range;
|
|
11
11
|
import DOMSelection = globalThis.Selection;
|
|
12
12
|
import DOMStaticRange = globalThis.StaticRange;
|
|
13
|
-
export { Dom7Array } from 'dom7';
|
|
13
|
+
export type { Dom7Array } from 'dom7';
|
|
14
14
|
export default $;
|
|
15
15
|
/**
|
|
16
16
|
* 获取 tagName lower-case
|
|
@@ -8,18 +8,9 @@ export interface WithTableOptions {
|
|
|
8
8
|
tr: ElementType;
|
|
9
9
|
table: ElementType;
|
|
10
10
|
tbody: ElementType;
|
|
11
|
-
tfoot
|
|
12
|
-
thead
|
|
11
|
+
tfoot?: ElementType;
|
|
12
|
+
thead?: ElementType;
|
|
13
13
|
};
|
|
14
14
|
}
|
|
15
|
-
export declare const DEFAULT_WITH_TABLE_OPTIONS:
|
|
16
|
-
blocks: {
|
|
17
|
-
td: string;
|
|
18
|
-
th: string;
|
|
19
|
-
content: string;
|
|
20
|
-
tr: string;
|
|
21
|
-
table: string;
|
|
22
|
-
tbody: string;
|
|
23
|
-
};
|
|
24
|
-
};
|
|
15
|
+
export declare const DEFAULT_WITH_TABLE_OPTIONS: WithTableOptions;
|
|
25
16
|
export {};
|
|
@@ -11,7 +11,7 @@ import DOMText = globalThis.Text;
|
|
|
11
11
|
import DOMRange = globalThis.Range;
|
|
12
12
|
import DOMSelection = globalThis.Selection;
|
|
13
13
|
import DOMStaticRange = globalThis.StaticRange;
|
|
14
|
-
export { Dom7Array } from 'dom7';
|
|
14
|
+
export type { Dom7Array } from 'dom7';
|
|
15
15
|
export default $;
|
|
16
16
|
/**
|
|
17
17
|
* 获取 tagName lower-case
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wangeditor-next/plugin-link-card",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "6.2.0",
|
|
4
4
|
"description": "wangEditor link card plugin",
|
|
5
5
|
"author": "cycleccc <2991205548@qq.com>",
|
|
6
6
|
"type": "module",
|
|
@@ -34,10 +34,10 @@
|
|
|
34
34
|
"url": "https://github.com/wangeditor-next/wangEditor-next/issues"
|
|
35
35
|
},
|
|
36
36
|
"peerDependencies": {
|
|
37
|
-
"@wangeditor-next/editor": ">=6.0.0",
|
|
38
37
|
"dom7": "^3.0.0 || ^4.0.0",
|
|
39
38
|
"slate": "^0.124.0",
|
|
40
|
-
"snabbdom": "^3.6.0"
|
|
39
|
+
"snabbdom": "^3.6.0",
|
|
40
|
+
"@wangeditor-next/editor": "^6.2.0"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@wangeditor-next-shared/rollup-config": "^0.0.2"
|