feat(extension-link): add support for default protocol (#5022)

This commit is contained in:
Henry Stelle 2024-06-07 10:37:48 -04:00 committed by GitHub
parent a52118c34b
commit ff6e00a356
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 48 additions and 2 deletions

View File

@ -20,6 +20,7 @@ export default () => {
Link.configure({
openOnClick: false,
autolink: true,
defaultProtocol: 'https',
}),
],
content: `

View File

@ -62,6 +62,16 @@ context('/src/Marks/Link/React/', () => {
.should('have.attr', 'href', 'https://tiptap4u.com')
})
it('uses the default protocol', () => {
cy.get('.tiptap').type('example.com ').find('a').should('contain', 'example.com')
.should('have.attr', 'href', 'https://example.com')
})
it('uses a non-default protocol if present', () => {
cy.get('.tiptap').type('http://example.com ').find('a').should('contain', 'http://example.com')
.should('have.attr', 'href', 'http://example.com')
})
it('detects a pasted URL within a text', () => {
cy.get('.tiptap')
.paste({

View File

@ -73,6 +73,16 @@ context('/src/Marks/Link/Vue/', () => {
.should('have.attr', 'href', 'https://tiptap4u.com')
})
it('uses the default protocol', () => {
cy.get('.tiptap').type('example.com ').find('a').should('contain', 'example.com')
.should('have.attr', 'href', 'https://example.com')
})
it('uses a non-default protocol if present', () => {
cy.get('.tiptap').type('http://example.com ').find('a').should('contain', 'http://example.com')
.should('have.attr', 'href', 'http://example.com')
})
it('detects a pasted URL with query params', () => {
cy.get('.tiptap')
.type('{backspace}')

View File

@ -38,6 +38,7 @@ export default {
Code,
Link.configure({
openOnClick: false,
defaultProtocol: 'https',
}),
],
content: `

View File

@ -76,6 +76,20 @@ Link.configure({
})
```
### default protocol
The default protocol used by `linkOnPaste` and `autolink` when no protocol is defined.
By default, the href generated for example.com is http://example.com and this option allows that protocol to be customized.
Default: `http`
```js
Link.configure({
defaultProtocol: 'https',
})
```
### HTMLAttributes
Custom HTML attributes that should be added to the rendered HTML tag.

View File

@ -33,6 +33,7 @@ function isValidLinkStructure(tokens: Array<ReturnType<MultiToken['toObject']>>)
type AutolinkOptions = {
type: MarkType
defaultProtocol: string
validate: (url: string) => boolean
}
@ -115,7 +116,7 @@ export function autolink(options: AutolinkOptions): Plugin {
return false
}
const linksBeforeSpace = tokenize(lastWordBeforeSpace).map(t => t.toObject())
const linksBeforeSpace = tokenize(lastWordBeforeSpace).map(t => t.toObject(options.defaultProtocol))
if (!isValidLinkStructure(linksBeforeSpace)) {
return false

View File

@ -5,6 +5,7 @@ import { find } from 'linkifyjs'
type PasteHandlerOptions = {
editor: Editor
defaultProtocol: string
type: MarkType
}
@ -27,7 +28,7 @@ export function pasteHandler(options: PasteHandlerOptions): Plugin {
textContent += node.textContent
})
const link = find(textContent).find(item => item.isLink && item.value === textContent)
const link = find(textContent, { defaultProtocol: options.defaultProtocol }).find(item => item.isLink && item.value === textContent)
if (!textContent || !link) {
return false

View File

@ -42,6 +42,11 @@ export interface LinkOptions {
*/
protocols: Array<LinkProtocolOptions | string>
/**
* Default protocol to use when no protocol is specified.
* @default 'http'
*/
defaultProtocol: string
/**
* If enabled, links will be opened on click.
* @default true
@ -139,6 +144,7 @@ export const Link = Mark.create<LinkOptions>({
linkOnPaste: true,
autolink: true,
protocols: [],
defaultProtocol: 'http',
HTMLAttributes: {
target: '_blank',
rel: 'noopener noreferrer nofollow',
@ -255,6 +261,7 @@ export const Link = Mark.create<LinkOptions>({
plugins.push(
autolink({
type: this.type,
defaultProtocol: this.options.defaultProtocol,
validate: this.options.validate,
}),
)
@ -272,6 +279,7 @@ export const Link = Mark.create<LinkOptions>({
plugins.push(
pasteHandler({
editor: this.editor,
defaultProtocol: this.options.defaultProtocol,
type: this.type,
}),
)