summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/behaviors/markdown/nodes/playable.js
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/behaviors/markdown/nodes/playable.js')
-rw-r--r--app/assets/javascripts/behaviors/markdown/nodes/playable.js73
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);
+ }
+}