Skip to content

Handle textarea resize when searched text is highlighted

Summary

  • Handle textarea resize when searching for text.
  • Additionally, when searched text is not in scroll view, the text and the current match highlight should be scrolled into view.

Implementation

Something like this should work:

diff --git a/app/assets/javascripts/vue_shared/components/markdown/header.vue b/app/assets/javascripts/vue_shared/components/markdown/header.vue
index c2c2c2c9dc2d..e0c9a0db4cf7 100644
--- a/app/assets/javascripts/vue_shared/components/markdown/header.vue
+++ b/app/assets/javascripts/vue_shared/components/markdown/header.vue
@@ -302,8 +302,9 @@ export default {
       if (e.key === 'Enter') {
         e.preventDefault();
       } else if (e.key === 'Escape') {
+        const textarea = this.getCurrentTextArea();
         this.findAndReplace.shouldShowBar = false;
-        this.getCurrentTextArea()?.removeEventListener('scroll', this.findAndReplace_syncScroll);
+        textarea?.removeEventListener('scroll', this.findAndReplace_syncScroll);
         this.cloneDiv?.parentElement.removeChild(this.cloneDiv);
         this.cloneDiv = undefined;
       }
@@ -315,6 +316,19 @@ export default {
       const textArea = this.getCurrentTextArea();
       this.cloneDiv.scrollTop = textArea.scrollTop;
     },
+    findAndReplace_syncSize() {
+      const textArea = this.getCurrentTextArea();
+
+      if (!this.cloneDiv || !textArea) {
+        console.log('hmmm');
+        return;
+      }
+
+      const computed = window.getComputedStyle(textArea);
+
+      this.cloneDiv.style.width = computed.width;
+      this.cloneDiv.style.heigth = computed.height;
+    },
     findAndReplace_safeReplace(textArea, textToFind) {
       const regex = new RegExp(`(${textToFind})`, 'g');
       const segments = textArea.value.split(regex);
@@ -376,7 +390,6 @@ export default {
         'overflow',
         'white-space',
         'word-wrap',
-        'resize',
         'margin',
       ];
 
@@ -393,6 +406,8 @@ export default {
 
       textArea.addEventListener('scroll', this.findAndReplace_syncScroll);
 
+      new ResizeObserver(() => this.findAndReplace_syncSize()).observe(textArea);
+
       textArea.parentElement.insertBefore(this.cloneDiv, textArea);
 
       await this.$nextTick();

Context

The following discussion from !173004 (merged) should be addressed:

  • @svedova started a discussion: (+4 comments)

    My only primary concern is how do the selections behave when you resize the textarea?

Edited by 🤖 GitLab Bot 🤖