From 7f9d58fab8a3c4fd1a8f18d58e36fbfab7b30f33 Mon Sep 17 00:00:00 2001
From: Hester Gong <hestergong@gmail.com>
Date: Sat, 4 Mar 2023 06:28:20 +0800
Subject: [PATCH] Support paste treepath when creating a new file or updating
 the file name (#23209)

Close #23204

Quick Demo:


https://user-images.githubusercontent.com/17645053/222058727-ad30a37c-f0ac-4184-9946-a71fcee473b5.mov

---------

Co-authored-by: delvh <leon@kske.dev>
---
 web_src/js/features/repo-editor.js | 74 +++++++++++++++++-------------
 1 file changed, 42 insertions(+), 32 deletions(-)

diff --git a/web_src/js/features/repo-editor.js b/web_src/js/features/repo-editor.js
index a9d143847d..b3e9b65f21 100644
--- a/web_src/js/features/repo-editor.js
+++ b/web_src/js/features/repo-editor.js
@@ -91,36 +91,8 @@ export function initRepoEditor() {
     $('#commit-button').text($(this).attr('button_text'));
   });
 
-  const $editFilename = $('#file-name');
-  $editFilename.on('keyup', function (e) {
-    const $section = $('.breadcrumb span.section');
-    const $divider = $('.breadcrumb div.divider');
-    let value;
-    let parts;
-
-    if (e.keyCode === 8 && getCursorPosition($(this)) === 0 && $section.length > 0) {
-      value = $section.last().find('a').text();
-      $(this).val(value + $(this).val());
-      $(this)[0].setSelectionRange(value.length, value.length);
-      $section.last().remove();
-      $divider.last().remove();
-    }
-    if (e.keyCode === 191) {
-      parts = $(this).val().split('/');
-      for (let i = 0; i < parts.length; ++i) {
-        value = parts[i];
-        if (i < parts.length - 1) {
-          if (value.length) {
-            $(`<span class="section"><a href="#">${htmlEscape(value)}</a></span>`).insertBefore($(this));
-            $('<div class="divider"> / </div>').insertBefore($(this));
-          }
-        } else {
-          $(this).val(value);
-        }
-        $(this)[0].setSelectionRange(0, 0);
-      }
-    }
-    parts = [];
+  const joinTreePath = ($fileNameEl) => {
+    const parts = [];
     $('.breadcrumb span.section').each(function () {
       const element = $(this);
       if (element.find('a').length) {
@@ -129,9 +101,47 @@ export function initRepoEditor() {
         parts.push(element.text());
       }
     });
-    if ($(this).val()) parts.push($(this).val());
+    if ($fileNameEl.val()) parts.push($fileNameEl.val());
     $('#tree_path').val(parts.join('/'));
-  }).trigger('keyup');
+  };
+
+  const $editFilename = $('#file-name');
+  $editFilename.on('input', function () {
+    const parts = $(this).val().split('/');
+
+    if (parts.length > 1) {
+      for (let i = 0; i < parts.length; ++i) {
+        const value = parts[i];
+        if (i < parts.length - 1) {
+          if (value.length) {
+            $(`<span class="section"><a href="#">${htmlEscape(value)}</a></span>`).insertBefore($(this));
+            $('<div class="divider"> / </div>').insertBefore($(this));
+          }
+        } else {
+          $(this).val(value);
+        }
+        this.setSelectionRange(0, 0);
+      }
+    }
+
+    joinTreePath($(this));
+  });
+
+  $editFilename.on('keydown', function (e) {
+    const $section = $('.breadcrumb span.section');
+
+    // Jump back to last directory once the filename is empty
+    if (e.code === 'Backspace' && getCursorPosition($(this)) === 0 && $section.length > 0) {
+      e.preventDefault();
+      const $divider = $('.breadcrumb div.divider');
+      const value = $section.last().find('a').text();
+      $(this).val(value + $(this).val());
+      this.setSelectionRange(value.length, value.length);
+      $section.last().remove();
+      $divider.last().remove();
+      joinTreePath($(this));
+    }
+  });
 
   const $editArea = $('.repository.editor textarea#edit_area');
   if (!$editArea.length) return;