@tiptap/extension-link 2.11.6 → 3.0.0-beta.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/src/link.ts CHANGED
@@ -1,7 +1,6 @@
1
- import {
2
- Mark, markPasteRule, mergeAttributes, PasteRuleMatch,
3
- } from '@tiptap/core'
4
- import { Plugin } from '@tiptap/pm/state'
1
+ import type { PasteRuleMatch } from '@tiptap/core'
2
+ import { Mark, markPasteRule, mergeAttributes } from '@tiptap/core'
3
+ import type { Plugin } from '@tiptap/pm/state'
5
4
  import { find, registerCustomProtocol, reset } from 'linkifyjs'
6
5
 
7
6
  import { autolink } from './helpers/autolink.js'
@@ -15,22 +14,23 @@ export interface LinkProtocolOptions {
15
14
  * @example 'ftp'
16
15
  * @example 'git'
17
16
  */
18
- scheme: string;
17
+ scheme: string
19
18
 
20
19
  /**
21
20
  * If enabled, it allows optional slashes after the protocol.
22
21
  * @default false
23
22
  * @example true
24
23
  */
25
- optionalSlashes?: boolean;
24
+ optionalSlashes?: boolean
26
25
  }
27
26
 
28
- export const pasteRegex = /https?:\/\/(?:www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z]{2,}\b(?:[-a-zA-Z0-9@:%._+~#=?!&/]*)(?:[-a-zA-Z0-9@:%._+~#=?!&/]*)/gi
27
+ export const pasteRegex =
28
+ /https?:\/\/(?:www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z]{2,}\b(?:[-a-zA-Z0-9@:%._+~#=?!&/]*)(?:[-a-zA-Z0-9@:%._+~#=?!&/]*)/gi
29
29
 
30
30
  /**
31
31
  * @deprecated The default behavior is now to open links when the editor is not editable.
32
32
  */
33
- type DeprecatedOpenWhenNotEditable = 'whenNotEditable';
33
+ type DeprecatedOpenWhenNotEditable = 'whenNotEditable'
34
34
 
35
35
  export interface LinkOptions {
36
36
  /**
@@ -38,39 +38,39 @@ export interface LinkOptions {
38
38
  * @default true
39
39
  * @example false
40
40
  */
41
- autolink: boolean;
41
+ autolink: boolean
42
42
 
43
43
  /**
44
44
  * An array of custom protocols to be registered with linkifyjs.
45
45
  * @default []
46
46
  * @example ['ftp', 'git']
47
47
  */
48
- protocols: Array<LinkProtocolOptions | string>;
48
+ protocols: Array<LinkProtocolOptions | string>
49
49
 
50
50
  /**
51
51
  * Default protocol to use when no protocol is specified.
52
52
  * @default 'http'
53
53
  */
54
- defaultProtocol: string;
54
+ defaultProtocol: string
55
55
  /**
56
56
  * If enabled, links will be opened on click.
57
57
  * @default true
58
58
  * @example false
59
59
  */
60
- openOnClick: boolean | DeprecatedOpenWhenNotEditable;
60
+ openOnClick: boolean | DeprecatedOpenWhenNotEditable
61
61
  /**
62
62
  * Adds a link to the current selection if the pasted content only contains an url.
63
63
  * @default true
64
64
  * @example false
65
65
  */
66
- linkOnPaste: boolean;
66
+ linkOnPaste: boolean
67
67
 
68
68
  /**
69
69
  * HTML attributes to add to the link element.
70
70
  * @default {}
71
71
  * @example { class: 'foo' }
72
72
  */
73
- HTMLAttributes: Record<string, any>;
73
+ HTMLAttributes: Record<string, any>
74
74
 
75
75
  /**
76
76
  * @deprecated Use the `shouldAutoLink` option instead.
@@ -78,7 +78,7 @@ export interface LinkOptions {
78
78
  * @param url - The url to be validated.
79
79
  * @returns - True if the url is valid, false otherwise.
80
80
  */
81
- validate: (url: string) => boolean;
81
+ validate: (url: string) => boolean
82
82
 
83
83
  /**
84
84
  * A validation function which is used for configuring link verification for preventing XSS attacks.
@@ -100,17 +100,17 @@ export interface LinkOptions {
100
100
  /**
101
101
  * The default validation function.
102
102
  */
103
- defaultValidate: (url: string) => boolean;
103
+ defaultValidate: (url: string) => boolean
104
104
  /**
105
105
  * An array of allowed protocols for the URL (e.g., "http", "https"). As defined in the `protocols` option.
106
106
  */
107
- protocols: Array<LinkProtocolOptions | string>;
107
+ protocols: Array<LinkProtocolOptions | string>
108
108
  /**
109
109
  * A string that represents the default protocol (e.g., 'http'). As defined in the `defaultProtocol` option.
110
110
  */
111
- defaultProtocol: string;
112
- }
113
- ) => boolean;
111
+ defaultProtocol: string
112
+ },
113
+ ) => boolean
114
114
 
115
115
  /**
116
116
  * Determines whether a valid link should be automatically linked in the content.
@@ -118,7 +118,7 @@ export interface LinkOptions {
118
118
  * @param {string} url - The URL that has already been validated.
119
119
  * @returns {boolean} - True if the link should be auto-linked; false if it should not be auto-linked.
120
120
  */
121
- shouldAutoLink: (url: string) => boolean;
121
+ shouldAutoLink: (url: string) => boolean
122
122
  }
