Add option to set rel on youtube embed link (#6083)

* add option to set rel on youtube embed link

* rename parameter and add changeset

* change to patch

* fix lint and try to fix for tests

---------

Co-authored-by: bdbch <6538827+bdbch@users.noreply.github.com>
This commit is contained in:
teamclouday 2025-03-27 18:32:02 -04:00 committed by GitHub
parent c403b90887
commit 81009d2160
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 93 additions and 8 deletions

View File

@ -0,0 +1,5 @@
---
"@tiptap/extension-youtube": patch
---
This change adds option to set rel parameter on youtube embed link

View File

@ -13,7 +13,15 @@ context('/src/Nodes/Youtube/React/', () => {
cy.get('#add').eq(0).click()
cy.get('.tiptap div[data-youtube-video] iframe')
.should('have.length', 1)
.should('have.attr', 'src', 'https://www.youtube-nocookie.com/embed/hBp4dgE7Bho?controls=0')
.invoke('attr', 'src')
.then(src => {
const url = new URL(src)
expect(`${url.origin}${url.pathname}`).to.eq('https://www.youtube-nocookie.com/embed/hBp4dgE7Bho')
expect([...url.searchParams.keys()]).to.have.members(['controls', 'rel'])
expect(url.searchParams.get('controls')).to.eq('0')
expect(url.searchParams.get('rel')).to.eq('1')
})
})
})
@ -24,9 +32,17 @@ context('/src/Nodes/Youtube/React/', () => {
cy.get('#height').type('{selectall}{backspace}240')
cy.get('#add').eq(0).click()
cy.get('.tiptap div[data-youtube-video] iframe').should('have.length', 1)
.should('have.attr', 'src', 'https://www.youtube-nocookie.com/embed/hBp4dgE7Bho?controls=0')
.should('have.css', 'width', '320px')
.should('have.css', 'height', '240px')
.invoke('attr', 'src')
.then(src => {
const url = new URL(src)
expect(`${url.origin}${url.pathname}`).to.eq('https://www.youtube-nocookie.com/embed/hBp4dgE7Bho')
expect([...url.searchParams.keys()]).to.have.members(['controls', 'rel'])
expect(url.searchParams.get('controls')).to.eq('0')
expect(url.searchParams.get('rel')).to.eq('1')
})
})
})
@ -45,7 +61,15 @@ context('/src/Nodes/Youtube/React/', () => {
cy.get('#add').eq(0).click()
cy.get('.tiptap div[data-youtube-video] iframe')
.should('have.length', 1)
.should('have.attr', 'src', 'https://www.youtube-nocookie.com/embed/hBp4dgE7Bho?controls=0')
.invoke('attr', 'src')
.then(src => {
const url = new URL(src)
expect(`${url.origin}${url.pathname}`).to.eq('https://www.youtube-nocookie.com/embed/hBp4dgE7Bho')
expect([...url.searchParams.keys()]).to.have.members(['controls', 'rel'])
expect(url.searchParams.get('controls')).to.eq('0')
expect(url.searchParams.get('rel')).to.eq('1')
})
cy.get('.tiptap div[data-youtube-video] iframe')
.click()
@ -54,7 +78,15 @@ context('/src/Nodes/Youtube/React/', () => {
cy.get('.tiptap div[data-youtube-video] iframe')
.should('have.length', 1)
.should('have.attr', 'src', 'https://www.youtube-nocookie.com/embed/wRakoMYVHm8?controls=0')
.invoke('attr', 'src')
.then(src => {
const url = new URL(src)
expect(`${url.origin}${url.pathname}`).to.eq('https://www.youtube-nocookie.com/embed/wRakoMYVHm8')
expect([...url.searchParams.keys()]).to.have.members(['controls', 'rel'])
expect(url.searchParams.get('controls')).to.eq('0')
expect(url.searchParams.get('rel')).to.eq('1')
})
})
})
})

View File

