From c0777279fec4e08bc13665f0e862bfc4f164a5e3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Oto=20=C5=A0=C5=A5=C3=A1va?= <oto.stava@gmail.com>
Date: Sun, 24 Nov 2024 16:41:09 +0100
Subject: [PATCH 1/2] Fix wiki search overflowing on wide screens (#6047)

Confine the search menu to be at most the width of the page, or 80% of
the viewport width, whichever is smaller. To do this, introduce a new
`--container-width` variable for the descendant elements of
`.ui.container` to be able to access.

Also update the relevant e2e test: add a long 'lorem ipsum' page, add a
search for it, parameterize the width.
---
 routers/web/repo/wiki_test.go                 |   4 +--
 templates/repo/wiki/search.tmpl               |   2 +-
 tests/e2e/repo-wiki.test.e2e.ts               |  31 +++++++++++-------
 .../53/0ab3e043bf2295fd1cec3129bf203a4349597a | Bin 0 -> 236 bytes
 .../bf/29486462016efad8872371078932d8c2cb5253 | Bin 0 -> 1075 bytes
 .../c0/b5b381e2df9f66d11e8c95fe7467b8fb7f3e4e | Bin 0 -> 1064 bytes
 .../d4/9ac742d44063dcf69d4e0afe725813b777dd89 |   1 +
 .../user2/repo1.wiki.git/refs/heads/master    |   2 +-
 tests/integration/api_wiki_test.go            |  29 ++++++++++++++--
 web_src/css/modules/container.css             |  21 ++++++++----
 10 files changed, 65 insertions(+), 25 deletions(-)
 create mode 100644 tests/gitea-repositories-meta/user2/repo1.wiki.git/objects/53/0ab3e043bf2295fd1cec3129bf203a4349597a
 create mode 100644 tests/gitea-repositories-meta/user2/repo1.wiki.git/objects/bf/29486462016efad8872371078932d8c2cb5253
 create mode 100644 tests/gitea-repositories-meta/user2/repo1.wiki.git/objects/c0/b5b381e2df9f66d11e8c95fe7467b8fb7f3e4e
 create mode 100644 tests/gitea-repositories-meta/user2/repo1.wiki.git/objects/d4/9ac742d44063dcf69d4e0afe725813b777dd89

diff --git a/routers/web/repo/wiki_test.go b/routers/web/repo/wiki_test.go
index 00a35a5da0..47bad6d8e0 100644
--- a/routers/web/repo/wiki_test.go
+++ b/routers/web/repo/wiki_test.go
@@ -86,7 +86,7 @@ func TestWiki(t *testing.T) {
 	Wiki(ctx)
 	assert.EqualValues(t, http.StatusOK, ctx.Resp.Status())
 	assert.EqualValues(t, "Home", ctx.Data["Title"])
-	assertPagesMetas(t, []string{"Home", "Page With Image", "Page With Spaced Name", "Unescaped File"}, ctx.Data["Pages"])
+	assertPagesMetas(t, []string{"Home", "Long Page", "Page With Image", "Page With Spaced Name", "Unescaped File"}, ctx.Data["Pages"])
 }
 
 func TestWikiPages(t *testing.T) {
@@ -96,7 +96,7 @@ func TestWikiPages(t *testing.T) {
 	contexttest.LoadRepo(t, ctx, 1)
 	WikiPages(ctx)
 	assert.EqualValues(t, http.StatusOK, ctx.Resp.Status())
-	assertPagesMetas(t, []string{"Home", "Page With Image", "Page With Spaced Name", "Unescaped File"}, ctx.Data["Pages"])
+	assertPagesMetas(t, []string{"Home", "Long Page", "Page With Image", "Page With Spaced Name", "Unescaped File"}, ctx.Data["Pages"])
 }
 
 func TestNewWiki(t *testing.T) {
diff --git a/templates/repo/wiki/search.tmpl b/templates/repo/wiki/search.tmpl
index 1b774908d0..5795b399af 100644
--- a/templates/repo/wiki/search.tmpl
+++ b/templates/repo/wiki/search.tmpl
@@ -1,6 +1,6 @@
 {{if .Results}}
 	{{range .Results}}
-		<a class="item tw-max-w-[80vw]" href="{{$.RepoLink}}/wiki/{{.Filename}}">
+		<a class="item tw-max-w-[min(80vw,var(--container-width))]" href="{{$.RepoLink}}/wiki/{{.Filename}}">
 			<b class="tw-block tw-mb-2 tw-whitespace-break-spaces">{{.Title}}</b>
 			{{range .LineCodes}}
 				<p class="tw-my-0 tw-whitespace-break-spaces">{{.}}</p>
diff --git a/tests/e2e/repo-wiki.test.e2e.ts b/tests/e2e/repo-wiki.test.e2e.ts
index c1b48dabf2..f32fe3fc91 100644
--- a/tests/e2e/repo-wiki.test.e2e.ts
+++ b/tests/e2e/repo-wiki.test.e2e.ts
@@ -6,17 +6,26 @@
 import {expect} from '@playwright/test';
 import {test} from './utils_e2e.ts';
 
-test(`Search for long titles and test for no overflow`, async ({page}, workerInfo) => {
-  test.skip(workerInfo.project.name === 'Mobile Safari', 'Fails as always, see https://codeberg.org/forgejo/forgejo/pulls/5326#issuecomment-2313275');
-  await page.goto('/user2/repo1/wiki');
-  await page.getByPlaceholder('Search wiki').fill('spaces');
-  await page.getByPlaceholder('Search wiki').click();
-  // workaround: HTMX listens on keyup events, playwright's fill only triggers the input event
-  // so we manually "type" the last letter
-  await page.getByPlaceholder('Search wiki').dispatchEvent('keyup');
-  // timeout is necessary because HTMX search could be slow
-  await expect(page.locator('#wiki-search a[href]')).toBeInViewport({ratio: 1});
-});
+for (const searchTerm of ['space', 'consectetur']) {
+  for (const width of [null, 2560, 4000]) {
+    test(`Search for '${searchTerm}' and test for no overflow ${width && `on ${width}-wide viewport` || ''}`, async ({page, viewport}, workerInfo) => {
+      test.skip(workerInfo.project.name === 'Mobile Safari', 'Fails as always, see https://codeberg.org/forgejo/forgejo/pulls/5326#issuecomment-2313275');
+
+      await page.setViewportSize({
+        width: width ?? viewport.width,
+        height: 1440, // We're testing that we fit horizontally - vertical scrolling is fine.
+      });
+      await page.goto('/user2/repo1/wiki');
+      await page.getByPlaceholder('Search wiki').fill(searchTerm);
+      await page.getByPlaceholder('Search wiki').click();
+      // workaround: HTMX listens on keyup events, playwright's fill only triggers the input event
+      // so we manually "type" the last letter
+      await page.getByPlaceholder('Search wiki').dispatchEvent('keyup');
+      // timeout is necessary because HTMX search could be slow
+      await expect(page.locator('#wiki-search a[href]')).toBeInViewport({ratio: 1});
+    });
+  }
+}
 
 test(`Search results show titles (and not file names)`, async ({page}, workerInfo) => {
   test.skip(workerInfo.project.name === 'Mobile Safari', 'Fails as always, see https://codeberg.org/forgejo/forgejo/pulls/5326#issuecomment-2313275');
diff --git a/tests/gitea-repositories-meta/user2/repo1.wiki.git/objects/53/0ab3e043bf2295fd1cec3129bf203a4349597a b/tests/gitea-repositories-meta/user2/repo1.wiki.git/objects/53/0ab3e043bf2295fd1cec3129bf203a4349597a
new file mode 100644
index 0000000000000000000000000000000000000000..eeae5d2b64678efab302d050246ab22c6494f357
GIT binary patch
literal 236
zcmV<I02BXs0V^p=O;s?mFlR6{FfcPQQSivmP1VayVR+T_r@efUH~XP%EAKClN_3cu
z?N&pT_~hrM>josIgVpWV^hil!%=>ktUAd6G)9A*b(?P*dbs#0W;h7~Fx}LdE)kd*L
ze!MjCOUw8qYPM`{ysY0<o5dKag9{RqQ&V*P5+N=r`jZrRCZ%tpj{w75LudI#kGp3n
zK=p*?r4}bA7Nn*qxMk+xbhe2B5GZ7V+)&I=a&^IV+nqb#SFN1hw|&9P4gDck;-IEw
m6{M!?Wfi0|6i$@>(w=r)LR8`)JEtJy{M`&2{{R5YC2$`_g?3v2

literal 0
HcmV?d00001

diff --git a/tests/gitea-repositories-meta/user2/repo1.wiki.git/objects/bf/29486462016efad8872371078932d8c2cb5253 b/tests/gitea-repositories-meta/user2/repo1.wiki.git/objects/bf/29486462016efad8872371078932d8c2cb5253
new file mode 100644
index 0000000000000000000000000000000000000000..ab5b5954cb4a8a98c381896b0a2aafce86201725
GIT binary patch
literal 1075
zcmV-31kC$*0ku}kj^s8B%(=gUz+M|ZBv|CU$O8zl8%z*j@3hSBVIWH$J&b&Qijr*4
zd_Ycv>6S!Rv8vd!k2C%F)6buO_(Wf0c+v|$<#ziTldPm$t}89k$3$5R@has`E`}_w
zNU4c<(M_{cTokWmqF<}#^DG5<t3pAupXiGO;XpAtrImB$JFU@s9M^>;7iw?UlxwCf
z<|;|Z>$7^E=#Nk&E$BrG?t00U7p4dL$;6HrUyo+Dq^ms{@NIQE*F4ehH9H~vTYv*K
zQA~waz0)rKJV!~bv^*Z_)UZjN=r6!A2xzetu?yB~mUWY4RP5X^)Ix6ty<`2x6|YgM
zC86n}!Rb;1uJNW4?)Kb+odP^gy;TM<FZz&xG9dBK8XSlU3<`k6-b6Q@c$_ZN?beQX
z#+X0}+YtrZjsU@7B<&IJnKtoWKu<%#UXNlcKCJ6RzZFIG<Dp=M?TAr6x+O0WqdHk1
zpgiaVT_6N-*wrz}j&P#C1w*axpa-2_CmO^ws$8FSTr~FcA%+WMm)%4!ubhDarI`My
zxx@x@?F2t0bs)5Pc9OUd27$UwctefsTwODycc6rdYrd0}JLsbJ*+k!U=M}X^Z{tsw
z;U()WNl~zOyL}mq?htq2f@$tr*u;fF(j&nbiZNUdU&47pR$gaG9noI>Rtp#DYJWmq
z17w8|?q~DBx5ZQ#y1&zCWE6!>1(W+0)2ts{>S0#{WyUrAP@8j~Ab5amc1~&(n~^d<
zwEzk%JJ20=Y%1gA>fLDGqpxMdYp|6$>y)sDiGHbx=Vl}8wrI1S@os)y`5BlBJY;j&
zs^1k_A0PBlT*|>)9&tgu6=;?Ud{dNibQ&RQBoJ7{>v%6FSQSTxGwZA{M$9FFKKl$d
zl&!=}uL{+$L_lmlLQAGXdM4g=!Rev#ttK>VxpZQK`Nt)B!g-gAM^xQzFYg@(_wE)q
zbM*)Ut{D2bj!5!?kg#-V#i803ix|_o#s!|U!5q{hkPx(e^h4JLw+jp{^pN^g3}WcC
zOYor8OeYR_Ga>6S3_LT;d!T~L5=%DjEZ{~hb5c-jfg^kmo1@cX8w>@bqiEfthZZo0
zRRxg<EO>R;;}ZAj4RqCZO}L_Y;JE~dind-xx_)4ID7WVhG6EuBY`jRf6R%NjVR%gI
z>f(%z_B>*_OEbsC@{UGe9`HVdX}7p7gTn~eC(Zmv&h+(JJqG1eu0_;!fE|LghnX<G
zGsQ-*w1sC8aIKC9I>cs`6=JMs8Z;xX{I6PQ>4HQ$5)9MBVLGdyq8`&_sQR)dQV9Kh
ze<#&KGr}p@(uF2$p?shn!Z!cH_O{RuO^@FQWY3w=`)J3SzhD9Y+G}cmCq3AycMIZ|
titP+Fy<4zI!T&c3x`aE=O$P0!&e-p#;13fRe}}wnlZ*v&`wtf$X*!0Y2bBN-

literal 0
HcmV?d00001

diff --git a/tests/gitea-repositories-meta/user2/repo1.wiki.git/objects/c0/b5b381e2df9f66d11e8c95fe7467b8fb7f3e4e b/tests/gitea-repositories-meta/user2/repo1.wiki.git/objects/c0/b5b381e2df9f66d11e8c95fe7467b8fb7f3e4e
new file mode 100644
index 0000000000000000000000000000000000000000..0474927fd24d33ed559b6039277d6b3a5e125814
GIT binary patch
literal 1064
zcmV+@1lRj`0ku}m&f_)=>^V=t2MB!F0=+M`El{9aY*AqEw9MpVAxr-BW9;L1D9Lud
z2k0q?Ba58j%rLW$GkyB`mrp<a8I!D}TdpfD(Z@tt3-K!DPA-Nlu1Kkgc+pL>)9@tm
zS|<9nYCg|WkoPJSH2aA@OArnelT%tbXTH-Ky~lA~NOGZecTKrw+G4JfguFhh=ZXFZ
zMbd&^q~KjIx$?sFKtGw-5##64?3Q%3D+7M5PUo5@`n_f+gs%lSP!q*eXw^II;?HxG
z)Jn_ap-v5()QSEE9D{%sTM>J~dd;$Kl8lO-8-`lw-Jo}@U%BEoO0^_3T{JjdYQSr}
zsf4>-_h6?0k5liJ0nCd&B%lmP{Hq2Bq5^{gAhA2qO(!0w%XGW7Bc3rPP{MXZ!L}nn
za2QFu#CxVqycf{ZP_Wmd*oudBo#?lssD4}&tgsz1%15{4C1O-3>jRVrouCVZ01mr4
z2H6o#^p9Yu^#yv+`E8;>Ory&6S;s|VKObVaFm~BZ^zDr^FrXCEzcrWGV6L6uholaK
zHqTBH7s4P=w+U~kk)5k+hV%}UP;t$7vT_Gq)SgZBU3XqlYxFigx(qK_Z%K-Rz1!{c
zV04GL0~btl*TN<)43ZuR#!!smy7&^#6SDF;OX`UB>bF|BNLTw4>KY&`gm6Eb2fi()
z!qEMlMkAvrY$}-C*O+Gg;8G8}8YnZa>4(~!`vk!QWV3Tpqu7j;`Kbj^VA+B0uwzph
zCs*%A^B#RI8*YQG%vq;|HB9uSCZ3y(tlOf^dd9o?b>(MZD)5laVXJ;uXnj2BqqvlV
zyFB88cq`B>75Jto<>)j*)JPz(h}&^rOt31B3}@C^VT_nd0)6%jHk7TzOm7O+utY#?
zK0-^TLV70Nb;0SO@vSB_Y`Jt|gZalx@`Up)7mujA-M+m#4({D8ZszI{1Y9xn@j4>O
z3qr!ur4@&2TP$Ks>lzn$&IWT(k3d4u_R$Yr7rb3yXrYJHr(zI8r(J>vt!6rLz?%v2
zj$z=MVcr83T$Wg}ac2QHYMGOQVhbGMd)OSE9@}6j7#&6H7Cp3pIjky(L}0<K!ycEo
zPj8^Bwrj!_%>&ORKvcB#GSc+}!$Y|}caRYf`C{Wmx}A89atp&_T2~imY_#hU%Uzl|
zE|zyR0`q|PAxyi)Z5bR!z&>f_KXRt8&+0KKr*bW#t^@24q&>`p@tr9)f~74yi-2o&
zJkTLFtE>=XJ=35WdF3B!p`{BF=}0h44~OZjeu{cbm!ay*nn)q^_x(kxg=U0Pu%!!4
z*h2Y0JA`fih3##jADSNj5y-AHqxaE{HGjbb0JPWC{vtitsdo$Fmx}ESHN7lYq~QM>
i1zp0O=O%;pS7+?^Q}BlgjK4$Pwn@eUx%~%4bY-%3Q4Lf8