123
123
 
124
124
  declare module '@tiptap/core' {
@@ -130,28 +130,28 @@ declare module '@tiptap/core' {
130
130
  * @example editor.commands.setLink({ href: 'https://tiptap.dev' })
131
131
  */
132
132
  setLink: (attributes: {
133
- href: string;
134
- target?: string | null;
135
- rel?: string | null;
136
- class?: string | null;
137
- }) => ReturnType;
133
+ href: string
134
+ target?: string | null
135
+ rel?: string | null
136
+ class?: string | null
137
+ }) => ReturnType
138
138
  /**
139
139
  * Toggle a link mark
140
140
  * @param attributes The link attributes
141
141
  * @example editor.commands.toggleLink({ href: 'https://tiptap.dev' })
142
142
  */
143
143
  toggleLink: (attributes: {
144
- href: string;
145
- target?: string | null;
146
- rel?: string | null;
147
- class?: string | null;
148
- }) => ReturnType;
144
+ href: string
145
+ target?: string | null
146
+ rel?: string | null
147
+ class?: string | null
148
+ }) => ReturnType
149
149
  /**
150
150
  * Unset a link mark
151
151
  * @example editor.commands.unsetLink()
152
152
  */
153
- unsetLink: () => ReturnType;
154
- };
153
+ unsetLink: () => ReturnType
154
+ }
155
155
  }
156
156
  }
157
157
 
