mattwr18 da1df27799 Extract logic to EmbedComponent to separate concerns
- Co-authored-by: senderfm <dev@sender.fm>
2019-10-07 19:15:39 +02:00

94 lines
2.1 KiB
JavaScript

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 = `<component :dataEmbedUrl="dataEmbedUrl" :embedData="embedData" :is="componentType" />`
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)
},
}
}
}