ueberdosis / tiptap

The headless rich text editor framework for web artisans.
https://tiptap.dev
MIT License
27.49k stars 2.28k forks source link

Build a Video-Extension? #2757

Closed siriusdemon closed 2 years ago

siriusdemon commented 2 years ago

What problem are you facing?

I want to insert a video in my article.

What’s the solution you would like to see?

Almost same as the Image extension.

What alternatives did you consider?

None

Anything to add? (optional)

No response

Are you sponsoring us?

bdbch commented 2 years ago

@siriusdemon thanks for your feature request. We'll take it into consideration when planning our next set of extensions.

codemzy commented 2 years ago

@siriusdemon here's an extension I wrote for adding video embeds... e.g. from YouTube

import { Node, mergeAttributes } from '@tiptap/core'

const Video = Node.create({
  name: 'video', // unique name for the Node
  group: 'block', // belongs to the 'block' group of extensions
  selectable: true, // so we can select the video
  draggable: true, // so we can drag the video
  atom: true, // is a single unit

  addAttributes() {
    return {
      "src": {
        default: null
      },
    }
  },

  parseHTML() {
    return [
      {
        tag: 'video',
      },
    ]
  },

  renderHTML({ HTMLAttributes }) {
      return ['video', mergeAttributes(HTMLAttributes)];
  },

  addNodeView() {
    return ({ editor, node }) => {
      const div = document.createElement('div');
      div.className = 'aspect-w-16 aspect-h-9' + (editor.isEditable ? ' cursor-pointer' : '');
      const iframe = document.createElement('iframe');
      if (editor.isEditable) {
        iframe.className = 'pointer-events-none';
      }
      iframe.width = '640';
      iframe.height = '360';
      iframe.frameborder = "0";
      iframe.allowfullscreen = "";
      iframe.src = node.attrs.src;
      div.append(iframe);
      return {
        dom: div,
      }
    }
  },
});

I choose to use a <video> tag, but you could also use something like <embed data-type="video" if you don't want to override the native <video> element behaviour.

The wrapping div and Tailwind CSS classes in the node view makes the embed responsive. It's draggable when the editor is editable, and in read only the video will playback like normal.

Hope it helps! I also wrote a blog post about it here https://www.codemzy.com/blog/tiptap-video-embed-extension

neemiasbj commented 2 years ago

@codemzy what should i do to use this extension in my project? Could you help me, please?

rezaffm commented 2 years ago

You need to import the extension, like

  import CustomExtension from '/Extension'

      this.editor = new Editor({
        editorProps: {
          attributes: {
            class: 'Editor'
          }
        },
        extensions: [
          // Other extensions
          CustomExtension
        ],
      })

And that's it..

neemiasbj commented 2 years ago

You need to import the extension, like

  import CustomExtension from '/Extension'

      this.editor = new Editor({
        editorProps: {
          attributes: {
            class: 'Editor'
          }
        },
        extensions: [
          // Other extensions
          CustomExtension
        ],
      })

And that's it..

Thankyou very much. Working. :D

Is it too hard to use the full embed tag that youtube give us to use?

image This one for example.

codemzy commented 2 years ago

That should be fairly straightforward, you'd update the node view for that. I kept my code more generic so it could be used with Vimeo embeds too.

You can add the extra attributes in the addNodeView() - something like...

  addNodeView() {
    return ({ editor, node }) => {
      const div = document.createElement('div');
      div.className = 'aspect-w-16 aspect-h-9' + (editor.isEditable ? ' cursor-pointer' : '');
      const iframe = document.createElement('iframe');
      if (editor.isEditable) {
        iframe.className = 'pointer-events-none';
      }
      iframe.width = '640';
      iframe.height = '360';
      iframe.frameborder = "0";
      iframe.allowfullscreen = "";
      iframe.src = node.attrs.src;
      iframe.title = "YouTube video player"; // this is new
      iframe.allow = "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"; // this is new
      div.append(iframe);
      return {
        dom: div,
      }
    }
  },

I think that would add the extra attributes on the full embed tag (I've not tested it though)!

neemiasbj commented 2 years ago

That should be fairly straightforward, you'd update the node view for that. I kept my code more generic so it could be used with Vimeo embeds too.

You can add the extra attributes in the addNodeView() - something like...

  addNodeView() {
    return ({ editor, node }) => {
      const div = document.createElement('div');
      div.className = 'aspect-w-16 aspect-h-9' + (editor.isEditable ? ' cursor-pointer' : '');
      const iframe = document.createElement('iframe');
      if (editor.isEditable) {
        iframe.className = 'pointer-events-none';
      }
      iframe.width = '640';
      iframe.height = '360';
      iframe.frameborder = "0";
      iframe.allowfullscreen = "";
      iframe.src = node.attrs.src;
      iframe.title = "YouTube video player"; // this is new
      iframe.allow = "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"; // this is new
      div.append(iframe);
      return {
        dom: div,
      }
    }
  },

I think that would add the extra attributes on the full embed tag (I've not tested it though)!

Man, YOU ARE THE BEST :D

THankyou very much.

Any chances to makke images/iframe resizeble on javascript?

I just found it for Vue :(

echo4eva commented 2 years ago

Hello, Is this going to be merged as a feature or is still open?

svenadlung commented 2 years ago

@echo4eva Meanwhile we released a basic YouTube extension: https://tiptap.dev/api/extensions/youtube