diff --git a/webapp/components/Editor/defaultExtensions.js b/webapp/components/Editor/defaultExtensions.js index 4b0eff1f9..63cf8c73f 100644 --- a/webapp/components/Editor/defaultExtensions.js +++ b/webapp/components/Editor/defaultExtensions.js @@ -1,4 +1,5 @@ import Embed from '~/components/Editor/nodes/Embed.js' +import LegacyEmbed from '~/components/Editor/nodes/LegacyEmbed.js' import Link from '~/components/Editor/nodes/Link.js' import Strike from '~/components/Editor/marks/Strike' import Italic from '~/components/Editor/marks/Italic' @@ -44,5 +45,13 @@ export default function defaultExtensions(component) { return embed }, }), + new LegacyEmbed({ + onEmbed: async ({ url }) => { + const { + data: { embed }, + } = await $apollo.query({ query: EmbedQuery(), variables: { url } }) + return embed + }, + }), ] } diff --git a/webapp/components/Editor/nodes/LegacyEmbed.js b/webapp/components/Editor/nodes/LegacyEmbed.js new file mode 100644 index 000000000..0d7a82a18 --- /dev/null +++ b/webapp/components/Editor/nodes/LegacyEmbed.js @@ -0,0 +1,93 @@ +import { Node } from 'tiptap' +import pasteRule from '../commands/pasteRule' +import { compileToFunctions } from 'vue-template-compiler' +import Vue from 'vue' +import EmbedComponent from '~/components/Embed/EmbedComponent' + +Vue.component(EmbedComponent) +const template = `` + +const compiledTemplate = compileToFunctions(template) + +export default class Embed extends Node { + get name() { + return 'embed' + } + + get defaultOptions() { + return { + onEmbed: () => ({}), + } + } + + pasteRules({ type, schema }) { + return [ + pasteRule( + // source: https://stackoverflow.com/a/3809435 + /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)/g, + type, + url => ({ dataEmbedUrl: url }), + ), + ] + } + + get schema() { + return { + attrs: { + dataEmbedUrl: { + default: null, + }, + }, + group: 'inline', + inline: true, + parseDOM: [ + { + tag: 'a[href].embed', + getAttrs: dom => ({ + dataEmbedUrl: dom.getAttribute('href'), + }), + }, + ], + toDOM: node => [ + 'a', + { + href: node.attrs.dataEmbedUrl, + class: 'embed', + target: '_blank', + }, + ], + } + } + + get view() { + return { + props: ['node', 'updateAttrs', 'options'], + data: () => ({ + embedData: {}, + }), + async created() { + if (this.options) { + this.embedData = await this.options.onEmbed({ url: this.dataEmbedUrl }) + } + }, + computed: { + componentType() { + return EmbedComponent + }, + dataEmbedUrl: { + get() { + return this.node.attrs.dataEmbedUrl + }, + set(dataEmbedUrl) { + this.updateAttrs({ + dataEmbedUrl, + }) + }, + }, + }, + render(createElement) { + return compiledTemplate.render.call(this, createElement) + }, + } + } +}