@tiptap/extension-youtube 3.0.0-next.2 → 3.0.0-next.4

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/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024, Tiptap GmbH
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,14 +1,18 @@
1
1
  # @tiptap/extension-youtube
2
+
2
3
  [![Version](https://img.shields.io/npm/v/@tiptap/extension-youtube.svg?label=version)](https://www.npmjs.com/package/@tiptap/extension-youtube)
3
4
  [![Downloads](https://img.shields.io/npm/dm/@tiptap/extension-youtube.svg)](https://npmcharts.com/compare/tiptap?minimal=true)
4
5
  [![License](https://img.shields.io/npm/l/@tiptap/extension-youtube.svg)](https://www.npmjs.com/package/@tiptap/extension-youtube)
5
6
  [![Sponsor](https://img.shields.io/static/v1?label=Sponsor&message=%E2%9D%A4&logo=GitHub)](https://github.com/sponsors/ueberdosis)
6
7
 
7
8
  ## Introduction
8
- Tiptap is a headless wrapper around [ProseMirror](https://ProseMirror.net) – a toolkit for building rich text WYSIWYG editors, which is already in use at many well-known companies such as *New York Times*, *The Guardian* or *Atlassian*.
9
+
10
+ Tiptap is a headless wrapper around [ProseMirror](https://ProseMirror.net) – a toolkit for building rich text WYSIWYG editors, which is already in use at many well-known companies such as _New York Times_, _The Guardian_ or _Atlassian_.
9
11
 
10
12
  ## Official Documentation
13
+
11
14
  Documentation can be found on the [Tiptap website](https://tiptap.dev).
12
15
 
13
16
  ## License
17
+
14
18
  Tiptap is open sourced software licensed under the [MIT license](https://github.com/ueberdosis/tiptap/blob/main/LICENSE.md).
package/dist/index.cjs CHANGED
@@ -18,19 +18,19 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
 
20
20
  // src/index.ts
21
- var src_exports = {};
22
- __export(src_exports, {
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
23
  Youtube: () => Youtube,
24
- default: () => src_default
24
+ default: () => index_default
25
25
  });
26
- module.exports = __toCommonJS(src_exports);
26
+ module.exports = __toCommonJS(index_exports);
27
27
 
28
28
  // src/youtube.ts
29
29
  var import_core = require("@tiptap/core");
30
30
 
31
31
  // src/utils.ts
32
- var YOUTUBE_REGEX = /^(https?:\/\/)?(www\.|music\.)?(youtube\.com|youtu\.be|youtube-nocookie\.com)\/(?!channel\/)(?!@)(.+)?$/;
33
- var YOUTUBE_REGEX_GLOBAL = /^(https?:\/\/)?(www\.|music\.)?(youtube\.com|youtu\.be)\/(?!channel\/)(?!@)(.+)?$/g;
32
+ var YOUTUBE_REGEX = /^((?:https?:)?\/\/)?((?:www|m|music)\.)?((?:youtube\.com|youtu.be|youtube-nocookie\.com))(\/(?:[\w-]+\?v=|embed\/|v\/)?)([\w-]+)(\S+)?$/;
33
+ var YOUTUBE_REGEX_GLOBAL = /^((?:https?:)?\/\/)?((?:www|m|music)\.)?((?:youtube\.com|youtu.be|youtube-nocookie\.com))(\/(?:[\w-]+\?v=|embed\/|v\/)?)([\w-]+)(\S+)?$/g;
34
34
  var isValidYoutubeUrl = (url) => {
35
35
  return url.match(YOUTUBE_REGEX);
36
36
  };
@@ -272,7 +272,7 @@ var Youtube = import_core.Node.create({
272
272
  });
273
273
 
274
274
  // src/index.ts
275
- var src_default = Youtube;
275
+ var index_default = Youtube;
276
276
  // Annotate the CommonJS export names for ESM import in node:
277
277
  0 && (module.exports = {
278
278
  Youtube
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/youtube.ts","../src/utils.ts"],"sourcesContent":["import { Youtube } from './youtube.js'\n\nexport * from './youtube.js'\n\nexport default Youtube\n","import { mergeAttributes, Node, nodePasteRule } from '@tiptap/core'\n\nimport { getEmbedUrlFromYoutubeUrl, isValidYoutubeUrl, YOUTUBE_REGEX_GLOBAL } from './utils.js'\n\nexport interface YoutubeOptions {\n /**\n * Controls if the paste handler for youtube videos should be added.\n * @default true\n * @example false\n */\n addPasteHandler: boolean;\n\n /**\n * Controls if the youtube video should be allowed to go fullscreen.\n * @default true\n * @example false\n */\n allowFullscreen: boolean;\n\n /**\n * Controls if the youtube video should autoplay.\n * @default false\n * @example true\n */\n autoplay: boolean;\n\n /**\n * The language of the captions shown in the youtube video.\n * @default undefined\n * @example 'en'\n */\n ccLanguage?: string;\n\n /**\n * Controls if the captions should be shown in the youtube video.\n * @default undefined\n * @example true\n */\n ccLoadPolicy?: boolean;\n\n /**\n * Controls if the controls should be shown in the youtube video.\n * @default true\n * @example false\n */\n controls: boolean;\n\n /**\n * Controls if the keyboard controls should be disabled in the youtube video.\n * @default false\n * @example true\n */\n disableKBcontrols: boolean;\n\n /**\n * Controls if the iframe api should be enabled in the youtube video.\n * @default false\n * @example true\n */\n enableIFrameApi: boolean;\n\n /**\n * The end time of the youtube video.\n * @default 0\n * @example 120\n */\n endTime: number;\n\n /**\n * The height of the youtube video.\n * @default 480\n * @example 720\n */\n height: number;\n\n /**\n * The language of the youtube video.\n * @default undefined\n * @example 'en'\n */\n interfaceLanguage?: string;\n\n /**\n * Controls if the video annotations should be shown in the youtube video.\n * @default 0\n * @example 1\n */\n ivLoadPolicy: number;\n\n /**\n * Controls if the youtube video should loop.\n * @default false\n * @example true\n */\n loop: boolean;\n\n /**\n * Controls if the youtube video should show a small youtube logo.\n * @default false\n * @example true\n */\n modestBranding: boolean;\n\n /**\n * The HTML attributes for a youtube video node.\n * @default {}\n * @example { class: 'foo' }\n */\n HTMLAttributes: Record<string, any>;\n\n /**\n * Controls if the youtube node should be inline or not.\n * @default false\n * @example true\n */\n inline: boolean;\n\n /**\n * Controls if the youtube video should be loaded from youtube-nocookie.com.\n * @default false\n * @example true\n */\n nocookie: boolean;\n\n /**\n * The origin of the youtube video.\n * @default ''\n * @example 'https://tiptap.dev'\n */\n origin: string;\n\n /**\n * The playlist of the youtube video.\n * @default ''\n * @example 'PLQg6GaokU5CwiVmsZ0dZm6VeIg0V5z1tK'\n */\n playlist: string;\n\n /**\n * The color of the youtube video progress bar.\n * @default undefined\n * @example 'red'\n */\n progressBarColor?: string;\n\n /**\n * The width of the youtube video.\n * @default 640\n * @example 1280\n */\n width: number;\n}\n\n/**\n * The options for setting a youtube video.\n */\ntype SetYoutubeVideoOptions = { src: string, width?: number, height?: number, start?: number }\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n youtube: {\n /**\n * Insert a youtube video\n * @param options The youtube video attributes\n * @example editor.commands.setYoutubeVideo({ src: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ' })\n */\n setYoutubeVideo: (options: SetYoutubeVideoOptions) => ReturnType,\n }\n }\n}\n\n/**\n * This extension adds support for youtube videos.\n * @see https://www.tiptap.dev/api/nodes/youtube\n */\nexport const Youtube = Node.create<YoutubeOptions>({\n name: 'youtube',\n\n addOptions() {\n return {\n addPasteHandler: true,\n allowFullscreen: true,\n autoplay: false,\n ccLanguage: undefined,\n ccLoadPolicy: undefined,\n controls: true,\n disableKBcontrols: false,\n enableIFrameApi: false,\n endTime: 0,\n height: 480,\n interfaceLanguage: undefined,\n ivLoadPolicy: 0,\n loop: false,\n modestBranding: false,\n HTMLAttributes: {},\n inline: false,\n nocookie: false,\n origin: '',\n playlist: '',\n progressBarColor: undefined,\n width: 640,\n }\n },\n\n inline() {\n return this.options.inline\n },\n\n group() {\n return this.options.inline ? 'inline' : 'block'\n },\n\n draggable: true,\n\n addAttributes() {\n return {\n src: {\n default: null,\n },\n start: {\n default: 0,\n },\n width: {\n default: this.options.width,\n },\n height: {\n default: this.options.height,\n },\n }\n },\n\n parseHTML() {\n return [\n {\n tag: 'div[data-youtube-video] iframe',\n },\n ]\n },\n\n addCommands() {\n return {\n setYoutubeVideo: (options: SetYoutubeVideoOptions) => ({ commands }) => {\n if (!isValidYoutubeUrl(options.src)) {\n return false\n }\n\n return commands.insertContent({\n type: this.name,\n attrs: options,\n })\n },\n }\n },\n\n addPasteRules() {\n if (!this.options.addPasteHandler) {\n return []\n }\n\n return [\n nodePasteRule({\n find: YOUTUBE_REGEX_GLOBAL,\n type: this.type,\n getAttributes: match => {\n return { src: match.input }\n },\n }),\n ]\n },\n\n renderHTML({ HTMLAttributes }) {\n const embedUrl = getEmbedUrlFromYoutubeUrl({\n url: HTMLAttributes.src,\n allowFullscreen: this.options.allowFullscreen,\n autoplay: this.options.autoplay,\n ccLanguage: this.options.ccLanguage,\n ccLoadPolicy: this.options.ccLoadPolicy,\n controls: this.options.controls,\n disableKBcontrols: this.options.disableKBcontrols,\n enableIFrameApi: this.options.enableIFrameApi,\n endTime: this.options.endTime,\n interfaceLanguage: this.options.interfaceLanguage,\n ivLoadPolicy: this.options.ivLoadPolicy,\n loop: this.options.loop,\n modestBranding: this.options.modestBranding,\n nocookie: this.options.nocookie,\n origin: this.options.origin,\n playlist: this.options.playlist,\n progressBarColor: this.options.progressBarColor,\n startAt: HTMLAttributes.start || 0,\n })\n\n HTMLAttributes.src = embedUrl\n\n return [\n 'div',\n { 'data-youtube-video': '' },\n [\n 'iframe',\n mergeAttributes(\n this.options.HTMLAttributes,\n {\n width: this.options.width,\n height: this.options.height,\n allowfullscreen: this.options.allowFullscreen,\n autoplay: this.options.autoplay,\n ccLanguage: this.options.ccLanguage,\n ccLoadPolicy: this.options.ccLoadPolicy,\n disableKBcontrols: this.options.disableKBcontrols,\n enableIFrameApi: this.options.enableIFrameApi,\n endTime: this.options.endTime,\n interfaceLanguage: this.options.interfaceLanguage,\n ivLoadPolicy: this.options.ivLoadPolicy,\n loop: this.options.loop,\n modestBranding: this.options.modestBranding,\n origin: this.options.origin,\n playlist: this.options.playlist,\n progressBarColor: this.options.progressBarColor,\n },\n HTMLAttributes,\n ),\n ],\n ]\n },\n})\n","export const YOUTUBE_REGEX = /^(https?:\\/\\/)?(www\\.|music\\.)?(youtube\\.com|youtu\\.be|youtube-nocookie\\.com)\\/(?!channel\\/)(?!@)(.+)?$/\nexport const YOUTUBE_REGEX_GLOBAL = /^(https?:\\/\\/)?(www\\.|music\\.)?(youtube\\.com|youtu\\.be)\\/(?!channel\\/)(?!@)(.+)?$/g\n\nexport const isValidYoutubeUrl = (url: string) => {\n return url.match(YOUTUBE_REGEX)\n}\n\nexport interface GetEmbedUrlOptions {\n url: string;\n allowFullscreen?: boolean;\n autoplay?: boolean;\n ccLanguage?:string;\n ccLoadPolicy?:boolean;\n controls?: boolean;\n disableKBcontrols?: boolean,\n enableIFrameApi?: boolean;\n endTime?: number;\n interfaceLanguage?: string;\n ivLoadPolicy?: number;\n loop?: boolean;\n modestBranding?: boolean;\n nocookie?: boolean;\n origin?: string;\n playlist?: string;\n progressBarColor?: string;\n startAt?: number;\n}\n\nexport const getYoutubeEmbedUrl = (nocookie?: boolean) => {\n return nocookie ? 'https://www.youtube-nocookie.com/embed/' : 'https://www.youtube.com/embed/'\n}\n\nexport const getEmbedUrlFromYoutubeUrl = (options: GetEmbedUrlOptions) => {\n const {\n url,\n allowFullscreen,\n autoplay,\n ccLanguage,\n ccLoadPolicy,\n controls,\n disableKBcontrols,\n enableIFrameApi,\n endTime,\n interfaceLanguage,\n ivLoadPolicy,\n loop,\n modestBranding,\n nocookie,\n origin,\n playlist,\n progressBarColor,\n startAt,\n } = options\n\n if (!isValidYoutubeUrl(url)) {\n return null\n }\n\n // if is already an embed url, return it\n if (url.includes('/embed/')) {\n return url\n }\n\n // if is a youtu.be url, get the id after the /\n if (url.includes('youtu.be')) {\n const id = url.split('/').pop()\n\n if (!id) {\n return null\n }\n return `${getYoutubeEmbedUrl(nocookie)}${id}`\n }\n\n const videoIdRegex = /(?:v=|shorts\\/)([-\\w]+)/gm\n const matches = videoIdRegex.exec(url)\n\n if (!matches || !matches[1]) {\n return null\n }\n\n let outputUrl = `${getYoutubeEmbedUrl(nocookie)}${matches[1]}`\n\n const params = []\n\n if (allowFullscreen === false) {\n params.push('fs=0')\n }\n\n if (autoplay) {\n params.push('autoplay=1')\n }\n\n if (ccLanguage) {\n params.push(`cc_lang_pref=${ccLanguage}`)\n }\n\n if (ccLoadPolicy) {\n params.push('cc_load_policy=1')\n }\n\n if (!controls) {\n params.push('controls=0')\n }\n\n if (disableKBcontrols) {\n params.push('disablekb=1')\n }\n\n if (enableIFrameApi) {\n params.push('enablejsapi=1')\n }\n\n if (endTime) {\n params.push(`end=${endTime}`)\n }\n\n if (interfaceLanguage) {\n params.push(`hl=${interfaceLanguage}`)\n }\n\n if (ivLoadPolicy) {\n params.push(`iv_load_policy=${ivLoadPolicy}`)\n }\n\n if (loop) {\n params.push('loop=1')\n }\n\n if (modestBranding) {\n params.push('modestbranding=1')\n }\n\n if (origin) {\n params.push(`origin=${origin}`)\n }\n\n if (playlist) {\n params.push(`playlist=${playlist}`)\n }\n\n if (startAt) {\n params.push(`start=${startAt}`)\n }\n\n if (progressBarColor) {\n params.push(`color=${progressBarColor}`)\n }\n\n if (params.length) {\n outputUrl += `?${params.join('&')}`\n }\n\n return outputUrl\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/youtube.ts","../src/utils.ts"],"sourcesContent":["import { Youtube } from './youtube.js'\n\nexport * from './youtube.js'\n\nexport default Youtube\n","import { mergeAttributes, Node, nodePasteRule } from '@tiptap/core'\n\nimport { getEmbedUrlFromYoutubeUrl, isValidYoutubeUrl, YOUTUBE_REGEX_GLOBAL } from './utils.js'\n\nexport interface YoutubeOptions {\n /**\n * Controls if the paste handler for youtube videos should be added.\n * @default true\n * @example false\n */\n addPasteHandler: boolean\n\n /**\n * Controls if the youtube video should be allowed to go fullscreen.\n * @default true\n * @example false\n */\n allowFullscreen: boolean\n\n /**\n * Controls if the youtube video should autoplay.\n * @default false\n * @example true\n */\n autoplay: boolean\n\n /**\n * The language of the captions shown in the youtube video.\n * @default undefined\n * @example 'en'\n */\n ccLanguage?: string\n\n /**\n * Controls if the captions should be shown in the youtube video.\n * @default undefined\n * @example true\n */\n ccLoadPolicy?: boolean\n\n /**\n * Controls if the controls should be shown in the youtube video.\n * @default true\n * @example false\n */\n controls: boolean\n\n /**\n * Controls if the keyboard controls should be disabled in the youtube video.\n * @default false\n * @example true\n */\n disableKBcontrols: boolean\n\n /**\n * Controls if the iframe api should be enabled in the youtube video.\n * @default false\n * @example true\n */\n enableIFrameApi: boolean\n\n /**\n * The end time of the youtube video.\n * @default 0\n * @example 120\n */\n endTime: number\n\n /**\n * The height of the youtube video.\n * @default 480\n * @example 720\n */\n height: number\n\n /**\n * The language of the youtube video.\n * @default undefined\n * @example 'en'\n */\n interfaceLanguage?: string\n\n /**\n * Controls if the video annotations should be shown in the youtube video.\n * @default 0\n * @example 1\n */\n ivLoadPolicy: number\n\n /**\n * Controls if the youtube video should loop.\n * @default false\n * @example true\n */\n loop: boolean\n\n /**\n * Controls if the youtube video should show a small youtube logo.\n * @default false\n * @example true\n */\n modestBranding: boolean\n\n /**\n * The HTML attributes for a youtube video node.\n * @default {}\n * @example { class: 'foo' }\n */\n HTMLAttributes: Record<string, any>\n\n /**\n * Controls if the youtube node should be inline or not.\n * @default false\n * @example true\n */\n inline: boolean\n\n /**\n * Controls if the youtube video should be loaded from youtube-nocookie.com.\n * @default false\n * @example true\n */\n nocookie: boolean\n\n /**\n * The origin of the youtube video.\n * @default ''\n * @example 'https://tiptap.dev'\n */\n origin: string\n\n /**\n * The playlist of the youtube video.\n * @default ''\n * @example 'PLQg6GaokU5CwiVmsZ0dZm6VeIg0V5z1tK'\n */\n playlist: string\n\n /**\n * The color of the youtube video progress bar.\n * @default undefined\n * @example 'red'\n */\n progressBarColor?: string\n\n /**\n * The width of the youtube video.\n * @default 640\n * @example 1280\n */\n width: number\n}\n\n/**\n * The options for setting a youtube video.\n */\ntype SetYoutubeVideoOptions = { src: string; width?: number; height?: number; start?: number }\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n youtube: {\n /**\n * Insert a youtube video\n * @param options The youtube video attributes\n * @example editor.commands.setYoutubeVideo({ src: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ' })\n */\n setYoutubeVideo: (options: SetYoutubeVideoOptions) => ReturnType\n }\n }\n}\n\n/**\n * This extension adds support for youtube videos.\n * @see https://www.tiptap.dev/api/nodes/youtube\n */\nexport const Youtube = Node.create<YoutubeOptions>({\n name: 'youtube',\n\n addOptions() {\n return {\n addPasteHandler: true,\n allowFullscreen: true,\n autoplay: false,\n ccLanguage: undefined,\n ccLoadPolicy: undefined,\n controls: true,\n disableKBcontrols: false,\n enableIFrameApi: false,\n endTime: 0,\n height: 480,\n interfaceLanguage: undefined,\n ivLoadPolicy: 0,\n loop: false,\n modestBranding: false,\n HTMLAttributes: {},\n inline: false,\n nocookie: false,\n origin: '',\n playlist: '',\n progressBarColor: undefined,\n width: 640,\n }\n },\n\n inline() {\n return this.options.inline\n },\n\n group() {\n return this.options.inline ? 'inline' : 'block'\n },\n\n draggable: true,\n\n addAttributes() {\n return {\n src: {\n default: null,\n },\n start: {\n default: 0,\n },\n width: {\n default: this.options.width,\n },\n height: {\n default: this.options.height,\n },\n }\n },\n\n parseHTML() {\n return [\n {\n tag: 'div[data-youtube-video] iframe',\n },\n ]\n },\n\n addCommands() {\n return {\n setYoutubeVideo:\n (options: SetYoutubeVideoOptions) =>\n ({ commands }) => {\n if (!isValidYoutubeUrl(options.src)) {\n return false\n }\n\n return commands.insertContent({\n type: this.name,\n attrs: options,\n })\n },\n }\n },\n\n addPasteRules() {\n if (!this.options.addPasteHandler) {\n return []\n }\n\n return [\n nodePasteRule({\n find: YOUTUBE_REGEX_GLOBAL,\n type: this.type,\n getAttributes: match => {\n return { src: match.input }\n },\n }),\n ]\n },\n\n renderHTML({ HTMLAttributes }) {\n const embedUrl = getEmbedUrlFromYoutubeUrl({\n url: HTMLAttributes.src,\n allowFullscreen: this.options.allowFullscreen,\n autoplay: this.options.autoplay,\n ccLanguage: this.options.ccLanguage,\n ccLoadPolicy: this.options.ccLoadPolicy,\n controls: this.options.controls,\n disableKBcontrols: this.options.disableKBcontrols,\n enableIFrameApi: this.options.enableIFrameApi,\n endTime: this.options.endTime,\n interfaceLanguage: this.options.interfaceLanguage,\n ivLoadPolicy: this.options.ivLoadPolicy,\n loop: this.options.loop,\n modestBranding: this.options.modestBranding,\n nocookie: this.options.nocookie,\n origin: this.options.origin,\n playlist: this.options.playlist,\n progressBarColor: this.options.progressBarColor,\n startAt: HTMLAttributes.start || 0,\n })\n\n HTMLAttributes.src = embedUrl\n\n return [\n 'div',\n { 'data-youtube-video': '' },\n [\n 'iframe',\n mergeAttributes(\n this.options.HTMLAttributes,\n {\n width: this.options.width,\n height: this.options.height,\n allowfullscreen: this.options.allowFullscreen,\n autoplay: this.options.autoplay,\n ccLanguage: this.options.ccLanguage,\n ccLoadPolicy: this.options.ccLoadPolicy,\n disableKBcontrols: this.options.disableKBcontrols,\n enableIFrameApi: this.options.enableIFrameApi,\n endTime: this.options.endTime,\n interfaceLanguage: this.options.interfaceLanguage,\n ivLoadPolicy: this.options.ivLoadPolicy,\n loop: this.options.loop,\n modestBranding: this.options.modestBranding,\n origin: this.options.origin,\n playlist: this.options.playlist,\n progressBarColor: this.options.progressBarColor,\n },\n HTMLAttributes,\n ),\n ],\n ]\n },\n})\n","export const YOUTUBE_REGEX =\n /^((?:https?:)?\\/\\/)?((?:www|m|music)\\.)?((?:youtube\\.com|youtu.be|youtube-nocookie\\.com))(\\/(?:[\\w-]+\\?v=|embed\\/|v\\/)?)([\\w-]+)(\\S+)?$/\nexport const YOUTUBE_REGEX_GLOBAL =\n /^((?:https?:)?\\/\\/)?((?:www|m|music)\\.)?((?:youtube\\.com|youtu.be|youtube-nocookie\\.com))(\\/(?:[\\w-]+\\?v=|embed\\/|v\\/)?)([\\w-]+)(\\S+)?$/g\n\nexport const isValidYoutubeUrl = (url: string) => {\n return url.match(YOUTUBE_REGEX)\n}\n\nexport interface GetEmbedUrlOptions {\n url: string\n allowFullscreen?: boolean\n autoplay?: boolean\n ccLanguage?: string\n ccLoadPolicy?: boolean\n controls?: boolean\n disableKBcontrols?: boolean\n enableIFrameApi?: boolean\n endTime?: number\n interfaceLanguage?: string\n ivLoadPolicy?: number\n loop?: boolean\n modestBranding?: boolean\n nocookie?: boolean\n origin?: string\n playlist?: string\n progressBarColor?: string\n startAt?: number\n}\n\nexport const getYoutubeEmbedUrl = (nocookie?: boolean) => {\n return nocookie ? 'https://www.youtube-nocookie.com/embed/' : 'https://www.youtube.com/embed/'\n}\n\nexport const getEmbedUrlFromYoutubeUrl = (options: GetEmbedUrlOptions) => {\n const {\n url,\n allowFullscreen,\n autoplay,\n ccLanguage,\n ccLoadPolicy,\n controls,\n disableKBcontrols,\n enableIFrameApi,\n endTime,\n interfaceLanguage,\n ivLoadPolicy,\n loop,\n modestBranding,\n nocookie,\n origin,\n playlist,\n progressBarColor,\n startAt,\n } = options\n\n if (!isValidYoutubeUrl(url)) {\n return null\n }\n\n // if is already an embed url, return it\n if (url.includes('/embed/')) {\n return url\n }\n\n // if is a youtu.be url, get the id after the /\n if (url.includes('youtu.be')) {\n const id = url.split('/').pop()\n\n if (!id) {\n return null\n }\n return `${getYoutubeEmbedUrl(nocookie)}${id}`\n }\n\n const videoIdRegex = /(?:v=|shorts\\/)([-\\w]+)/gm\n const matches = videoIdRegex.exec(url)\n\n if (!matches || !matches[1]) {\n return null\n }\n\n let outputUrl = `${getYoutubeEmbedUrl(nocookie)}${matches[1]}`\n\n const params = []\n\n if (allowFullscreen === false) {\n params.push('fs=0')\n }\n\n if (autoplay) {\n params.push('autoplay=1')\n }\n\n if (ccLanguage) {\n params.push(`cc_lang_pref=${ccLanguage}`)\n }\n\n if (ccLoadPolicy) {\n params.push('cc_load_policy=1')\n }\n\n if (!controls) {\n params.push('controls=0')\n }\n\n if (disableKBcontrols) {\n params.push('disablekb=1')\n }\n\n if (enableIFrameApi) {\n params.push('enablejsapi=1')\n }\n\n if (endTime) {\n params.push(`end=${endTime}`)\n }\n\n if (interfaceLanguage) {\n params.push(`hl=${interfaceLanguage}`)\n }\n\n if (ivLoadPolicy) {\n params.push(`iv_load_policy=${ivLoadPolicy}`)\n }\n\n if (loop) {\n params.push('loop=1')\n }\n\n if (modestBranding) {\n params.push('modestbranding=1')\n }\n\n if (origin) {\n params.push(`origin=${origin}`)\n }\n\n if (playlist) {\n params.push(`playlist=${playlist}`)\n }\n\n if (startAt) {\n params.push(`start=${startAt}`)\n }\n\n if (progressBarColor) {\n params.push(`color=${progressBarColor}`)\n }\n\n if (params.length) {\n outputUrl += `?${params.join('&')}`\n }\n\n return outputUrl\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,kBAAqD;;;ACA9C,IAAM,gBACX;AACK,IAAM,uBACX;AAEK,IAAM,oBAAoB,CAAC,QAAgB;AAChD,SAAO,IAAI,MAAM,aAAa;AAChC;AAuBO,IAAM,qBAAqB,CAAC,aAAuB;AACxD,SAAO,WAAW,4CAA4C;AAChE;AAEO,IAAM,4BAA4B,CAAC,YAAgC;AACxE,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AAEJ,MAAI,CAAC,kBAAkB,GAAG,GAAG;AAC3B,WAAO;AAAA,EACT;AAGA,MAAI,IAAI,SAAS,SAAS,GAAG;AAC3B,WAAO;AAAA,EACT;AAGA,MAAI,IAAI,SAAS,UAAU,GAAG;AAC5B,UAAM,KAAK,IAAI,MAAM,GAAG,EAAE,IAAI;AAE9B,QAAI,CAAC,IAAI;AACP,aAAO;AAAA,IACT;AACA,WAAO,GAAG,mBAAmB,QAAQ,CAAC,GAAG,EAAE;AAAA,EAC7C;AAEA,QAAM,eAAe;AACrB,QAAM,UAAU,aAAa,KAAK,GAAG;AAErC,MAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,GAAG;AAC3B,WAAO;AAAA,EACT;AAEA,MAAI,YAAY,GAAG,mBAAmB,QAAQ,CAAC,GAAG,QAAQ,CAAC,CAAC;AAE5D,QAAM,SAAS,CAAC;AAEhB,MAAI,oBAAoB,OAAO;AAC7B,WAAO,KAAK,MAAM;AAAA,EACpB;AAEA,MAAI,UAAU;AACZ,WAAO,KAAK,YAAY;AAAA,EAC1B;AAEA,MAAI,YAAY;AACd,WAAO,KAAK,gBAAgB,UAAU,EAAE;AAAA,EAC1C;AAEA,MAAI,cAAc;AAChB,WAAO,KAAK,kBAAkB;AAAA,EAChC;AAEA,MAAI,CAAC,UAAU;AACb,WAAO,KAAK,YAAY;AAAA,EAC1B;AAEA,MAAI,mBAAmB;AACrB,WAAO,KAAK,aAAa;AAAA,EAC3B;AAEA,MAAI,iBAAiB;AACnB,WAAO,KAAK,eAAe;AAAA,EAC7B;AAEA,MAAI,SAAS;AACX,WAAO,KAAK,OAAO,OAAO,EAAE;AAAA,EAC9B;AAEA,MAAI,mBAAmB;AACrB,WAAO,KAAK,MAAM,iBAAiB,EAAE;AAAA,EACvC;AAEA,MAAI,cAAc;AAChB,WAAO,KAAK,kBAAkB,YAAY,EAAE;AAAA,EAC9C;AAEA,MAAI,MAAM;AACR,WAAO,KAAK,QAAQ;AAAA,EACtB;AAEA,MAAI,gBAAgB;AAClB,WAAO,KAAK,kBAAkB;AAAA,EAChC;AAEA,MAAI,QAAQ;AACV,WAAO,KAAK,UAAU,MAAM,EAAE;AAAA,EAChC;AAEA,MAAI,UAAU;AACZ,WAAO,KAAK,YAAY,QAAQ,EAAE;AAAA,EACpC;AAEA,MAAI,SAAS;AACX,WAAO,KAAK,SAAS,OAAO,EAAE;AAAA,EAChC;AAEA,MAAI,kBAAkB;AACpB,WAAO,KAAK,SAAS,gBAAgB,EAAE;AAAA,EACzC;AAEA,MAAI,OAAO,QAAQ;AACjB,iBAAa,IAAI,OAAO,KAAK,GAAG,CAAC;AAAA,EACnC;AAEA,SAAO;AACT;;;ADoBO,IAAM,UAAU,iBAAK,OAAuB;AAAA,EACjD,MAAM;AAAA,EAEN,aAAa;AACX,WAAO;AAAA,MACL,iBAAiB;AAAA,MACjB,iBAAiB;AAAA,MACjB,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,cAAc;AAAA,MACd,UAAU;AAAA,MACV,mBAAmB;AAAA,MACnB,iBAAiB;AAAA,MACjB,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,mBAAmB;AAAA,MACnB,cAAc;AAAA,MACd,MAAM;AAAA,MACN,gBAAgB;AAAA,MAChB,gBAAgB,CAAC;AAAA,MACjB,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,kBAAkB;AAAA,MAClB,OAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,SAAS;AACP,WAAO,KAAK,QAAQ;AAAA,EACtB;AAAA,EAEA,QAAQ;AACN,WAAO,KAAK,QAAQ,SAAS,WAAW;AAAA,EAC1C;AAAA,EAEA,WAAW;AAAA,EAEX,gBAAgB;AACd,WAAO;AAAA,MACL,KAAK;AAAA,QACH,SAAS;AAAA,MACX;AAAA,MACA,OAAO;AAAA,QACL,SAAS;AAAA,MACX;AAAA,MACA,OAAO;AAAA,QACL,SAAS,KAAK,QAAQ;AAAA,MACxB;AAAA,MACA,QAAQ;AAAA,QACN,SAAS,KAAK,QAAQ;AAAA,MACxB;AAAA,IACF;AAAA,EACF;AAAA,EAEA,YAAY;AACV,WAAO;AAAA,MACL;AAAA,QACE,KAAK;AAAA,MACP;AAAA,IACF;AAAA,EACF;AAAA,EAEA,cAAc;AACZ,WAAO;AAAA,MACL,iBACE,CAAC,YACD,CAAC,EAAE,SAAS,MAAM;AAChB,YAAI,CAAC,kBAAkB,QAAQ,GAAG,GAAG;AACnC,iBAAO;AAAA,QACT;AAEA,eAAO,SAAS,cAAc;AAAA,UAC5B,MAAM,KAAK;AAAA,UACX,OAAO;AAAA,QACT,CAAC;AAAA,MACH;AAAA,IACJ;AAAA,EACF;AAAA,EAEA,gBAAgB;AACd,QAAI,CAAC,KAAK,QAAQ,iBAAiB;AACjC,aAAO,CAAC;AAAA,IACV;AAEA,WAAO;AAAA,UACL,2BAAc;AAAA,QACZ,MAAM;AAAA,QACN,MAAM,KAAK;AAAA,QACX,eAAe,WAAS;AACtB,iBAAO,EAAE,KAAK,MAAM,MAAM;AAAA,QAC5B;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,WAAW,EAAE,eAAe,GAAG;AAC7B,UAAM,WAAW,0BAA0B;AAAA,MACzC,KAAK,eAAe;AAAA,MACpB,iBAAiB,KAAK,QAAQ;AAAA,MAC9B,UAAU,KAAK,QAAQ;AAAA,MACvB,YAAY,KAAK,QAAQ;AAAA,MACzB,cAAc,KAAK,QAAQ;AAAA,MAC3B,UAAU,KAAK,QAAQ;AAAA,MACvB,mBAAmB,KAAK,QAAQ;AAAA,MAChC,iBAAiB,KAAK,QAAQ;AAAA,MAC9B,SAAS,KAAK,QAAQ;AAAA,MACtB,mBAAmB,KAAK,QAAQ;AAAA,MAChC,cAAc,KAAK,QAAQ;AAAA,MAC3B,MAAM,KAAK,QAAQ;AAAA,MACnB,gBAAgB,KAAK,QAAQ;AAAA,MAC7B,UAAU,KAAK,QAAQ;AAAA,MACvB,QAAQ,KAAK,QAAQ;AAAA,MACrB,UAAU,KAAK,QAAQ;AAAA,MACvB,kBAAkB,KAAK,QAAQ;AAAA,MAC/B,SAAS,eAAe,SAAS;AAAA,IACnC,CAAC;AAED,mBAAe,MAAM;AAErB,WAAO;AAAA,MACL;AAAA,MACA,EAAE,sBAAsB,GAAG;AAAA,MAC3B;AAAA,QACE;AAAA,YACA;AAAA,UACE,KAAK,QAAQ;AAAA,UACb;AAAA,YACE,OAAO,KAAK,QAAQ;AAAA,YACpB,QAAQ,KAAK,QAAQ;AAAA,YACrB,iBAAiB,KAAK,QAAQ;AAAA,YAC9B,UAAU,KAAK,QAAQ;AAAA,YACvB,YAAY,KAAK,QAAQ;AAAA,YACzB,cAAc,KAAK,QAAQ;AAAA,YAC3B,mBAAmB,KAAK,QAAQ;AAAA,YAChC,iBAAiB,KAAK,QAAQ;AAAA,YAC9B,SAAS,KAAK,QAAQ;AAAA,YACtB,mBAAmB,KAAK,QAAQ;AAAA,YAChC,cAAc,KAAK,QAAQ;AAAA,YAC3B,MAAM,KAAK,QAAQ;AAAA,YACnB,gBAAgB,KAAK,QAAQ;AAAA,YAC7B,QAAQ,KAAK,QAAQ;AAAA,YACrB,UAAU,KAAK,QAAQ;AAAA,YACvB,kBAAkB,KAAK,QAAQ;AAAA,UACjC;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF,CAAC;;;ADlUD,IAAO,gBAAQ;","names":[]}
package/dist/index.js CHANGED
@@ -2,8 +2,8 @@
2
2
  import { mergeAttributes, Node, nodePasteRule } from "@tiptap/core";
3
3
 
4
4
  // src/utils.ts
5
- var YOUTUBE_REGEX = /^(https?:\/\/)?(www\.|music\.)?(youtube\.com|youtu\.be|youtube-nocookie\.com)\/(?!channel\/)(?!@)(.+)?$/;
6
- var YOUTUBE_REGEX_GLOBAL = /^(https?:\/\/)?(www\.|music\.)?(youtube\.com|youtu\.be)\/(?!channel\/)(?!@)(.+)?$/g;
5
+ var YOUTUBE_REGEX = /^((?:https?:)?\/\/)?((?:www|m|music)\.)?((?:youtube\.com|youtu.be|youtube-nocookie\.com))(\/(?:[\w-]+\?v=|embed\/|v\/)?)([\w-]+)(\S+)?$/;
6
+ var YOUTUBE_REGEX_GLOBAL = /^((?:https?:)?\/\/)?((?:www|m|music)\.)?((?:youtube\.com|youtu.be|youtube-nocookie\.com))(\/(?:[\w-]+\?v=|embed\/|v\/)?)([\w-]+)(\S+)?$/g;
7
7
  var isValidYoutubeUrl = (url) => {
8
8
  return url.match(YOUTUBE_REGEX);
9
9
  };
@@ -245,9 +245,9 @@ var Youtube = Node.create({
245
245
  });
246
246
 
247
247
  // src/index.ts
248
- var src_default = Youtube;
248
+ var index_default = Youtube;
249
249
  export {
250
250
  Youtube,
251
- src_default as default
251
+ index_default as default
252
252
  };
253
253
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/youtube.ts","../src/utils.ts","../src/index.ts"],"sourcesContent":["import { mergeAttributes, Node, nodePasteRule } from '@tiptap/core'\n\nimport { getEmbedUrlFromYoutubeUrl, isValidYoutubeUrl, YOUTUBE_REGEX_GLOBAL } from './utils.js'\n\nexport interface YoutubeOptions {\n /**\n * Controls if the paste handler for youtube videos should be added.\n * @default true\n * @example false\n */\n addPasteHandler: boolean;\n\n /**\n * Controls if the youtube video should be allowed to go fullscreen.\n * @default true\n * @example false\n */\n allowFullscreen: boolean;\n\n /**\n * Controls if the youtube video should autoplay.\n * @default false\n * @example true\n */\n autoplay: boolean;\n\n /**\n * The language of the captions shown in the youtube video.\n * @default undefined\n * @example 'en'\n */\n ccLanguage?: string;\n\n /**\n * Controls if the captions should be shown in the youtube video.\n * @default undefined\n * @example true\n */\n ccLoadPolicy?: boolean;\n\n /**\n * Controls if the controls should be shown in the youtube video.\n * @default true\n * @example false\n */\n controls: boolean;\n\n /**\n * Controls if the keyboard controls should be disabled in the youtube video.\n * @default false\n * @example true\n */\n disableKBcontrols: boolean;\n\n /**\n * Controls if the iframe api should be enabled in the youtube video.\n * @default false\n * @example true\n */\n enableIFrameApi: boolean;\n\n /**\n * The end time of the youtube video.\n * @default 0\n * @example 120\n */\n endTime: number;\n\n /**\n * The height of the youtube video.\n * @default 480\n * @example 720\n */\n height: number;\n\n /**\n * The language of the youtube video.\n * @default undefined\n * @example 'en'\n */\n interfaceLanguage?: string;\n\n /**\n * Controls if the video annotations should be shown in the youtube video.\n * @default 0\n * @example 1\n */\n ivLoadPolicy: number;\n\n /**\n * Controls if the youtube video should loop.\n * @default false\n * @example true\n */\n loop: boolean;\n\n /**\n * Controls if the youtube video should show a small youtube logo.\n * @default false\n * @example true\n */\n modestBranding: boolean;\n\n /**\n * The HTML attributes for a youtube video node.\n * @default {}\n * @example { class: 'foo' }\n */\n HTMLAttributes: Record<string, any>;\n\n /**\n * Controls if the youtube node should be inline or not.\n * @default false\n * @example true\n */\n inline: boolean;\n\n /**\n * Controls if the youtube video should be loaded from youtube-nocookie.com.\n * @default false\n * @example true\n */\n nocookie: boolean;\n\n /**\n * The origin of the youtube video.\n * @default ''\n * @example 'https://tiptap.dev'\n */\n origin: string;\n\n /**\n * The playlist of the youtube video.\n * @default ''\n * @example 'PLQg6GaokU5CwiVmsZ0dZm6VeIg0V5z1tK'\n */\n playlist: string;\n\n /**\n * The color of the youtube video progress bar.\n * @default undefined\n * @example 'red'\n */\n progressBarColor?: string;\n\n /**\n * The width of the youtube video.\n * @default 640\n * @example 1280\n */\n width: number;\n}\n\n/**\n * The options for setting a youtube video.\n */\ntype SetYoutubeVideoOptions = { src: string, width?: number, height?: number, start?: number }\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n youtube: {\n /**\n * Insert a youtube video\n * @param options The youtube video attributes\n * @example editor.commands.setYoutubeVideo({ src: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ' })\n */\n setYoutubeVideo: (options: SetYoutubeVideoOptions) => ReturnType,\n }\n }\n}\n\n/**\n * This extension adds support for youtube videos.\n * @see https://www.tiptap.dev/api/nodes/youtube\n */\nexport const Youtube = Node.create<YoutubeOptions>({\n name: 'youtube',\n\n addOptions() {\n return {\n addPasteHandler: true,\n allowFullscreen: true,\n autoplay: false,\n ccLanguage: undefined,\n ccLoadPolicy: undefined,\n controls: true,\n disableKBcontrols: false,\n enableIFrameApi: false,\n endTime: 0,\n height: 480,\n interfaceLanguage: undefined,\n ivLoadPolicy: 0,\n loop: false,\n modestBranding: false,\n HTMLAttributes: {},\n inline: false,\n nocookie: false,\n origin: '',\n playlist: '',\n progressBarColor: undefined,\n width: 640,\n }\n },\n\n inline() {\n return this.options.inline\n },\n\n group() {\n return this.options.inline ? 'inline' : 'block'\n },\n\n draggable: true,\n\n addAttributes() {\n return {\n src: {\n default: null,\n },\n start: {\n default: 0,\n },\n width: {\n default: this.options.width,\n },\n height: {\n default: this.options.height,\n },\n }\n },\n\n parseHTML() {\n return [\n {\n tag: 'div[data-youtube-video] iframe',\n },\n ]\n },\n\n addCommands() {\n return {\n setYoutubeVideo: (options: SetYoutubeVideoOptions) => ({ commands }) => {\n if (!isValidYoutubeUrl(options.src)) {\n return false\n }\n\n return commands.insertContent({\n type: this.name,\n attrs: options,\n })\n },\n }\n },\n\n addPasteRules() {\n if (!this.options.addPasteHandler) {\n return []\n }\n\n return [\n nodePasteRule({\n find: YOUTUBE_REGEX_GLOBAL,\n type: this.type,\n getAttributes: match => {\n return { src: match.input }\n },\n }),\n ]\n },\n\n renderHTML({ HTMLAttributes }) {\n const embedUrl = getEmbedUrlFromYoutubeUrl({\n url: HTMLAttributes.src,\n allowFullscreen: this.options.allowFullscreen,\n autoplay: this.options.autoplay,\n ccLanguage: this.options.ccLanguage,\n ccLoadPolicy: this.options.ccLoadPolicy,\n controls: this.options.controls,\n disableKBcontrols: this.options.disableKBcontrols,\n enableIFrameApi: this.options.enableIFrameApi,\n endTime: this.options.endTime,\n interfaceLanguage: this.options.interfaceLanguage,\n ivLoadPolicy: this.options.ivLoadPolicy,\n loop: this.options.loop,\n modestBranding: this.options.modestBranding,\n nocookie: this.options.nocookie,\n origin: this.options.origin,\n playlist: this.options.playlist,\n progressBarColor: this.options.progressBarColor,\n startAt: HTMLAttributes.start || 0,\n })\n\n HTMLAttributes.src = embedUrl\n\n return [\n 'div',\n { 'data-youtube-video': '' },\n [\n 'iframe',\n mergeAttributes(\n this.options.HTMLAttributes,\n {\n width: this.options.width,\n height: this.options.height,\n allowfullscreen: this.options.allowFullscreen,\n autoplay: this.options.autoplay,\n ccLanguage: this.options.ccLanguage,\n ccLoadPolicy: this.options.ccLoadPolicy,\n disableKBcontrols: this.options.disableKBcontrols,\n enableIFrameApi: this.options.enableIFrameApi,\n endTime: this.options.endTime,\n interfaceLanguage: this.options.interfaceLanguage,\n ivLoadPolicy: this.options.ivLoadPolicy,\n loop: this.options.loop,\n modestBranding: this.options.modestBranding,\n origin: this.options.origin,\n playlist: this.options.playlist,\n progressBarColor: this.options.progressBarColor,\n },\n HTMLAttributes,\n ),\n ],\n ]\n },\n})\n","export const YOUTUBE_REGEX = /^(https?:\\/\\/)?(www\\.|music\\.)?(youtube\\.com|youtu\\.be|youtube-nocookie\\.com)\\/(?!channel\\/)(?!@)(.+)?$/\nexport const YOUTUBE_REGEX_GLOBAL = /^(https?:\\/\\/)?(www\\.|music\\.)?(youtube\\.com|youtu\\.be)\\/(?!channel\\/)(?!@)(.+)?$/g\n\nexport const isValidYoutubeUrl = (url: string) => {\n return url.match(YOUTUBE_REGEX)\n}\n\nexport interface GetEmbedUrlOptions {\n url: string;\n allowFullscreen?: boolean;\n autoplay?: boolean;\n ccLanguage?:string;\n ccLoadPolicy?:boolean;\n controls?: boolean;\n disableKBcontrols?: boolean,\n enableIFrameApi?: boolean;\n endTime?: number;\n interfaceLanguage?: string;\n ivLoadPolicy?: number;\n loop?: boolean;\n modestBranding?: boolean;\n nocookie?: boolean;\n origin?: string;\n playlist?: string;\n progressBarColor?: string;\n startAt?: number;\n}\n\nexport const getYoutubeEmbedUrl = (nocookie?: boolean) => {\n return nocookie ? 'https://www.youtube-nocookie.com/embed/' : 'https://www.youtube.com/embed/'\n}\n\nexport const getEmbedUrlFromYoutubeUrl = (options: GetEmbedUrlOptions) => {\n const {\n url,\n allowFullscreen,\n autoplay,\n ccLanguage,\n ccLoadPolicy,\n controls,\n disableKBcontrols,\n enableIFrameApi,\n endTime,\n interfaceLanguage,\n ivLoadPolicy,\n loop,\n modestBranding,\n nocookie,\n origin,\n playlist,\n progressBarColor,\n startAt,\n } = options\n\n if (!isValidYoutubeUrl(url)) {\n return null\n }\n\n // if is already an embed url, return it\n if (url.includes('/embed/')) {\n return url\n }\n\n // if is a youtu.be url, get the id after the /\n if (url.includes('youtu.be')) {\n const id = url.split('/').pop()\n\n if (!id) {\n return null\n }\n return `${getYoutubeEmbedUrl(nocookie)}${id}`\n }\n\n const videoIdRegex = /(?:v=|shorts\\/)([-\\w]+)/gm\n const matches = videoIdRegex.exec(url)\n\n if (!matches || !matches[1]) {\n return null\n }\n\n let outputUrl = `${getYoutubeEmbedUrl(nocookie)}${matches[1]}`\n\n const params = []\n\n if (allowFullscreen === false) {\n params.push('fs=0')\n }\n\n if (autoplay) {\n params.push('autoplay=1')\n }\n\n if (ccLanguage) {\n params.push(`cc_lang_pref=${ccLanguage}`)\n }\n\n if (ccLoadPolicy) {\n params.push('cc_load_policy=1')\n }\n\n if (!controls) {\n params.push('controls=0')\n }\n\n if (disableKBcontrols) {\n params.push('disablekb=1')\n }\n\n if (enableIFrameApi) {\n params.push('enablejsapi=1')\n }\n\n if (endTime) {\n params.push(`end=${endTime}`)\n }\n\n if (interfaceLanguage) {\n params.push(`hl=${interfaceLanguage}`)\n }\n\n if (ivLoadPolicy) {\n params.push(`iv_load_policy=${ivLoadPolicy}`)\n }\n\n if (loop) {\n params.push('loop=1')\n }\n\n if (modestBranding) {\n params.push('modestbranding=1')\n }\n\n if (origin) {\n params.push(`origin=${origin}`)\n }\n\n if (playlist) {\n params.push(`playlist=${playlist}`)\n }\n\n if (startAt) {\n params.push(`start=${startAt}`)\n }\n\n if (progressBarColor) {\n params.push(`color=${progressBarColor}`)\n }\n\n if (params.length) {\n outputUrl += `?${params.join('&')}`\n }\n\n return outputUrl\n}\n","import { Youtube } from './youtube.js'\n\nexport * from './youtube.js'\n\nexport default Youtube\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/youtube.ts","../src/utils.ts","../src/index.ts"],"sourcesContent":["import { mergeAttributes, Node, nodePasteRule } from '@tiptap/core'\n\nimport { getEmbedUrlFromYoutubeUrl, isValidYoutubeUrl, YOUTUBE_REGEX_GLOBAL } from './utils.js'\n\nexport interface YoutubeOptions {\n /**\n * Controls if the paste handler for youtube videos should be added.\n * @default true\n * @example false\n */\n addPasteHandler: boolean\n\n /**\n * Controls if the youtube video should be allowed to go fullscreen.\n * @default true\n * @example false\n */\n allowFullscreen: boolean\n\n /**\n * Controls if the youtube video should autoplay.\n * @default false\n * @example true\n */\n autoplay: boolean\n\n /**\n * The language of the captions shown in the youtube video.\n * @default undefined\n * @example 'en'\n */\n ccLanguage?: string\n\n /**\n * Controls if the captions should be shown in the youtube video.\n * @default undefined\n * @example true\n */\n ccLoadPolicy?: boolean\n\n /**\n * Controls if the controls should be shown in the youtube video.\n * @default true\n * @example false\n */\n controls: boolean\n\n /**\n * Controls if the keyboard controls should be disabled in the youtube video.\n * @default false\n * @example true\n */\n disableKBcontrols: boolean\n\n /**\n * Controls if the iframe api should be enabled in the youtube video.\n * @default false\n * @example true\n */\n enableIFrameApi: boolean\n\n /**\n * The end time of the youtube video.\n * @default 0\n * @example 120\n */\n endTime: number\n\n /**\n * The height of the youtube video.\n * @default 480\n * @example 720\n */\n height: number\n\n /**\n * The language of the youtube video.\n * @default undefined\n * @example 'en'\n */\n interfaceLanguage?: string\n\n /**\n * Controls if the video annotations should be shown in the youtube video.\n * @default 0\n * @example 1\n */\n ivLoadPolicy: number\n\n /**\n * Controls if the youtube video should loop.\n * @default false\n * @example true\n */\n loop: boolean\n\n /**\n * Controls if the youtube video should show a small youtube logo.\n * @default false\n * @example true\n */\n modestBranding: boolean\n\n /**\n * The HTML attributes for a youtube video node.\n * @default {}\n * @example { class: 'foo' }\n */\n HTMLAttributes: Record<string, any>\n\n /**\n * Controls if the youtube node should be inline or not.\n * @default false\n * @example true\n */\n inline: boolean\n\n /**\n * Controls if the youtube video should be loaded from youtube-nocookie.com.\n * @default false\n * @example true\n */\n nocookie: boolean\n\n /**\n * The origin of the youtube video.\n * @default ''\n * @example 'https://tiptap.dev'\n */\n origin: string\n\n /**\n * The playlist of the youtube video.\n * @default ''\n * @example 'PLQg6GaokU5CwiVmsZ0dZm6VeIg0V5z1tK'\n */\n playlist: string\n\n /**\n * The color of the youtube video progress bar.\n * @default undefined\n * @example 'red'\n */\n progressBarColor?: string\n\n /**\n * The width of the youtube video.\n * @default 640\n * @example 1280\n */\n width: number\n}\n\n/**\n * The options for setting a youtube video.\n */\ntype SetYoutubeVideoOptions = { src: string; width?: number; height?: number; start?: number }\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n youtube: {\n /**\n * Insert a youtube video\n * @param options The youtube video attributes\n * @example editor.commands.setYoutubeVideo({ src: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ' })\n */\n setYoutubeVideo: (options: SetYoutubeVideoOptions) => ReturnType\n }\n }\n}\n\n/**\n * This extension adds support for youtube videos.\n * @see https://www.tiptap.dev/api/nodes/youtube\n */\nexport const Youtube = Node.create<YoutubeOptions>({\n name: 'youtube',\n\n addOptions() {\n return {\n addPasteHandler: true,\n allowFullscreen: true,\n autoplay: false,\n ccLanguage: undefined,\n ccLoadPolicy: undefined,\n controls: true,\n disableKBcontrols: false,\n enableIFrameApi: false,\n endTime: 0,\n height: 480,\n interfaceLanguage: undefined,\n ivLoadPolicy: 0,\n loop: false,\n modestBranding: false,\n HTMLAttributes: {},\n inline: false,\n nocookie: false,\n origin: '',\n playlist: '',\n progressBarColor: undefined,\n width: 640,\n }\n },\n\n inline() {\n return this.options.inline\n },\n\n group() {\n return this.options.inline ? 'inline' : 'block'\n },\n\n draggable: true,\n\n addAttributes() {\n return {\n src: {\n default: null,\n },\n start: {\n default: 0,\n },\n width: {\n default: this.options.width,\n },\n height: {\n default: this.options.height,\n },\n }\n },\n\n parseHTML() {\n return [\n {\n tag: 'div[data-youtube-video] iframe',\n },\n ]\n },\n\n addCommands() {\n return {\n setYoutubeVideo:\n (options: SetYoutubeVideoOptions) =>\n ({ commands }) => {\n if (!isValidYoutubeUrl(options.src)) {\n return false\n }\n\n return commands.insertContent({\n type: this.name,\n attrs: options,\n })\n },\n }\n },\n\n addPasteRules() {\n if (!this.options.addPasteHandler) {\n return []\n }\n\n return [\n nodePasteRule({\n find: YOUTUBE_REGEX_GLOBAL,\n type: this.type,\n getAttributes: match => {\n return { src: match.input }\n },\n }),\n ]\n },\n\n renderHTML({ HTMLAttributes }) {\n const embedUrl = getEmbedUrlFromYoutubeUrl({\n url: HTMLAttributes.src,\n allowFullscreen: this.options.allowFullscreen,\n autoplay: this.options.autoplay,\n ccLanguage: this.options.ccLanguage,\n ccLoadPolicy: this.options.ccLoadPolicy,\n controls: this.options.controls,\n disableKBcontrols: this.options.disableKBcontrols,\n enableIFrameApi: this.options.enableIFrameApi,\n endTime: this.options.endTime,\n interfaceLanguage: this.options.interfaceLanguage,\n ivLoadPolicy: this.options.ivLoadPolicy,\n loop: this.options.loop,\n modestBranding: this.options.modestBranding,\n nocookie: this.options.nocookie,\n origin: this.options.origin,\n playlist: this.options.playlist,\n progressBarColor: this.options.progressBarColor,\n startAt: HTMLAttributes.start || 0,\n })\n\n HTMLAttributes.src = embedUrl\n\n return [\n 'div',\n { 'data-youtube-video': '' },\n [\n 'iframe',\n mergeAttributes(\n this.options.HTMLAttributes,\n {\n width: this.options.width,\n height: this.options.height,\n allowfullscreen: this.options.allowFullscreen,\n autoplay: this.options.autoplay,\n ccLanguage: this.options.ccLanguage,\n ccLoadPolicy: this.options.ccLoadPolicy,\n disableKBcontrols: this.options.disableKBcontrols,\n enableIFrameApi: this.options.enableIFrameApi,\n endTime: this.options.endTime,\n interfaceLanguage: this.options.interfaceLanguage,\n ivLoadPolicy: this.options.ivLoadPolicy,\n loop: this.options.loop,\n modestBranding: this.options.modestBranding,\n origin: this.options.origin,\n playlist: this.options.playlist,\n progressBarColor: this.options.progressBarColor,\n },\n HTMLAttributes,\n ),\n ],\n ]\n },\n})\n","export const YOUTUBE_REGEX =\n /^((?:https?:)?\\/\\/)?((?:www|m|music)\\.)?((?:youtube\\.com|youtu.be|youtube-nocookie\\.com))(\\/(?:[\\w-]+\\?v=|embed\\/|v\\/)?)([\\w-]+)(\\S+)?$/\nexport const YOUTUBE_REGEX_GLOBAL =\n /^((?:https?:)?\\/\\/)?((?:www|m|music)\\.)?((?:youtube\\.com|youtu.be|youtube-nocookie\\.com))(\\/(?:[\\w-]+\\?v=|embed\\/|v\\/)?)([\\w-]+)(\\S+)?$/g\n\nexport const isValidYoutubeUrl = (url: string) => {\n return url.match(YOUTUBE_REGEX)\n}\n\nexport interface GetEmbedUrlOptions {\n url: string\n allowFullscreen?: boolean\n autoplay?: boolean\n ccLanguage?: string\n ccLoadPolicy?: boolean\n controls?: boolean\n disableKBcontrols?: boolean\n enableIFrameApi?: boolean\n endTime?: number\n interfaceLanguage?: string\n ivLoadPolicy?: number\n loop?: boolean\n modestBranding?: boolean\n nocookie?: boolean\n origin?: string\n playlist?: string\n progressBarColor?: string\n startAt?: number\n}\n\nexport const getYoutubeEmbedUrl = (nocookie?: boolean) => {\n return nocookie ? 'https://www.youtube-nocookie.com/embed/' : 'https://www.youtube.com/embed/'\n}\n\nexport const getEmbedUrlFromYoutubeUrl = (options: GetEmbedUrlOptions) => {\n const {\n url,\n allowFullscreen,\n autoplay,\n ccLanguage,\n ccLoadPolicy,\n controls,\n disableKBcontrols,\n enableIFrameApi,\n endTime,\n interfaceLanguage,\n ivLoadPolicy,\n loop,\n modestBranding,\n nocookie,\n origin,\n playlist,\n progressBarColor,\n startAt,\n } = options\n\n if (!isValidYoutubeUrl(url)) {\n return null\n }\n\n // if is already an embed url, return it\n if (url.includes('/embed/')) {\n return url\n }\n\n // if is a youtu.be url, get the id after the /\n if (url.includes('youtu.be')) {\n const id = url.split('/').pop()\n\n if (!id) {\n return null\n }\n return `${getYoutubeEmbedUrl(nocookie)}${id}`\n }\n\n const videoIdRegex = /(?:v=|shorts\\/)([-\\w]+)/gm\n const matches = videoIdRegex.exec(url)\n\n if (!matches || !matches[1]) {\n return null\n }\n\n let outputUrl = `${getYoutubeEmbedUrl(nocookie)}${matches[1]}`\n\n const params = []\n\n if (allowFullscreen === false) {\n params.push('fs=0')\n }\n\n if (autoplay) {\n params.push('autoplay=1')\n }\n\n if (ccLanguage) {\n params.push(`cc_lang_pref=${ccLanguage}`)\n }\n\n if (ccLoadPolicy) {\n params.push('cc_load_policy=1')\n }\n\n if (!controls) {\n params.push('controls=0')\n }\n\n if (disableKBcontrols) {\n params.push('disablekb=1')\n }\n\n if (enableIFrameApi) {\n params.push('enablejsapi=1')\n }\n\n if (endTime) {\n params.push(`end=${endTime}`)\n }\n\n if (interfaceLanguage) {\n params.push(`hl=${interfaceLanguage}`)\n }\n\n if (ivLoadPolicy) {\n params.push(`iv_load_policy=${ivLoadPolicy}`)\n }\n\n if (loop) {\n params.push('loop=1')\n }\n\n if (modestBranding) {\n params.push('modestbranding=1')\n }\n\n if (origin) {\n params.push(`origin=${origin}`)\n }\n\n if (playlist) {\n params.push(`playlist=${playlist}`)\n }\n\n if (startAt) {\n params.push(`start=${startAt}`)\n }\n\n if (progressBarColor) {\n params.push(`color=${progressBarColor}`)\n }\n\n if (params.length) {\n outputUrl += `?${params.join('&')}`\n }\n\n return outputUrl\n}\n","import { Youtube } from './youtube.js'\n\nexport * from './youtube.js'\n\nexport default Youtube\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tiptap/extension-youtube",
3
3
  "description": "a youtube embed extension for tiptap",
4
- "version": "3.0.0-next.2",
4
+ "version": "3.0.0-next.4",
5
5
  "homepage": "https://tiptap.dev",
6
6
  "keywords": [
7
7
  "tiptap",
@@ -15,7 +15,10 @@
15
15
  "type": "module",
16
16
  "exports": {
17
17
  ".": {
18
- "types": "./dist/index.d.ts",
18
+ "types": {
19
+ "import": "./dist/index.d.ts",
20
+ "require": "./dist/index.d.cts"
21
+ },
19
22
  "import": "./dist/index.js",
20
23
  "require": "./dist/index.cjs"
21
24
  }
@@ -28,7 +31,7 @@
28
31
  "dist"
29
32
  ],
30
33
  "devDependencies": {
31
- "@tiptap/core": "^3.0.0-next.2"
34
+ "@tiptap/core": "^3.0.0-next.4"
32
35
  },
33
36
  "peerDependencies": {
34
37
  "@tiptap/core": "^3.0.0-next.1"
@@ -39,6 +42,7 @@
39
42
  "directory": "packages/extension-youtube"
40
43
  },
41
44
  "scripts": {
42
- "build": "tsup"
45
+ "build": "tsup",
46
+ "lint": "prettier ./src/ --check && eslint --cache --quiet --no-error-on-unmatched-pattern ./src/"
43
47
  }
44
- }
48
+ }
package/src/utils.ts CHANGED
@@ -1,29 +1,31 @@
1
- export const YOUTUBE_REGEX = /^(https?:\/\/)?(www\.|music\.)?(youtube\.com|youtu\.be|youtube-nocookie\.com)\/(?!channel\/)(?!@)(.+)?$/
2
- export const YOUTUBE_REGEX_GLOBAL = /^(https?:\/\/)?(www\.|music\.)?(youtube\.com|youtu\.be)\/(?!channel\/)(?!@)(.+)?$/g
1
+ export const YOUTUBE_REGEX =
2
+ /^((?:https?:)?\/\/)?((?:www|m|music)\.)?((?:youtube\.com|youtu.be|youtube-nocookie\.com))(\/(?:[\w-]+\?v=|embed\/|v\/)?)([\w-]+)(\S+)?$/
3
+ export const YOUTUBE_REGEX_GLOBAL =
4
+ /^((?:https?:)?\/\/)?((?:www|m|music)\.)?((?:youtube\.com|youtu.be|youtube-nocookie\.com))(\/(?:[\w-]+\?v=|embed\/|v\/)?)([\w-]+)(\S+)?$/g
3
5
 
4
6
  export const isValidYoutubeUrl = (url: string) => {
5
7
  return url.match(YOUTUBE_REGEX)
6
8
  }
7
9
 
8
10
  export interface GetEmbedUrlOptions {
9
- url: string;
10
- allowFullscreen?: boolean;
11
- autoplay?: boolean;
12
- ccLanguage?:string;
13
- ccLoadPolicy?:boolean;
14
- controls?: boolean;
15
- disableKBcontrols?: boolean,
16
- enableIFrameApi?: boolean;
17
- endTime?: number;
18
- interfaceLanguage?: string;
19
- ivLoadPolicy?: number;
20
- loop?: boolean;
21
- modestBranding?: boolean;
22
- nocookie?: boolean;
23
- origin?: string;
24
- playlist?: string;
25
- progressBarColor?: string;
26
- startAt?: number;
11
+ url: string
12
+ allowFullscreen?: boolean
13
+ autoplay?: boolean
14
+ ccLanguage?: string
15
+ ccLoadPolicy?: boolean
16
+ controls?: boolean
17
+ disableKBcontrols?: boolean
18
+ enableIFrameApi?: boolean
19
+ endTime?: number
20
+ interfaceLanguage?: string
21
+ ivLoadPolicy?: number
22
+ loop?: boolean
23
+ modestBranding?: boolean
24
+ nocookie?: boolean
25
+ origin?: string
26
+ playlist?: string
27
+ progressBarColor?: string
28
+ startAt?: number
27
29
  }
28
30
 
29
31
  export const getYoutubeEmbedUrl = (nocookie?: boolean) => {
package/src/youtube.ts CHANGED
@@ -8,153 +8,153 @@ export interface YoutubeOptions {
8
8
  * @default true
9
9
  * @example false
10
10
  */
11
- addPasteHandler: boolean;
11
+ addPasteHandler: boolean
12
12
 
13
13
  /**
14
14
  * Controls if the youtube video should be allowed to go fullscreen.
15
15
  * @default true
16
16
  * @example false
17
17
  */
18
- allowFullscreen: boolean;
18
+ allowFullscreen: boolean
19
19
 
20
20
  /**
21
21
  * Controls if the youtube video should autoplay.
22
22
  * @default false
23
23
  * @example true
24
24
  */
25
- autoplay: boolean;
25
+ autoplay: boolean
26
26
 
27
27
  /**
28
28
  * The language of the captions shown in the youtube video.
29
29
  * @default undefined
30
30
  * @example 'en'
31
31
  */
32
- ccLanguage?: string;
32
+ ccLanguage?: string
33
33
 
34
34
  /**
35
35
  * Controls if the captions should be shown in the youtube video.
36
36
  * @default undefined
37
37
  * @example true
38
38
  */
39
- ccLoadPolicy?: boolean;
39
+ ccLoadPolicy?: boolean
40
40
 
41
41
  /**
42
42
  * Controls if the controls should be shown in the youtube video.
43
43
  * @default true
44
44
  * @example false
45
45
  */
46
- controls: boolean;
46
+ controls: boolean
47
47
 
48
48
  /**
49
49
  * Controls if the keyboard controls should be disabled in the youtube video.
50
50
  * @default false
51
51
  * @example true
52
52
  */
53
- disableKBcontrols: boolean;
53
+ disableKBcontrols: boolean
54
54
 
55
55
  /**
56
56
  * Controls if the iframe api should be enabled in the youtube video.
57
57
  * @default false
58
58
  * @example true
59
59
  */
60
- enableIFrameApi: boolean;
60
+ enableIFrameApi: boolean
61
61
 
62
62
  /**
63
63
  * The end time of the youtube video.
64
64
  * @default 0
65
65
  * @example 120
66
66
  */
67
- endTime: number;
67
+ endTime: number
68
68
 
69
69
  /**
70
70
  * The height of the youtube video.
71
71
  * @default 480
72
72
  * @example 720
73
73
  */
74
- height: number;
74
+ height: number
75
75
 
76
76
  /**
77
77
  * The language of the youtube video.
78
78
  * @default undefined
79
79
  * @example 'en'
80
80
  */
81
- interfaceLanguage?: string;
81
+ interfaceLanguage?: string
82
82
 
83
83
  /**
84
84
  * Controls if the video annotations should be shown in the youtube video.
85
85
  * @default 0
86
86
  * @example 1
87
87
  */
88
- ivLoadPolicy: number;
88
+ ivLoadPolicy: number
89
89
 
90
90
  /**
91
91
  * Controls if the youtube video should loop.
92
92
  * @default false
93
93
  * @example true
94
94
  */
95
- loop: boolean;
95
+ loop: boolean
96
96
 
97
97
  /**
98
98
  * Controls if the youtube video should show a small youtube logo.
99
99
  * @default false
100
100
  * @example true
101
101
  */
102
- modestBranding: boolean;
102
+ modestBranding: boolean
103
103
 
104
104
  /**
105
105
  * The HTML attributes for a youtube video node.
106
106
  * @default {}
107
107
  * @example { class: 'foo' }
108
108
  */
109
- HTMLAttributes: Record<string, any>;
109
+ HTMLAttributes: Record<string, any>
110
110
 
111
111
  /**
112
112
  * Controls if the youtube node should be inline or not.
113
113
  * @default false
114
114
  * @example true
115
115
  */
116
- inline: boolean;
116
+ inline: boolean
117
117
 
118
118
  /**
119
119
  * Controls if the youtube video should be loaded from youtube-nocookie.com.
120
120
  * @default false
121
121
  * @example true
122
122
  */
123
- nocookie: boolean;
123
+ nocookie: boolean
124
124
 
125
125
  /**
126
126
  * The origin of the youtube video.
127
127
  * @default ''
128
128
  * @example 'https://tiptap.dev'
129
129
  */
130
- origin: string;
130
+ origin: string
131
131
 
132
132
  /**
133
133
  * The playlist of the youtube video.
134
134
  * @default ''
135
135
  * @example 'PLQg6GaokU5CwiVmsZ0dZm6VeIg0V5z1tK'
136
136
  */
137
- playlist: string;
137
+ playlist: string
138
138
 
139
139
  /**
140
140
  * The color of the youtube video progress bar.
141
141
  * @default undefined
142
142
  * @example 'red'
143
143
  */
144
- progressBarColor?: string;
144
+ progressBarColor?: string
145
145
 
146
146
  /**
147
147
  * The width of the youtube video.
148
148
  * @default 640
149
149
  * @example 1280
150
150
  */
151
- width: number;
151
+ width: number
152
152
  }
153
153
 
154
154
  /**
155
155
  * The options for setting a youtube video.
156
156
  */
157
- type SetYoutubeVideoOptions = { src: string, width?: number, height?: number, start?: number }
157
+ type SetYoutubeVideoOptions = { src: string; width?: number; height?: number; start?: number }
158
158
 
159
159
  declare module '@tiptap/core' {
160
160
  interface Commands<ReturnType> {
@@ -164,7 +164,7 @@ declare module '@tiptap/core' {
164
164
  * @param options The youtube video attributes
165
165
  * @example editor.commands.setYoutubeVideo({ src: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ' })
166
166
  */
167
- setYoutubeVideo: (options: SetYoutubeVideoOptions) => ReturnType,
167
+ setYoutubeVideo: (options: SetYoutubeVideoOptions) => ReturnType
168
168
  }
169
169
  }
170
170
  }
@@ -239,16 +239,18 @@ export const Youtube = Node.create<YoutubeOptions>({
239
239
 
240
240
  addCommands() {
241
241
  return {
242
- setYoutubeVideo: (options: SetYoutubeVideoOptions) => ({ commands }) => {
243
- if (!isValidYoutubeUrl(options.src)) {
244
- return false
245
- }
246
-
247
- return commands.insertContent({
248
- type: this.name,
249
- attrs: options,
250
- })
251
- },
242
+ setYoutubeVideo:
243
+ (options: SetYoutubeVideoOptions) =>
244
+ ({ commands }) => {
245
+ if (!isValidYoutubeUrl(options.src)) {
246
+ return false
247
+ }
248
+
249
+ return commands.insertContent({
250
+ type: this.name,
251
+ attrs: options,
252
+ })
253
+ },
252
254
  }
253
255
  },
254
256