literal 0
HcmV?d00001

diff --git a/tests/gitea-repositories-meta/user2/repo1.wiki.git/objects/d4/9ac742d44063dcf69d4e0afe725813b777dd89 b/tests/gitea-repositories-meta/user2/repo1.wiki.git/objects/d4/9ac742d44063dcf69d4e0afe725813b777dd89
new file mode 100644
index 0000000000..9dc276f37d
--- /dev/null
+++ b/tests/gitea-repositories-meta/user2/repo1.wiki.git/objects/d4/9ac742d44063dcf69d4e0afe725813b777dd89
@@ -0,0 +1 @@
+x���n�@������*���Gj��mJ��C1���~R0�ӧi}�*�U����*gw>�H�˺��5�6}���3�)Sh��0�9�Tƨ�;2i2��-�^j��L�4wS�۪p�mSTȭ��\9V��1S�p"������|���Ǔ���.Z>�법us�u�G�63����)"9��G�޶.��.��O��� �#X�J$����	�?o<1�_�)n�/�~��6���cS��l<�X�iҖb3{@��B,g���	�����K|��E�[�0\���aW�ݢR�|��i{���xd������9<��ҏ�g>���KOv�"D�J�sE��؜z���[�_s!2ϡ�v%�e��o(��
\ No newline at end of file
diff --git a/tests/gitea-repositories-meta/user2/repo1.wiki.git/refs/heads/master b/tests/gitea-repositories-meta/user2/repo1.wiki.git/refs/heads/master
index 38984b12b7..c804802cbf 100644
--- a/tests/gitea-repositories-meta/user2/repo1.wiki.git/refs/heads/master
+++ b/tests/gitea-repositories-meta/user2/repo1.wiki.git/refs/heads/master
@@ -1 +1 @@
-0dca5bd9b5d7ef937710e056f575e86c0184ba85
+d49ac742d44063dcf69d4e0afe725813b777dd89
diff --git a/tests/integration/api_wiki_test.go b/tests/integration/api_wiki_test.go
index b930791969..e086fa26af 100644
--- a/tests/integration/api_wiki_test.go
+++ b/tests/integration/api_wiki_test.go
@@ -133,8 +133,31 @@ func TestAPIListWikiPages(t *testing.T) {
 			},
 		},
 		{
-			Title:   "Page With Image",
+			Title:   "Long Page",
 			HTMLURL: meta[1].HTMLURL,
+			SubURL:  "Long-Page",
+			LastCommit: &api.WikiCommit{
+				ID: "d49ac742d44063dcf69d4e0afe725813b777dd89",
+				Author: &api.CommitUser{
+					Identity: api.Identity{
+						Name:  "Oto Šťáva",
+						Email: "oto.stava@gmail.com",
+					},
+					Date: "2024-11-23T11:16:51Z",
+				},
+				Committer: &api.CommitUser{
+					Identity: api.Identity{
+						Name:  "Oto Šťáva",
+						Email: "oto.stava@gmail.com",
+					},
+					Date: "2024-11-23T11:16:51Z",
+				},
+				Message: "add long page\n",
+			},
+		},
+		{
+			Title:   "Page With Image",
+			HTMLURL: meta[2].HTMLURL,
 			SubURL:  "Page-With-Image",
 			LastCommit: &api.WikiCommit{
 				ID: "0cf15c3f66ec8384480ed9c3cf87c9e97fbb0ec3",
@@ -157,7 +180,7 @@ func TestAPIListWikiPages(t *testing.T) {
 		},
 		{
 			Title:   "Page With Spaced Name",
-			HTMLURL: meta[2].HTMLURL,
+			HTMLURL: meta[3].HTMLURL,
 			SubURL:  "Page-With-Spaced-Name",
 			LastCommit: &api.WikiCommit{
 				ID: "c10d10b7e655b3dab1f53176db57c8219a5488d6",
@@ -180,7 +203,7 @@ func TestAPIListWikiPages(t *testing.T) {
 		},
 		{
 			Title:   "Unescaped File",
-			HTMLURL: meta[3].HTMLURL,
+			HTMLURL: meta[4].HTMLURL,
 			SubURL:  "Unescaped-File",
 			LastCommit: &api.WikiCommit{
 				ID: "0dca5bd9b5d7ef937710e056f575e86c0184ba85",
diff --git a/web_src/css/modules/container.css b/web_src/css/modules/container.css
index f394d6c06d..95c71b207f 100644
--- a/web_src/css/modules/container.css
+++ b/web_src/css/modules/container.css
@@ -3,12 +3,14 @@
 
 .ui.container {
   display: block;
-  max-width: 100%;
+  --container-width: 100%;
+  max-width: var(--container-width);
 }
 
 @media (max-width: 767.98px) {
   .ui.ui.ui.container:not(.fluid) {
-    width: auto;
+    --container-width: auto;
+    width: var(--container-width);
     margin-left: 1em;
     margin-right: 1em;
   }
@@ -16,7 +18,8 @@
 
 @media (min-width: 768px) and (max-width: 991.98px) {
   .ui.ui.ui.container:not(.fluid) {
-    width: 723px;
+    --container-width: 723px;
+    width: var(--container-width);
     margin-left: auto;
     margin-right: auto;
   }
@@ -24,7 +27,8 @@
 
 @media (min-width: 992px) and (max-width: 1199.98px) {
   .ui.ui.ui.container:not(.fluid) {
-    width: 933px;
+    --container-width: 933px;
+    width: var(--container-width);
     margin-left: auto;
     margin-right: auto;
   }
@@ -32,14 +36,16 @@
 
 @media (min-width: 1200px) {
   .ui.ui.ui.container:not(.fluid) {
-    width: 1127px;
+    --container-width: 1127px;
+    width: var(--container-width);
     margin-left: auto;
     margin-right: auto;
   }
 }
 
 .ui.fluid.container {
-  width: 100%;
+  --container-width: 100%;
+  width: var(--container-width);
 }
 
 .ui[class*="center aligned"].container {
@@ -48,7 +54,8 @@
 
 /* overwrite width of containers inside the main page content div (div with class "page-content") */
 .page-content .ui.ui.ui.container:not(.fluid) {
-  width: 1280px;
+  --container-width: 1280px;
+  width: var(--container-width);
   max-width: calc(100% - calc(2 * var(--page-margin-x)));
   margin-left: auto;
   margin-right: auto;

From 767467b9ae2d27772a44041fe4d78725d2db6899 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Oto=20=C5=A0=C5=A5=C3=A1va?= <oto.stava@gmail.com>
Date: Sun, 24 Nov 2024 17:41:14 +0100
Subject: [PATCH 2/2] Cap wiki search width at 80% container width
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Co-Authored-By: Zuzana Slavíková <zuza.slavik@email.cz>
---
 templates/repo/wiki/search.tmpl | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/templates/repo/wiki/search.tmpl b/templates/repo/wiki/search.tmpl
index 5795b399af..7f4cb9c5a2 100644
--- a/templates/repo/wiki/search.tmpl
+++ b/templates/repo/wiki/search.tmpl
@@ -1,6 +1,6 @@
 {{if .Results}}
 	{{range .Results}}
-		<a class="item tw-max-w-[min(80vw,var(--container-width))]" href="{{$.RepoLink}}/wiki/{{.Filename}}">
+		<a class="item tw-max-w-[min(80vw,calc(0.8*var(--container-width)))]" href="{{$.RepoLink}}/wiki/{{.Filename}}">
 			<b class="tw-block tw-mb-2 tw-whitespace-break-spaces">{{.Title}}</b>
 			{{range .LineCodes}}
 				<p class="tw-my-0 tw-whitespace-break-spaces">{{.}}</p>