diff options
Diffstat (limited to 'app/assets/javascripts/behaviors/markdown/nodes/playable.js')
-rw-r--r-- | app/assets/javascripts/behaviors/markdown/nodes/playable.js | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/app/assets/javascripts/behaviors/markdown/nodes/playable.js b/app/assets/javascripts/behaviors/markdown/nodes/playable.js new file mode 100644 index 00000000000..08539df1242 --- /dev/null +++ b/app/assets/javascripts/behaviors/markdown/nodes/playable.js @@ -0,0 +1,73 @@ +/* eslint-disable class-methods-use-this */ +/* eslint-disable @gitlab/i18n/no-non-i18n-strings */ + +import { Node } from 'tiptap'; +import { defaultMarkdownSerializer } from 'prosemirror-markdown'; +import { HIGHER_PARSE_RULE_PRIORITY } from '../constants'; + +/** + * Abstract base class for playable media, like video and audio. + * Must not be instantiated directly. Subclasses must set + * the `mediaType` property in their constructors. + * @abstract + */ +export default class Playable extends Node { + constructor() { + super(); + this.mediaType = ''; + this.extraElementAttrs = {}; + } + + get name() { + return this.mediaType; + } + + get schema() { + const attrs = { + src: {}, + alt: { + default: null, + }, + }; + + const parseDOM = [ + { + tag: `.${this.mediaType}-container`, + skip: true, + }, + { + tag: `.${this.mediaType}-container p`, + priority: HIGHER_PARSE_RULE_PRIORITY, + ignore: true, + }, + { + tag: `${this.mediaType}[src]`, + getAttrs: el => ({ src: el.getAttribute('src'), alt: el.dataset.title }), + }, + ]; + + const toDOM = node => [ + this.mediaType, + { + src: node.attrs.src, + controls: true, + 'data-setup': '{}', + 'data-title': node.attrs.alt, + ...this.extraElementAttrs, + }, + ]; + + return { + attrs, + group: 'block', + draggable: true, + parseDOM, + toDOM, + }; + } + + toMarkdown(state, node) { + defaultMarkdownSerializer.nodes.image(state, node); + state.closeBlock(node); + } +} |