summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/content_editor/extensions/playable.js
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/content_editor/extensions/playable.js')
-rw-r--r--app/assets/javascripts/content_editor/extensions/playable.js66
1 files changed, 66 insertions, 0 deletions
diff --git a/app/assets/javascripts/content_editor/extensions/playable.js b/app/assets/javascripts/content_editor/extensions/playable.js
new file mode 100644
index 00000000000..0062bc563db
--- /dev/null
+++ b/app/assets/javascripts/content_editor/extensions/playable.js
@@ -0,0 +1,66 @@
+/* eslint-disable @gitlab/require-i18n-strings */
+
+import { Node } from '@tiptap/core';
+
+const queryPlayableElement = (element, mediaType) => element.querySelector(mediaType);
+
+export default Node.create({
+ group: 'inline',
+ inline: true,
+ draggable: true,
+
+ addAttributes() {
+ return {
+ src: {
+ default: null,
+ parseHTML: (element) => {
+ const playable = queryPlayableElement(element, this.options.mediaType);
+
+ return playable.src;
+ },
+ },
+ canonicalSrc: {
+ default: null,
+ parseHTML: (element) => {
+ const playable = queryPlayableElement(element, this.options.mediaType);
+
+ return playable.dataset.canonicalSrc;
+ },
+ },
+ alt: {
+ default: null,
+ parseHTML: (element) => {
+ const playable = queryPlayableElement(element, this.options.mediaType);
+
+ return playable.dataset.title;
+ },
+ },
+ };
+ },
+
+ parseHTML() {
+ return [
+ {
+ tag: `.${this.options.mediaType}-container`,
+ },
+ ];
+ },
+
+ renderHTML({ node }) {
+ return [
+ 'span',
+ { class: `media-container ${this.options.mediaType}-container` },
+ [
+ this.options.mediaType,
+ {
+ src: node.attrs.src,
+ controls: true,
+ 'data-setup': '{}',
+ 'data-title': node.attrs.alt,
+ ...this.extraElementAttrs,
+ },
+ ],
+ ['a', { href: node.attrs.src }, node.attrs.alt],
+ ];
+ },
+});