From e4384360a16dd9a19d4d2d25d0ef1f2b862ed2a6 Mon Sep 17 00:00:00 2001
From: GitLab Bot <gitlab-bot@gitlab.com>
Date: Wed, 19 Jul 2023 14:16:28 +0000
Subject: Add latest changes from gitlab-org/gitlab@16-2-stable-ee

---
 .../content_editor/components/wrappers/image.vue   | 103 +++++++++++++++++++++
 1 file changed, 103 insertions(+)
 create mode 100644 app/assets/javascripts/content_editor/components/wrappers/image.vue

(limited to 'app/assets/javascripts/content_editor/components/wrappers/image.vue')

diff --git a/app/assets/javascripts/content_editor/components/wrappers/image.vue b/app/assets/javascripts/content_editor/components/wrappers/image.vue
new file mode 100644
index 00000000000..0b80802d993
--- /dev/null
+++ b/app/assets/javascripts/content_editor/components/wrappers/image.vue
@@ -0,0 +1,103 @@
+<script>
+import { NodeViewWrapper } from '@tiptap/vue-2';
+
+export default {
+  name: 'ImageWrapper',
+  components: {
+    NodeViewWrapper,
+  },
+  props: {
+    getPos: {
+      type: Function,
+      required: true,
+    },
+    editor: {
+      type: Object,
+      required: true,
+    },
+    node: {
+      type: Object,
+      required: true,
+    },
+    selected: {
+      type: Boolean,
+      required: false,
+      default: false,
+    },
+  },
+  data() {
+    return {
+      dragData: {},
+    };
+  },
+  mounted() {
+    document.addEventListener('mousemove', this.onDrag);
+    document.addEventListener('mouseup', this.onDragEnd);
+  },
+  destroyed() {
+    document.removeEventListener('mousemove', this.onDrag);
+    document.removeEventListener('mouseup', this.onDragEnd);
+  },
+  methods: {
+    onDragStart(handle, event) {
+      this.dragData = {
+        handle,
+        startX: event.screenX,
+        startY: event.screenY,
+        width: this.$refs.image.width,
+        height: this.$refs.image.height,
+      };
+    },
+    onDrag(event) {
+      const { handle, startX, width, height } = this.dragData;
+      if (!handle) return;
+
+      const deltaX = event.screenX - startX;
+      const newWidth = handle.includes('w') ? width - deltaX : width + deltaX;
+      const newHeight = (height / width) * newWidth;
+
+      this.$refs.image.setAttribute('width', newWidth);
+      this.$refs.image.setAttribute('height', newHeight);
+    },
+    onDragEnd() {
+      const { handle } = this.dragData;
+      if (!handle) return;
+
+      this.dragData = {};
+
+      this.editor
+        .chain()
+        .focus()
+        .updateAttributes(this.node.type, {
+          width: this.$refs.image.width,
+          height: this.$refs.image.height,
+        })
+        .setNodeSelection(this.getPos())
+        .run();
+    },
+  },
+  resizeHandles: ['ne', 'nw', 'se', 'sw'],
+};
+</script>
+<template>
+  <node-view-wrapper as="span" class="gl-relative gl-display-inline-block">
+    <span
+      v-for="handle in $options.resizeHandles"
+      v-show="selected"
+      :key="handle"
+      class="image-resize"
+      :class="`image-resize-${handle}`"
+      :data-testid="`image-resize-${handle}`"
+      @mousedown="onDragStart(handle, $event)"
+    ></span>
+    <img
+      ref="image"
+      :src="node.attrs.src"
+      :alt="node.attrs.alt"
+      :title="node.attrs.title"
+      :width="node.attrs.width || 'auto'"
+      :height="node.attrs.height || 'auto'"
+      :class="{ 'ProseMirror-selectednode': selected }"
+    />
+  </node-view-wrapper>
+</template>
-- 
cgit v1.2.3