@@ -161,18 +161,7 @@ declare module '@tiptap/core' {
161
161
  const ATTR_WHITESPACE = /[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g
162
162
 
163
163
  export function isAllowedUri(uri: string | undefined, protocols?: LinkOptions['protocols']) {
164
- const allowedProtocols: string[] = [
165
- 'http',
166
- 'https',
167
- 'ftp',
168
- 'ftps',
169
- 'mailto',
170
- 'tel',
171
- 'callto',
172
- 'sms',
173
- 'cid',
174
- 'xmpp',
175
- ]
164
+ const allowedProtocols: string[] = ['http', 'https', 'ftp', 'ftps', 'mailto', 'tel', 'callto', 'sms', 'cid', 'xmpp']
176
165
 
177
166
  if (protocols) {
178
167
  protocols.forEach(protocol => {
@@ -185,16 +174,14 @@ export function isAllowedUri(uri: string | undefined, protocols?: LinkOptions['p
185
174
  }
186
175
 
187
176
  return (
188
- !uri
189
- || uri
190
- .replace(ATTR_WHITESPACE, '')
191
- .match(
192
- new RegExp(
193
- // eslint-disable-next-line no-useless-escape
194
- `^(?:(?:${allowedProtocols.join('|')}):|[^a-z]|[a-z0-9+.\-]+(?:[^a-z+.\-:]|$))`,
195
- 'i',
196
- ),
197
- )
177
+ !uri ||
178
+ uri.replace(ATTR_WHITESPACE, '').match(
179
+ new RegExp(
180
+ // eslint-disable-next-line no-useless-escape
181
+ `^(?:(?:${allowedProtocols.join('|')}):|[^a-z]|[a-z0-9+.\-]+(?:[^a-z+.\-:]|$))`,
182
+ 'i',
183
+ ),
184
+ )
198
185
  )
199
186
  }
200
187
 
@@ -215,9 +202,7 @@ export const Link = Mark.create<LinkOptions>({
215
202
  if (this.options.validate && !this.options.shouldAutoLink) {
216
203
  // Copy the validate function to the shouldAutoLink option
217
204
  this.options.shouldAutoLink = this.options.validate
218
- console.warn(
219
- 'The `validate` option is deprecated. Rename to the `shouldAutoLink` option instead.',
220
- )
205
+ console.warn('The `validate` option is deprecated. Rename to the `shouldAutoLink` option instead.')
221
206
  }
222
207
  this.options.protocols.forEach(protocol => {
223
208
  if (typeof protocol === 'string') {
@@ -283,8 +268,8 @@ export const Link = Mark.create<LinkOptions>({
283
268
 
284
269
  // prevent XSS attacks
285
270
  if (
286
- !href
287
- || !this.options.isAllowedUri(href, {
271
+ !href ||
272
+ !this.options.isAllowedUri(href, {
288
273
  defaultValidate: url => !!isAllowedUri(url, this.options.protocols),
289
274
  protocols: this.options.protocols,
290
275
  defaultProtocol: this.options.defaultProtocol,
@@ -308,11 +293,7 @@ export const Link = Mark.create<LinkOptions>({
308
293
  })
309
294
  ) {
310
295
  // strip out the href
311
- return [
312
- 'a',
313
- mergeAttributes(this.options.HTMLAttributes, { ...HTMLAttributes, href: '' }),
314
- 0,
315
- ]
296
+ return ['a', mergeAttributes(this.options.HTMLAttributes, { ...HTMLAttributes, href: '' }), 0]
316
297
  }
317
298
 
318
299
  return ['a', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]
@@ -321,14 +302,17 @@ export const Link = Mark.create<LinkOptions>({
321
302
  addCommands() {
322
303
  return {
323
304
  setLink:
324
- attributes => ({ chain }) => {
305
+ attributes =>
306
+ ({ chain }) => {
325
307
  const { href } = attributes
326
308
 
327
- if (!this.options.isAllowedUri(href, {
328
- defaultValidate: url => !!isAllowedUri(url, this.options.protocols),
329
- protocols: this.options.protocols,
330
- defaultProtocol: this.options.defaultProtocol,
331
- })) {
309
+ if (
310
+ !this.options.isAllowedUri(href, {
311
+ defaultValidate: url => !!isAllowedUri(url, this.options.protocols),
312
+ protocols: this.options.protocols,
313
+ defaultProtocol: this.options.defaultProtocol,
314
+ })
315
+ ) {
332
316
  return false
333
317
  }
334
318
 
@@ -336,14 +320,17 @@ export const Link = Mark.create<LinkOptions>({
336
320
  },
337
321
 
338
322
  toggleLink:
339
- attributes => ({ chain }) => {
323
+ attributes =>
324
+ ({ chain }) => {
340
325
  const { href } = attributes
341
326
 
342
- if (!this.options.isAllowedUri(href, {
343
- defaultValidate: url => !!isAllowedUri(url, this.options.protocols),
344
- protocols: this.options.protocols,
345
- defaultProtocol: this.options.defaultProtocol,
346
- })) {
327
+ if (
328
+ !this.options.isAllowedUri(href, {
329
+ defaultValidate: url => !!isAllowedUri(url, this.options.protocols),
330
+ protocols: this.options.protocols,
331
+ defaultProtocol: this.options.defaultProtocol,
332
+ })
333
+ ) {
347
334
  return false
348
335
  }
349
336
 
@@ -354,11 +341,9 @@ export const Link = Mark.create<LinkOptions>({
354
341
  },
355
342
 
356
343
  unsetLink:
357
- () => ({ chain }) => {
358
- return chain()
359
- .unsetMark(this.name, { extendEmptyMarkRange: true })
360
- .setMeta('preventAutolink', true)
361
- .run()
344
+ () =>
345
+ ({ chain }) => {
346
+ return chain().unsetMark(this.name, { extendEmptyMarkRange: true }).setMeta('preventAutolink', true).run()
362
347
  },
363
348
  }
364
349
  },
@@ -372,8 +357,9 @@ export const Link = Mark.create<LinkOptions>({
372
357
  if (text) {
373
358
  const { protocols, defaultProtocol } = this.options
374
359
  const links = find(text).filter(
375
- item => item.isLink
376
- && this.options.isAllowedUri(item.value, {
360
+ item =>
361
+ item.isLink &&
362
+ this.options.isAllowedUri(item.value, {
377
363
  defaultValidate: href => !!isAllowedUri(href, protocols),
378
364
  protocols,
379
365
  defaultProtocol,
@@ -381,13 +367,15 @@ export const Link = Mark.create<LinkOptions>({
381
367
  )
382
368
 
383
369
  if (links.length) {
384
- links.forEach(link => foundLinks.push({
385
- text: link.value,
386
- data: {
387
- href: link.href,
388
- },
389
- index: link.start,
390
- }))
370
+ links.forEach(link =>
371
+ foundLinks.push({
372
+ text: link.value,
373
+ data: {
374
+ href: link.href,
375
+ },
376
+ index: link.start,
377
+ }),
378
+ )
391
379
  }
392
380
  }
393
381
 
@@ -412,11 +400,12 @@ export const Link = Mark.create<LinkOptions>({
412
400
  autolink({
413
401
  type: this.type,
414
402
  defaultProtocol: this.options.defaultProtocol,
415
- validate: url => this.options.isAllowedUri(url, {
416
- defaultValidate: href => !!isAllowedUri(href, protocols),
417
- protocols,
418
- defaultProtocol,
419
- }),
403
+ validate: url =>
404
+ this.options.isAllowedUri(url, {
405
+ defaultValidate: href => !!isAllowedUri(href, protocols),
406
+ protocols,
407
+ defaultProtocol,
408
+ }),
420
409
  shouldAutoLink: this.options.shouldAutoLink,
421
410
  }),
422
411
  )
@@ -1,16 +0,0 @@
1
- import { MarkType } from '@tiptap/pm/model';
2
- import { Plugin } from '@tiptap/pm/state';
3
- type AutolinkOptions = {
4
- type: MarkType;
5
- defaultProtocol: string;
6
- validate: (url: string) => boolean;
7
- shouldAutoLink: (url: string) => boolean;
8
- };
9
- /**
10
- * This plugin allows you to automatically add links to your editor.
11
- * @param options The plugin options
12
- * @returns The plugin instance
13
- */
14
- export declare function autolink(options: AutolinkOptions): Plugin;
15
- export {};
16
- //# sourceMappingURL=autolink.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"autolink.d.ts","sourceRoot":"","sources":["../../src/helpers/autolink.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAC3C,OAAO,EAAE,MAAM,EAAa,MAAM,kBAAkB,CAAA;AAyBpD,KAAK,eAAe,GAAG;IACrB,IAAI,EAAE,QAAQ,CAAA;IACd,eAAe,EAAE,MAAM,CAAA;IACvB,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAA;IAClC,cAAc,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAA;CACzC,CAAA;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,MAAM,CAgIzD"}
@@ -1,8 +0,0 @@
1
- import { MarkType } from '@tiptap/pm/model';
2
- import { Plugin } from '@tiptap/pm/state';
3
- type ClickHandlerOptions = {
4
- type: MarkType;
5
- };
6
- export declare function clickHandler(options: ClickHandlerOptions): Plugin;
7
- export {};
8
- //# sourceMappingURL=clickHandler.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"clickHandler.d.ts","sourceRoot":"","sources":["../../src/helpers/clickHandler.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAC3C,OAAO,EAAE,MAAM,EAAa,MAAM,kBAAkB,CAAA;AAEpD,KAAK,mBAAmB,GAAG;IACzB,IAAI,EAAE,QAAQ,CAAC;CAChB,CAAA;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,MAAM,CAyCjE"}
@@ -1,11 +0,0 @@
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
- defaultProtocol: string;
7
- type: MarkType;
8
- };
9
- export declare function pasteHandler(options: PasteHandlerOptions): Plugin;
10
- export {};
11
- //# sourceMappingURL=pasteHandler.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"pasteHandler.d.ts","sourceRoot":"","sources":["../../src/helpers/pasteHandler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAC3C,OAAO,EAAE,MAAM,EAAa,MAAM,kBAAkB,CAAA;AAGpD,KAAK,mBAAmB,GAAG;IACzB,MAAM,EAAE,MAAM,CAAA;IACd,eAAe,EAAE,MAAM,CAAA;IACvB,IAAI,EAAE,QAAQ,CAAA;CACf,CAAA;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,MAAM,CA+BjE"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAEhC,cAAc,WAAW,CAAA;AAEzB,eAAe,IAAI,CAAA"}