Skip to content

Commit

Permalink
feat(extension-link): add support for default protocol (#5022)
Browse files Browse the repository at this point in the history
  • Loading branch information
henryStelle authored Jun 7, 2024
1 parent a52118c commit ff6e00a
Show file tree
Hide file tree
Showing 8 changed files with 48 additions and 2 deletions.
1 change: 1 addition & 0 deletions demos/src/Marks/Link/React/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export default () => {
Link.configure({
openOnClick: false,
autolink: true,
defaultProtocol: 'https',
}),
],
content: `
Expand Down
10 changes: 10 additions & 0 deletions demos/src/Marks/Link/React/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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({
Expand Down
10 changes: 10 additions & 0 deletions demos/src/Marks/Link/Vue/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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}')
Expand Down
1 change: 1 addition & 0 deletions demos/src/Marks/Link/Vue/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export default {
Code,
Link.configure({
openOnClick: false,
defaultProtocol: 'https',
}),
],
content: `
Expand Down
14 changes: 14 additions & 0 deletions docs/api/marks/link.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
3 changes: 2 additions & 1 deletion packages/extension-link/src/helpers/autolink.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ function isValidLinkStructure(tokens: Array<ReturnType<MultiToken['toObject']>>)

type AutolinkOptions = {
type: MarkType
defaultProtocol: string
validate: (url: string) => boolean
}

Expand Down Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion packages/extension-link/src/helpers/pasteHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { find } from 'linkifyjs'

type PasteHandlerOptions = {
editor: Editor
defaultProtocol: string
type: MarkType
}

Expand All @@ -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
Expand Down
8 changes: 8 additions & 0 deletions packages/extension-link/src/link.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -139,6 +144,7 @@ export const Link = Mark.create<LinkOptions>({
linkOnPaste: true,
autolink: true,
protocols: [],
defaultProtocol: 'http',
HTMLAttributes: {
target: '_blank',
rel: 'noopener noreferrer nofollow',
Expand Down Expand Up @@ -255,6 +261,7 @@ export const Link = Mark.create<LinkOptions>({
plugins.push(
autolink({
type: this.type,
defaultProtocol: this.options.defaultProtocol,
validate: this.options.validate,
}),
)
Expand All @@ -272,6 +279,7 @@ export const Link = Mark.create<LinkOptions>({
plugins.push(
pasteHandler({
editor: this.editor,
defaultProtocol: this.options.defaultProtocol,
type: this.type,
}),
)
Expand Down

0 comments on commit ff6e00a

Please sign in to comment.