74 lines
1.6 KiB
TypeScript
74 lines
1.6 KiB
TypeScript
import { mergeAttributes, Node } from '@tiptap/core'
|
|
import { NodeRange } from 'prosemirror-model'
|
|
import { insert } from 'solid-js/web'
|
|
import { TextSelection } from 'prosemirror-state'
|
|
|
|
export interface IframeOptions {
|
|
allowFullscreen: boolean
|
|
HTMLAttributes: {
|
|
[key: string]: any
|
|
}
|
|
}
|
|
|
|
declare module '@tiptap/core' {
|
|
interface Commands<ReturnType> {
|
|
iframe: {
|
|
setIframe: (options: { src: string }) => ReturnType
|
|
}
|
|
}
|
|
}
|
|
|
|
export const Embed = Node.create<IframeOptions>({
|
|
name: 'embed',
|
|
group: 'block',
|
|
selectable: true,
|
|
atom: true,
|
|
draggable: true,
|
|
addAttributes() {
|
|
return {
|
|
src: { default: null },
|
|
width: { default: null },
|
|
height: { default: null }
|
|
}
|
|
},
|
|
parseHTML() {
|
|
return [
|
|
{
|
|
tag: 'iframe'
|
|
}
|
|
]
|
|
},
|
|
renderHTML({ HTMLAttributes }) {
|
|
return ['iframe', mergeAttributes(HTMLAttributes)]
|
|
},
|
|
addNodeView() {
|
|
return ({ node }) => {
|
|
const div = document.createElement('div')
|
|
div.className = 'embed-wrapper'
|
|
const iframe = document.createElement('iframe')
|
|
iframe.width = node.attrs.width
|
|
iframe.height = node.attrs.height
|
|
iframe.allowfullscreen = node.attrs.allowfullscreen
|
|
iframe.src = node.attrs.src
|
|
div.append(iframe)
|
|
return {
|
|
dom: div
|
|
}
|
|
}
|
|
},
|
|
addCommands() {
|
|
return {
|
|
setIframe:
|
|
(options) =>
|
|
({ tr, dispatch }) => {
|
|
const { selection } = tr
|
|
const node = this.type.create(options)
|
|
if (dispatch) {
|
|
tr.replaceRangeWith(selection.from, selection.to, node)
|
|
}
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
})
|