@docs.plus/extension-hyperlink 1.0.4
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/README.md +172 -0
- package/dist/helpers/autoHyperlink.d.ts +8 -0
- package/dist/helpers/clickHandler.d.ts +16 -0
- package/dist/helpers/editHyperlink.d.ts +9 -0
- package/dist/helpers/pasteHandler.d.ts +9 -0
- package/dist/helpers/tippyHelper.d.ts +20 -0
- package/dist/hyperlink.d.ts +75 -0
- package/dist/index.cjs +496 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +490 -0
- package/dist/index.js.map +1 -0
- package/dist/index.umd.js +497 -0
- package/dist/index.umd.js.map +1 -0
- package/package.json +44 -0
- package/src/helpers/autoHyperlink.ts +167 -0
- package/src/helpers/clickHandler.ts +76 -0
- package/src/helpers/editHyperlink.ts +55 -0
- package/src/helpers/pasteHandler.ts +46 -0
- package/src/helpers/tippyHelper.ts +126 -0
- package/src/hyperlink.ts +272 -0
- package/src/index.ts +6 -0
package/README.md
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
# Hyperlink
|
|
2
|
+
|
|
3
|
+
The Hyperlink extension adds support for tags to the editor. The extension is headless too, there is no actual UI to add, modify or delete links. The usage example below uses the native JavaScript prompt to show you how that could work.
|
|
4
|
+
|
|
5
|
+
In a real world application, you would probably add a more sophisticated user interface.
|
|
6
|
+
|
|
7
|
+
Pasted URLs will be transformed to links automatically.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
````sh
|
|
12
|
+
npm install @docsplus/extension-hyperlink
|
|
13
|
+
````
|
|
14
|
+
|
|
15
|
+
## Settings
|
|
16
|
+
|
|
17
|
+
### protocols
|
|
18
|
+
|
|
19
|
+
Additional custom protocols you would like to be recognized as links.
|
|
20
|
+
|
|
21
|
+
Default: []
|
|
22
|
+
|
|
23
|
+
````js
|
|
24
|
+
Hyperlink.configure({
|
|
25
|
+
protocols: ['ftp', 'mailto'],
|
|
26
|
+
})
|
|
27
|
+
````
|
|
28
|
+
|
|
29
|
+
By default, linkify adds // to the end of a protocol however this behavior can be changed by passing optionalSlashes option
|
|
30
|
+
|
|
31
|
+
````js
|
|
32
|
+
Hyperlink.configure({
|
|
33
|
+
protocols: [
|
|
34
|
+
{
|
|
35
|
+
scheme: 'tel',
|
|
36
|
+
optionalSlashes: true
|
|
37
|
+
}
|
|
38
|
+
]
|
|
39
|
+
})
|
|
40
|
+
````
|
|
41
|
+
|
|
42
|
+
### autolink
|
|
43
|
+
|
|
44
|
+
If enabled, it adds links as you type.
|
|
45
|
+
|
|
46
|
+
Default: true
|
|
47
|
+
|
|
48
|
+
````js
|
|
49
|
+
Hyperlink.configure({
|
|
50
|
+
autolink: false,
|
|
51
|
+
})
|
|
52
|
+
````
|
|
53
|
+
|
|
54
|
+
### openOnClick
|
|
55
|
+
|
|
56
|
+
If enabled, links will be opened on click.
|
|
57
|
+
|
|
58
|
+
Default: true
|
|
59
|
+
|
|
60
|
+
````js
|
|
61
|
+
Hyperlink.configure({
|
|
62
|
+
openOnClick: false,
|
|
63
|
+
})
|
|
64
|
+
````
|
|
65
|
+
|
|
66
|
+
### linkOnPaste
|
|
67
|
+
|
|
68
|
+
Adds a link to the current selection if the pasted content only contains an url.
|
|
69
|
+
|
|
70
|
+
Default: true
|
|
71
|
+
|
|
72
|
+
````js
|
|
73
|
+
Hyperlink.configure({
|
|
74
|
+
linkOnPaste: false,
|
|
75
|
+
})
|
|
76
|
+
````
|
|
77
|
+
|
|
78
|
+
### HTMLAttributes
|
|
79
|
+
|
|
80
|
+
Custom HTML attributes that should be added to the rendered HTML tag.
|
|
81
|
+
|
|
82
|
+
````js
|
|
83
|
+
Hyperlink.configure({
|
|
84
|
+
HTMLAttributes: {
|
|
85
|
+
class: 'my-custom-class',
|
|
86
|
+
},
|
|
87
|
+
})
|
|
88
|
+
````
|
|
89
|
+
|
|
90
|
+
### Modals
|
|
91
|
+
|
|
92
|
+
The modals configuration option lets you incorporate an interactive user interface similar to Google Docs for setting and previewing hyperlinks. This provides users with a more intuitive and interactive experience; [More details in the code](https://github.com/HMarzban/extension-hyperlink/blob/4f37ffa18237f10d76c316844b1c2ab20b751fe9/packages/nextjs/src/components/Tiptap.tsx#L21-L28).
|
|
93
|
+
````js
|
|
94
|
+
Hyperlink.configure({
|
|
95
|
+
modals: {
|
|
96
|
+
previewHyperlink: (data) => {
|
|
97
|
+
return previewHyperlinkModal(data);
|
|
98
|
+
},
|
|
99
|
+
setHyperlink: (data) => {
|
|
100
|
+
return setHyperlinks(data);
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
})
|
|
104
|
+
````
|
|
105
|
+
|
|
106
|
+
### Removing and overriding existing html attributes
|
|
107
|
+
|
|
108
|
+
You can add rel: null to HTMLAttributes to remove the default rel="noopener noreferrer nofollow". You can also override the default by using rel: "your-value".
|
|
109
|
+
|
|
110
|
+
This can also be used to change the target from the default value of _blank.
|
|
111
|
+
|
|
112
|
+
````js
|
|
113
|
+
Hyperlink.configure({
|
|
114
|
+
HTMLAttributes: {
|
|
115
|
+
// Change rel to different value
|
|
116
|
+
// Allow search engines to follow links(remove nofollow)
|
|
117
|
+
rel: 'noopener noreferrer',
|
|
118
|
+
// Remove target entirely so links open in current tab
|
|
119
|
+
target: null,
|
|
120
|
+
},
|
|
121
|
+
})
|
|
122
|
+
````
|
|
123
|
+
|
|
124
|
+
### validate
|
|
125
|
+
|
|
126
|
+
A function that validates every autolinked link. If it exists, it will be called with the link href as argument. If it returns false, the link will be removed.
|
|
127
|
+
|
|
128
|
+
Can be used to set rules for example excluding or including certain domains, tlds, etc.
|
|
129
|
+
|
|
130
|
+
````js
|
|
131
|
+
// only autolink urls with a protocol
|
|
132
|
+
Hyperlink.configure({
|
|
133
|
+
validate: href => /^https?:\/\//.test(href),
|
|
134
|
+
})
|
|
135
|
+
````
|
|
136
|
+
|
|
137
|
+
## Commands
|
|
138
|
+
|
|
139
|
+
### editHyperLinkText(), editHyperLinkHref(), editHyperlink()
|
|
140
|
+
|
|
141
|
+
These commands allow you to edit the text and href value of a hyperlink.
|
|
142
|
+
|
|
143
|
+
```js
|
|
144
|
+
editor.commands.editHyperLinkText('New Text')
|
|
145
|
+
editor.commands.editHyperLinkHref('https://new-url.com')
|
|
146
|
+
editor.commands.editHyperlink({
|
|
147
|
+
newText: 'New Text', newURL: 'https://new-url.com'
|
|
148
|
+
})
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### setHyperlink()
|
|
152
|
+
|
|
153
|
+
Links the selected text.
|
|
154
|
+
|
|
155
|
+
````js
|
|
156
|
+
editor.commands.setHyperlink({ href: '<https://example.com>' })
|
|
157
|
+
editor.commands.setHyperlink({ href: '<https://example.com>', target: '_blank' })
|
|
158
|
+
editor.commands.unsetHyperlink()
|
|
159
|
+
````
|
|
160
|
+
|
|
161
|
+
### unsetHyperlink()
|
|
162
|
+
|
|
163
|
+
Removes a Hyperlink.
|
|
164
|
+
|
|
165
|
+
````js
|
|
166
|
+
editor.commands.unsetHyperlink()
|
|
167
|
+
````
|
|
168
|
+
|
|
169
|
+
## Keyboard shortcuts
|
|
170
|
+
|
|
171
|
+
Doesn’t have a keyboard shortcut
|
|
172
|
+
This extension doesn’t bind a specific keyboard shortcut. You would probably open your custom UI on Mod-k though.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { MarkType } from "@tiptap/pm/model";
|
|
2
|
+
import { Plugin } from "@tiptap/pm/state";
|
|
3
|
+
type AutoHyperlinkOptions = {
|
|
4
|
+
type: MarkType;
|
|
5
|
+
validate?: (url: string) => boolean;
|
|
6
|
+
};
|
|
7
|
+
export default function autoHyperlink(options: AutoHyperlinkOptions): Plugin;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { MarkType } from "@tiptap/pm/model";
|
|
2
|
+
import { Plugin } from "@tiptap/pm/state";
|
|
3
|
+
import { Editor } from "@tiptap/core";
|
|
4
|
+
import { EditorView } from "@tiptap/pm/view";
|
|
5
|
+
type ClickHandlerOptions = {
|
|
6
|
+
type: MarkType;
|
|
7
|
+
editor: Editor;
|
|
8
|
+
validate?: (url: string) => boolean;
|
|
9
|
+
view: EditorView;
|
|
10
|
+
modals: {
|
|
11
|
+
previewHyperlink?: ((options: any) => HTMLElement) | null;
|
|
12
|
+
setHyperlink?: ((options: any) => HTMLElement) | null;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
export default function clickHandler(options: ClickHandlerOptions): Plugin;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Editor } from "@tiptap/core";
|
|
2
|
+
type EditHyperlinkOptions = {
|
|
3
|
+
editor: Editor;
|
|
4
|
+
validate?: (url: string) => boolean;
|
|
5
|
+
newURL?: string;
|
|
6
|
+
newText?: string;
|
|
7
|
+
};
|
|
8
|
+
export default function editHyperlink(options: EditHyperlinkOptions): boolean;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Editor } from "@tiptap/core";
|
|
2
|
+
import { MarkType } from "@tiptap/pm/model";
|
|
3
|
+
import { Plugin } from "@tiptap/pm/state";
|
|
4
|
+
type PasteHandlerOptions = {
|
|
5
|
+
editor: Editor;
|
|
6
|
+
type: MarkType;
|
|
7
|
+
};
|
|
8
|
+
export declare function pasteHandler(options: PasteHandlerOptions): Plugin;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Instance, Props } from "tippy.js";
|
|
2
|
+
import { Editor } from "@tiptap/core";
|
|
3
|
+
import { EditorView } from "@tiptap/pm/view";
|
|
4
|
+
type TippyInitOptions = {
|
|
5
|
+
editor: Editor;
|
|
6
|
+
validate?: (url: string) => boolean;
|
|
7
|
+
view: EditorView;
|
|
8
|
+
};
|
|
9
|
+
export declare const init: (options: TippyInitOptions) => {
|
|
10
|
+
tippyModal: HTMLDivElement;
|
|
11
|
+
tippyInstance: Instance<Props> | undefined;
|
|
12
|
+
};
|
|
13
|
+
export declare const show: () => boolean;
|
|
14
|
+
export declare const hide: () => boolean;
|
|
15
|
+
export declare const mousedownHandler: () => void;
|
|
16
|
+
export declare const dragstartHandler: () => void;
|
|
17
|
+
export declare const focusHandler: () => void;
|
|
18
|
+
export declare const update: (view: EditorView, option?: any) => {};
|
|
19
|
+
export declare const destroyTooltip: () => void;
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { Mark } from "@tiptap/core";
|
|
2
|
+
export interface LinkProtocolOptions {
|
|
3
|
+
scheme: string;
|
|
4
|
+
optionalSlashes?: boolean;
|
|
5
|
+
}
|
|
6
|
+
export interface HyperlinkOptions {
|
|
7
|
+
/**
|
|
8
|
+
* If enabled, it adds links as you type.
|
|
9
|
+
*/
|
|
10
|
+
autoHyperlink: boolean;
|
|
11
|
+
/**
|
|
12
|
+
* An array of custom protocols to be registered with linkifyjs.
|
|
13
|
+
*/
|
|
14
|
+
protocols: Array<LinkProtocolOptions | string>;
|
|
15
|
+
/**
|
|
16
|
+
* If enabled, links will be opened on click.
|
|
17
|
+
*/
|
|
18
|
+
openOnClick: boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Adds a link to the current selection if the pasted content only contains an url.
|
|
21
|
+
*/
|
|
22
|
+
hyperlinkOnPaste: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* A list of HTML attributes to be rendered.
|
|
25
|
+
*/
|
|
26
|
+
HTMLAttributes: Record<string, any>;
|
|
27
|
+
/**
|
|
28
|
+
* A list of modals to be rendered.
|
|
29
|
+
* @default null
|
|
30
|
+
* @example
|
|
31
|
+
*/
|
|
32
|
+
modals: {
|
|
33
|
+
previewHyperlink?: ((options: any) => HTMLElement) | null;
|
|
34
|
+
setHyperlink?: ((options: any) => HTMLElement) | null;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* A validation function that modifies link verification for the auto linker.
|
|
38
|
+
* @param url - The url to be validated.
|
|
39
|
+
* @returns - True if the url is valid, false otherwise.
|
|
40
|
+
*/
|
|
41
|
+
validate?: (url: string) => boolean;
|
|
42
|
+
}
|
|
43
|
+
declare module "@tiptap/core" {
|
|
44
|
+
interface Commands<ReturnType> {
|
|
45
|
+
link: {
|
|
46
|
+
/**
|
|
47
|
+
* Edit the hyperlink's text
|
|
48
|
+
*/
|
|
49
|
+
editHyperLinkText: (text: string) => ReturnType;
|
|
50
|
+
/**
|
|
51
|
+
* Edit the hyperlink's href value
|
|
52
|
+
*/
|
|
53
|
+
editHyperLinkHref: (href: string) => ReturnType;
|
|
54
|
+
/**
|
|
55
|
+
* Edit the hyperlink's
|
|
56
|
+
*/
|
|
57
|
+
editHyperlink: (attributes?: {
|
|
58
|
+
newText?: string;
|
|
59
|
+
newURL?: string;
|
|
60
|
+
}) => ReturnType;
|
|
61
|
+
/**
|
|
62
|
+
* Set a hyperlink
|
|
63
|
+
*/
|
|
64
|
+
setHyperlink: (attributes?: {
|
|
65
|
+
href: string;
|
|
66
|
+
target?: string | null;
|
|
67
|
+
}) => ReturnType;
|
|
68
|
+
/**
|
|
69
|
+
* Unset a link mark
|
|
70
|
+
*/
|
|
71
|
+
unsetHyperlink: () => ReturnType;
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
export declare const Hyperlink: Mark<HyperlinkOptions, any>;
|