Răsfoiți Sursa

Merge pull request #2040 from mvanhorn/fix/1788-privatebin-navbar-wrapping

fix: wrap crowded Bootstrap 5 navbar controls
El RIDO 1 lună în urmă
părinte
comite
215680e27f
5 a modificat fișierele cu 110 adăugiri și 3 ștergeri
  1. 8 0
      js/privatebin.js
  2. 88 0
      js/test/TopNav.js
  3. 1 1
      lib/Configuration.php
  4. 2 2
      tpl/bootstrap5.php
  5. 11 0
      tst/ViewTest.php

+ 8 - 0
js/privatebin.js

@@ -4383,6 +4383,11 @@ window.PrivateBin = (function () {
          */
         me.showRetryButton = function () {
             retryButton.classList.remove('hidden');
+            // The Bootstrap 5 template gives Retry its own list item. That item
+            // still takes a flex gap while only the button is hidden.
+            if (Helper.isBootstrap5()) {
+                retryButton.parentElement.classList.remove('hidden');
+            }
         };
 
         /**
@@ -4393,6 +4398,9 @@ window.PrivateBin = (function () {
          */
         me.hideRetryButton = function () {
             retryButton.classList.add('hidden');
+            if (Helper.isBootstrap5()) {
+                retryButton.parentElement.classList.add('hidden');
+            }
         };
 
         /**

+ 88 - 0
js/test/TopNav.js

@@ -856,6 +856,94 @@ describe('TopNav', function () {
         );
     });
 
+    describe('showRetryButton & hideRetryButton', function () {
+        afterEach(function () {
+            delete global.bootstrap;
+            cleanup();
+        });
+
+        it(
+            'shows and hides the Bootstrap 5 retry button with its list item and runs the callback once',
+            function () {
+                cleanup();
+                global.bootstrap = {};
+                document.documentElement.innerHTML =
+                    '<nav><div id="navbar"><ul class="navbar-nav">' +
+                    '<li class="nav-item hidden"><button id="retrybutton" ' +
+                    'type="button" class="hidden">Retry</button></li>' +
+                    '<li><button id="newbutton" type="button">New</button>' +
+                    '</li></ul></div></nav>';
+                PrivateBin.TopNav.init();
+                let calls = 0;
+                PrivateBin.TopNav.setRetryCallback(function () {
+                    calls++;
+                });
+                const retryItem = query('#retrybutton').parentElement;
+
+                assert.ok(query('#retrybutton').classList.contains('hidden'));
+                assert.ok(retryItem.classList.contains('hidden'));
+
+                PrivateBin.TopNav.showRetryButton();
+                assert.ok(!query('#retrybutton').classList.contains('hidden'));
+                assert.ok(!retryItem.classList.contains('hidden'));
+
+                query('#retrybutton').click();
+                assert.strictEqual(calls, 1);
+
+                PrivateBin.TopNav.hideRetryButton();
+                assert.ok(query('#retrybutton').classList.contains('hidden'));
+                assert.ok(retryItem.classList.contains('hidden'));
+
+                PrivateBin.TopNav.showRetryButton();
+                PrivateBin.TopNav.hideRetryButton();
+                assert.ok(query('#retrybutton').classList.contains('hidden'));
+                assert.ok(retryItem.classList.contains('hidden'));
+                assert.ok(!query('#newbutton').classList.contains('hidden'));
+                assert.strictEqual(calls, 1);
+            }
+        );
+
+        it(
+            'toggles only the retry button on legacy Bootstrap 3 and page templates',
+            function () {
+                cleanup();
+                delete global.bootstrap;
+                document.documentElement.innerHTML =
+                    '<nav><div id="navbar"><ul class="nav navbar-nav"><li>' +
+                    '<button id="retrybutton" type="button" class="hidden">' +
+                    'Retry</button><button id="newbutton" type="button">' +
+                    'New</button></li></ul></div></nav>';
+                PrivateBin.TopNav.init();
+                let calls = 0;
+                PrivateBin.TopNav.setRetryCallback(function () {
+                    calls++;
+                });
+                const retryItem = query('#retrybutton').parentElement;
+
+                assert.ok(query('#retrybutton').classList.contains('hidden'));
+                assert.ok(!retryItem.classList.contains('hidden'));
+
+                PrivateBin.TopNav.showRetryButton();
+                assert.ok(!query('#retrybutton').classList.contains('hidden'));
+                assert.ok(!retryItem.classList.contains('hidden'));
+                assert.ok(!query('#newbutton').classList.contains('hidden'));
+
+                query('#retrybutton').click();
+                assert.strictEqual(calls, 1);
+
+                PrivateBin.TopNav.hideRetryButton();
+                assert.ok(query('#retrybutton').classList.contains('hidden'));
+                assert.ok(!retryItem.classList.contains('hidden'));
+                assert.ok(!query('#newbutton').classList.contains('hidden'));
+
+                PrivateBin.TopNav.showRetryButton();
+                PrivateBin.TopNav.hideRetryButton();
+                assert.ok(query('#retrybutton').classList.contains('hidden'));
+                assert.strictEqual(calls, 1);
+            }
+        );
+    });
+
     describe('rawText', function () {
         before(function () {
             cleanup();

+ 1 - 1
lib/Configuration.php

@@ -124,7 +124,7 @@ class Configuration
             'js/kjua-0.10.0.js'      => 'sha512-BYj4xggowR7QD150VLSTRlzH62YPfhpIM+b/1EUEr7RQpdWAGKulxWnOvjFx1FUlba4m6ihpNYuQab51H6XlYg==',
             'js/legacy.js'           => 'sha512-pRofxsrf5UItjiP22Dcjh3FAcBjF/n7h8U9/W5xqJk17U0N2U1oajhXypq/omo9jhwS1iVGOhWrRepoPeFns+w==',
             'js/prettify.js'         => 'sha512-puO0Ogy++IoA2Pb9IjSxV1n4+kQkKXYAEUtVzfZpQepyDPyXk8hokiYDS7ybMogYlyyEIwMLpZqVhCkARQWLMg==',
-            'js/privatebin.js'       => 'sha512-TESkKT3BI8chkAJUlFgIJxnBG/mtgHAKJk0sEMX3l554ohQvEyNjLl5ZFeVhT6jvW3mFIxengHfkc12+MokyJA==',
+            'js/privatebin.js'       => 'sha512-ECxau81icFK+pB7VsyYoxEMXrERcuE7ILhtTD6dedfsHZfL59+4f57SSvvpwIy/CZ665jyvtYZ9FBDZ1Lx3DAQ==',
             'js/purify-3.4.12.js'    => 'sha512-Akf6HnAJZm0sWWWI4gp2GYff0NDnHUB02XJE5S7Hdq/Z5xtMjkuFacsDA8ZtViv1gi+onBxMhEMIaGyQeGxBng==',
             'js/showdown-2.1.0.js'   => 'sha512-WYXZgkTR0u/Y9SVIA4nTTOih0kXMEd8RRV6MLFdL6YU8ymhR528NLlYQt1nlJQbYz4EW+ZsS0fx1awhiQJme1Q==',
             'js/zlib-1.3.2.js'       => 'sha512-RAhJgxg9siMIA8ky4c10Rc2zUgnK80olHB8Tt1IOYWY4Eh1WmrviQkDn+sgBlb38ZHq3tzufGC41kP360gmosQ==',

+ 2 - 2
tpl/bootstrap5.php

@@ -158,12 +158,12 @@ endif;
 					<span class="navbar-toggler-icon"></span>
 				</button>
 				<div id="navbar" class="collapse navbar-collapse">
-					<ul class="navbar-nav me-auto gap-2 align-items-lg-center align-items-stretch">
+					<ul class="navbar-nav me-auto gap-2 align-items-lg-center align-items-stretch flex-wrap">
 						<li id="loadingindicator" class="navbar-text hidden me-auto">
 							<svg width="16" height="16" fill="currentColor" aria-hidden="true"><use href="img/bootstrap-icons.svg#clock" /></svg>
 							<?php echo I18n::_('Loading…'), PHP_EOL; ?>
 						</li>
-						<li class="nav-item d-flex flex-lg-row flex-column">
+						<li class="nav-item d-flex flex-lg-row flex-column hidden">
 							<button id="retrybutton" type="button" class="reloadlink hidden btn btn-primary d-flex justify-content-center align-items-center gap-1">
 								<svg width="16" height="16" fill="currentColor" aria-hidden="true"><use href="img/bootstrap-icons.svg#repeat" /></svg> <?php echo I18n::_('Retry'), PHP_EOL; ?>
 							</button>

+ 11 - 0
tst/ViewTest.php

@@ -114,6 +114,17 @@ class ViewTest extends TestCase
         }
     }
 
+    public function testBootstrap5RetryButtonStartsHiddenInItsListItem()
+    {
+        $this->assertArrayHasKey('bootstrap5', $this->_content);
+        $this->assertMatchesRegularExpression(
+            '#<li class="nav-item d-flex flex-lg-row flex-column hidden">\s*'
+            . '<button id="retrybutton" type="button" class="reloadlink hidden\b#',
+            $this->_content['bootstrap5'],
+            'bootstrap5: retry button stays inside an initially hidden list item'
+        );
+    }
+
     public function testMissingTemplate()
     {
         $test = new View;