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({ Link.configure({
openOnClick: false, openOnClick: false,
autolink: true, autolink: true,
defaultProtocol: 'https',
}), }),
], ],
content: ` content: `

View File

@ -62,6 +62,16 @@ context('/src/Marks/Link/React/', () => {
.should('have.attr', 'href', 'https://tiptap4u.com') .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', () => { it('detects a pasted URL within a text', () => {
cy.get('.tiptap') cy.get('.tiptap')
.paste({ .paste({

View File

@ -73,6 +73,16 @@ context('/src/Marks/Link/Vue/', () => {
.should('have.attr', 'href', 'https://tiptap4u.com') .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', () => { it('detects a pasted URL with query params', () => {
cy.get('.tiptap') cy.get('.tiptap')
.type('{backspace}') .type('{backspace}')

View File

@ -38,6 +38,7 @@ export default {
Code, Code,
Link.configure({ Link.configure({
openOnClick: false, openOnClick: false,
defaultProtocol: 'https',
}), }),
], ],
content: ` 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 ### HTMLAttributes
Custom HTML attributes that should be added to the rendered HTML tag. 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 AutolinkOptions = {
type: MarkType type: MarkType
defaultProtocol: string
validate: (url: string) => boolean validate: (url: string) => boolean
} }
@ -115,7 +116,7 @@ export function autolink(options: AutolinkOptions): Plugin {
return false return false
} }
const linksBeforeSpace = tokenize(lastWordBeforeSpace).map(t => t.toObject()) const linksBeforeSpace = tokenize(lastWordBeforeSpace).map(t => t.toObject(options.defaultProtocol))
if (!isValidLinkStructure(linksBeforeSpace)) { if (!isValidLinkStructure(linksBeforeSpace)) {
return false return false

View File

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

View File

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