@ -13,7 +13,15 @@ context('/src/Nodes/Youtube/Vue/', () => {
cy.get('#add').eq(0).click()
cy.get('.tiptap div[data-youtube-video] iframe')
.should('have.length', 1)
.should('have.attr', 'src', 'https://www.youtube-nocookie.com/embed/hBp4dgE7Bho?controls=0')
.invoke('attr', 'src')
.then(src => {
const url = new URL(src)
expect(`${url.origin}${url.pathname}`).to.eq('https://www.youtube-nocookie.com/embed/hBp4dgE7Bho')
expect([...url.searchParams.keys()]).to.have.members(['controls', 'rel'])
expect(url.searchParams.get('controls')).to.eq('0')
expect(url.searchParams.get('rel')).to.eq('1')
})
})
})
@ -24,9 +32,17 @@ context('/src/Nodes/Youtube/Vue/', () => {
cy.get('#height').type('{selectall}{backspace}240')
cy.get('#add').eq(0).click()
cy.get('.tiptap div[data-youtube-video] iframe').should('have.length', 1)
.should('have.attr', 'src', 'https://www.youtube-nocookie.com/embed/hBp4dgE7Bho?controls=0')
.should('have.css', 'width', '320px')
.should('have.css', 'height', '240px')
.invoke('attr', 'src')
.then(src => {
const url = new URL(src)
expect(`${url.origin}${url.pathname}`).to.eq('https://www.youtube-nocookie.com/embed/hBp4dgE7Bho')
expect([...url.searchParams.keys()]).to.have.members(['controls', 'rel'])
expect(url.searchParams.get('controls')).to.eq('0')
expect(url.searchParams.get('rel')).to.eq('1')
})
})
})
@ -45,7 +61,15 @@ context('/src/Nodes/Youtube/Vue/', () => {
cy.get('#add').eq(0).click()
cy.get('.tiptap div[data-youtube-video] iframe')
.should('have.length', 1)
.should('have.attr', 'src', 'https://www.youtube-nocookie.com/embed/hBp4dgE7Bho?controls=0')
.invoke('attr', 'src')
.then(src => {
const url = new URL(src)
expect(`${url.origin}${url.pathname}`).to.eq('https://www.youtube-nocookie.com/embed/hBp4dgE7Bho')
expect([...url.searchParams.keys()]).to.have.members(['controls', 'rel'])
expect(url.searchParams.get('controls')).to.eq('0')
expect(url.searchParams.get('rel')).to.eq('1')
})
cy.get('.tiptap div[data-youtube-video] iframe')
.click()
@ -54,7 +78,15 @@ context('/src/Nodes/Youtube/Vue/', () => {
cy.get('.tiptap div[data-youtube-video] iframe')
.should('have.length', 1)
.should('have.attr', 'src', 'https://www.youtube-nocookie.com/embed/wRakoMYVHm8?controls=0')
.invoke('attr', 'src')
.then(src => {
const url = new URL(src)
expect(`${url.origin}${url.pathname}`).to.eq('https://www.youtube-nocookie.com/embed/wRakoMYVHm8')
expect([...url.searchParams.keys()]).to.have.members(['controls', 'rel'])
expect(url.searchParams.get('controls')).to.eq('0')
expect(url.searchParams.get('rel')).to.eq('1')
})
})
})
})

View File

@ -24,6 +24,7 @@ export interface GetEmbedUrlOptions {
playlist?: string;
progressBarColor?: string;
startAt?: number;
rel?: number;
}
export const getYoutubeEmbedUrl = (nocookie?: boolean) => {
@ -50,6 +51,7 @@ export const getEmbedUrlFromYoutubeUrl = (options: GetEmbedUrlOptions) => {
playlist,
progressBarColor,
startAt,
rel,
} = options
if (!isValidYoutubeUrl(url)) {
@ -146,6 +148,10 @@ export const getEmbedUrlFromYoutubeUrl = (options: GetEmbedUrlOptions) => {
params.push(`color=${progressBarColor}`)
}
if (rel !== undefined) {
params.push(`rel=${rel}`)
}
if (params.length) {
outputUrl += `?${params.join('&')}`
}

View File

@ -149,6 +149,13 @@ export interface YoutubeOptions {
* @example 1280
*/
width: number;
/**
* Controls if the related youtube videos at the end are from the same channel.
* @default 1
* @example 0
*/
rel: number;
}
/**
@ -199,6 +206,7 @@ export const Youtube = Node.create<YoutubeOptions>({
playlist: '',
progressBarColor: undefined,
width: 640,
rel: 1,
}
},
@ -288,6 +296,7 @@ export const Youtube = Node.create<YoutubeOptions>({
playlist: this.options.playlist,
progressBarColor: this.options.progressBarColor,
startAt: HTMLAttributes.start || 0,
rel: this.options.rel,
})
HTMLAttributes.src = embedUrl
@ -316,6 +325,7 @@ export const Youtube = Node.create<YoutubeOptions>({
origin: this.options.origin,
playlist: this.options.playlist,
progressBarColor: this.options.progressBarColor,
rel: this.options.rel,
},
HTMLAttributes,
),