diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-07-19 17:16:28 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-07-19 17:16:28 +0300 |
commit | e4384360a16dd9a19d4d2d25d0ef1f2b862ed2a6 (patch) | |
tree | 2fcdfa7dcdb9db8f5208b2562f4b4e803d671243 /app/assets/javascripts/content_editor/components/wrappers/image.vue | |
parent | ffda4e7bcac36987f936b4ba515995a6698698f0 (diff) |
Add latest changes from gitlab-org/gitlab@16-2-stable-eev16.2.0-rc42
Diffstat (limited to 'app/assets/javascripts/content_editor/components/wrappers/image.vue')
-rw-r--r-- | app/assets/javascripts/content_editor/components/wrappers/image.vue | 103 |
1 files changed, 103 insertions, 0 deletions
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> |