From fd094eea959a235654b7591da066dcbbee11fc25 Mon Sep 17 00:00:00 2001
From: silverwind <me@silverwind.io>
Date: Sun, 26 Jan 2020 09:17:25 +0100
Subject: [PATCH] fix commit view JS features, reimplement folding (#9968)

* fix commit view JS features, reimplement folding

File content folding was not working so I reimplemented it in a saner
way. Then I noticed the issue was actually because of missing JS
libraries (seen on the console of every commit with error
'SimpleMDE is not defined').

Fixed the libraries. I think the reimplementation is worth to keep.

* add .closest polyfill

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
---
 routers/repo/commit.go        |  2 ++
 templates/repo/diff/box.tmpl  |  4 ++--
 web_src/js/index.js           | 18 +++++++-----------
 web_src/js/polyfills.js       | 17 +++++++++++++++++
 web_src/less/_repository.less |  8 ++++++++
 5 files changed, 36 insertions(+), 13 deletions(-)
 create mode 100644 web_src/js/polyfills.js

diff --git a/routers/repo/commit.go b/routers/repo/commit.go
index cb9727fccc..2e6cd76bb3 100644
--- a/routers/repo/commit.go
+++ b/routers/repo/commit.go
@@ -206,6 +206,8 @@ func FileHistory(ctx *context.Context) {
 func Diff(ctx *context.Context) {
 	ctx.Data["PageIsDiff"] = true
 	ctx.Data["RequireHighlightJS"] = true
+	ctx.Data["RequireSimpleMDE"] = true
+	ctx.Data["RequireTribute"] = true
 
 	userName := ctx.Repo.Owner.Name
 	repoName := ctx.Repo.Repository.Name
diff --git a/templates/repo/diff/box.tmpl b/templates/repo/diff/box.tmpl
index 9b0738b1b7..15ba387dca 100644
--- a/templates/repo/diff/box.tmpl
+++ b/templates/repo/diff/box.tmpl
@@ -80,7 +80,7 @@
 				</div>
 			{{else}}
 				<div class="diff-file-box diff-box file-content {{TabSizeClass $.Editorconfig $file.Name}}" id="diff-{{.Index}}">
-					<h4 class="ui top attached normal header">
+					<h4 class="diff-file-header ui top attached normal header">
 						{{$isImage := false}}
 						{{if $file.IsDeleted}}
 							{{$isImage = (call $.IsImageFileInBase $file.Name)}}
@@ -111,7 +111,7 @@
 							{{end}}
 						{{end}}
 					</h4>
-					<div class="ui attached unstackable table segment">
+					<div class="diff-file-body ui attached unstackable table segment">
 						{{if ne $file.Type 4}}
 							<div class="file-body file-code code-view has-context-menu code-diff {{if $.IsSplitStyle}}code-diff-split{{else}}code-diff-unified{{end}}">
 								<table>
diff --git a/web_src/js/index.js b/web_src/js/index.js
index f89750e933..12c46903a6 100644
--- a/web_src/js/index.js
+++ b/web_src/js/index.js
@@ -3,6 +3,7 @@
 /* exported toggleDeadlineForm, setDeadline, updateDeadline, deleteDependencyModal, cancelCodeComment, onOAuthLoginClick */
 
 import './publicPath.js';
+import './polyfills.js';
 import './gitGraphLoader.js';
 import './semanticDropdown.js';
 import initContextPopups from './features/contextPopup';
@@ -2109,17 +2110,12 @@ function initCodeView() {
       }
     }).trigger('hashchange');
   }
-  $('.ui.fold-code').on('click', (e) => {
-    const $foldButton = $(e.target);
-    if ($foldButton.hasClass('fa-chevron-down')) {
-      $(e.target).parent().next().slideUp('fast', () => {
-        $foldButton.removeClass('fa-chevron-down').addClass('fa-chevron-right');
-      });
-    } else {
-      $(e.target).parent().next().slideDown('fast', () => {
-        $foldButton.removeClass('fa-chevron-right').addClass('fa-chevron-down');
-      });
-    }
+  $('.fold-code').on('click', ({ target }) => {
+    const box = target.closest('.file-content');
+    const folded = box.dataset.folded !== 'true';
+    target.classList.add(`fa-chevron-${folded ? 'right' : 'down'}`);
+    target.classList.remove(`fa-chevron-${folded ? 'down' : 'right'}`);
+    box.dataset.folded = String(folded);
   });
   function insertBlobExcerpt(e) {
     const $blob = $(e.target);
diff --git a/web_src/js/polyfills.js b/web_src/js/polyfills.js
new file mode 100644
index 0000000000..0063b6d253
--- /dev/null
+++ b/web_src/js/polyfills.js
@@ -0,0 +1,17 @@
+// compat: IE11
+if (!Element.prototype.matches) {
+  Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
+}
+
+// compat: IE11
+if (!Element.prototype.closest) {
+  Element.prototype.closest = function (s) {
+    let el = this;
+
+    do {
+      if (el.matches(s)) return el;
+      el = el.parentElement || el.parentNode;
+    } while (el !== null && el.nodeType === 1);
+    return null;
+  };
+}
diff --git a/web_src/less/_repository.less b/web_src/less/_repository.less
index a1b55e86aa..5c05499af7 100644
--- a/web_src/less/_repository.less
+++ b/web_src/less/_repository.less
@@ -2524,3 +2524,11 @@ td.blob-excerpt {
 .title_wip_desc {
     margin-top: 1em;
 }
+
+.diff-file-box[data-folded="true"] .diff-file-body {
+    visibility: hidden;
+}
+
+.diff-file-box[data-folded="true"] .diff-file-header {
+    border-radius: 0.28571429rem !important;
+}