Răsfoiți Sursa

prototype keyboard trap toggle

- needs updating all language files
- replicate changes to all templates
El RIDO 1 an în urmă
părinte
comite
544c4d2f5f
6 a modificat fișierele cu 41 adăugiri și 13 ștergeri
  1. 1 0
      CHANGELOG.md
  2. 4 2
      i18n/en.json
  3. 1 1
      js/dark-mode-switch.js
  4. 24 5
      js/privatebin.js
  5. 1 1
      lib/Configuration.php
  6. 10 4
      tpl/bootstrap5.php

+ 1 - 0
CHANGELOG.md

@@ -1,6 +1,7 @@
 # PrivateBin version history
 
 ## 1.7.6 (not yet released)
+* CHANGED: Allow toggling tab-key-support using `[Ctrl]+[m]` or `[Esc]` in textarea for keyboard navigation (#1386)
 
 ## 1.7.5 (2024-11-16)
 * ADDED: Allow non persistent SQL connections, if configured (#1394)

+ 4 - 2
i18n/en.json

@@ -151,7 +151,7 @@
     "server error or not responding": "server error or not responding",
     "Could not post comment: %s": "Could not post comment: %s",
     "Sending paste…": "Sending paste…",
-    "Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>": "Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>",
+    "Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit <kbd>Ctrl</kbd>+<kbd>c</kbd> to copy)</span>": "Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit <kbd>Ctrl</kbd>+<kbd>c</kbd> to copy)</span>",
     "Delete data": "Delete data",
     "Could not create paste: %s": "Could not create paste: %s",
     "Cannot decrypt paste: Decryption key missing in URL (Did you use a redirector or an URL shortener which strips part of the URL?)": "Cannot decrypt paste: Decryption key missing in URL (Did you use a redirector or an URL shortener which strips part of the URL?)",
@@ -220,5 +220,7 @@
     "Dark Mode": "Dark Mode",
     "Error compressing paste, due to missing WebAssembly support.": "Error compressing paste, due to missing WebAssembly support.",
     "Error decompressing paste, your browser does not support WebAssembly. Please use another browser to view this paste.": "Error decompressing paste, your browser does not support WebAssembly. Please use another browser to view this paste.",
-    "Start over": "Start over"
+    "Start over": "Start over",
+    "Paste text": "Paste text",
+    "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
 }

+ 1 - 1
js/dark-mode-switch.js

@@ -68,7 +68,7 @@
     } else {
       delStoredPrettifyTheme()
     }
-    const toggle = document.querySelector('#bd-theme')
+    const toggle = document.getElementById('bd-theme')
     const theme = getStoredPreferredTheme()
     setTheme(theme)
     toggle.checked = (theme === 'dark')

+ 24 - 5
js/privatebin.js

@@ -2092,7 +2092,7 @@ jQuery.PrivateBin = (function($, RawDeflate) {
         {
             I18n._(
                 $('#pastelink'),
-                'Your paste is <a id="pasteurl" href="%s">%s</a> <span id="copyhint">(Hit [Ctrl]+[c] to copy)</span>',
+                'Your paste is <a id="pasteurl" href="%s">%s</a> <span id="copyhint">(Hit <kbd>Ctrl</kbd>+<kbd>c</kbd> to copy)</span>',
                 url, url
             );
             // save newly created element
@@ -2394,7 +2394,8 @@ jQuery.PrivateBin = (function($, RawDeflate) {
             $messagePreview,
             $messagePreviewParent,
             $message,
-            isPreview = false;
+            isPreview = false,
+            isTabSupported = true;
 
         /**
          * support input of tab character
@@ -2406,9 +2407,14 @@ jQuery.PrivateBin = (function($, RawDeflate) {
          */
         function supportTabs(event)
         {
-            const keyCode = event.keyCode || event.which;
+            // support disabling tab support using [Esc] and [Ctrl]+[m]
+            if (event.key === 'Escape' || (event.ctrlKey && event.key === 'm')) {
+                toggleTabSupport();
+                document.getElementById('message-tab').checked = isTabSupported;
+                event.preventDefault();
+            }
             // tab was pressed
-            if (keyCode === 9) {
+            else if (isTabSupported && event.key === 'Tab') {
                 // get caret position & selection
                 const val   = this.value,
                       start = this.selectionStart,
@@ -2422,6 +2428,18 @@ jQuery.PrivateBin = (function($, RawDeflate) {
             }
         }
 
+        /**
+         * toggle tab support in message textarea
+         *
+         * @name   Editor.toggleTabSupport
+         * @private
+         * @function
+         */
+        function toggleTabSupport()
+        {
+            isTabSupported = !isTabSupported;
+        }
+
         /**
          * view the Editor tab
          *
@@ -2599,6 +2617,7 @@ jQuery.PrivateBin = (function($, RawDeflate) {
 
             // bind events
             $message.keydown(supportTabs);
+            $('#message-tab').change(toggleTabSupport);
 
             // bind click events to tab switchers (a), and save parents (li)
             $messageEdit = $('#messageedit').click(viewEditor);
@@ -3768,7 +3787,7 @@ jQuery.PrivateBin = (function($, RawDeflate) {
 
         /**
          * Clear the password input in the top navigation
-         * 
+         *
          * @name TopNav.clearPasswordInput
          * @function
          */

+ 1 - 1
lib/Configuration.php

@@ -108,7 +108,7 @@ class Configuration
             'js/kjua-0.9.0.js'       => 'sha512-CVn7af+vTMBd9RjoS4QM5fpLFEOtBCoB0zPtaqIDC7sF4F8qgUSRFQQpIyEDGsr6yrjbuOLzdf20tkHHmpaqwQ==',
             'js/legacy.js'           => 'sha512-LYos+qXHIRqFf5ZPNphvtTB0cgzHUizu2wwcOwcwz/VIpRv9lpcBgPYz4uq6jx0INwCAj6Fbnl5HoKiLufS2jg==',
             'js/prettify.js'         => 'sha512-puO0Ogy++IoA2Pb9IjSxV1n4+kQkKXYAEUtVzfZpQepyDPyXk8hokiYDS7ybMogYlyyEIwMLpZqVhCkARQWLMg==',
-            'js/privatebin.js'       => 'sha512-JUj/Sbl/bMHlIoIUT1U9e89JU33fDBxCxLSGxwwaeydBFXOBHyfdF7hwSIjgbPxb4d9CO7CSe4meouTIRMy8Vg==',
+            'js/privatebin.js'       => 'sha512-V0coVhQkhG/bSJcZAMOoR+9Ztak1hElXiOtcrR4zZYm4MwScgytYHPVeZa6ZVKf+Mxp5TtIvM+NcYixP33Yliw==',
             'js/purify-3.1.7.js'     => 'sha512-LegvqULiMtOfboJZw9MpETN/b+xnLRXZI90gG7oIFHW+yAeHmKvRtEUbiMFx2WvUqQoL9XB3gwU+hWXUT0X+8A==',
             'js/rawinflate-0.3.js'   => 'sha512-g8uelGgJW9A/Z1tB6Izxab++oj5kdD7B4qC7DHwZkB6DGMXKyzx7v5mvap2HXueI2IIn08YlRYM56jwWdm2ucQ==',
             'js/showdown-2.1.0.js'   => 'sha512-WYXZgkTR0u/Y9SVIA4nTTOih0kXMEd8RRV6MLFdL6YU8ymhR528NLlYQt1nlJQbYz4EW+ZsS0fx1awhiQJme1Q==',

+ 10 - 4
tpl/bootstrap5.php

@@ -88,7 +88,7 @@ endif;
 						<form id="passwordform" role="form">
 							<div class="mb-3">
 								<label for="passworddecrypt"><svg width="16" height="16" fill="currentColor" aria-hidden="true"><use href="img/bootstrap-icons.svg#eye" /></svg> <?php echo I18n::_('Please enter the password for this paste:') ?></label>
-								<input id="passworddecrypt" type="password" class="form-control" placeholder="<?php echo I18n::_('Enter password') ?>" required="required">
+								<input id="passworddecrypt" type="password" class="form-control" placeholder="<?php echo I18n::_('Enter password') ?>" required="required" />
 							</div>
 							<button type="submit" class="btn btn-success btn-block"><svg width="16" height="16" fill="currentColor" aria-hidden="true"><use href="img/bootstrap-icons.svg#power" /></svg> <?php echo I18n::_('Decrypt') ?></button>
 						</form>
@@ -249,7 +249,7 @@ if ($PASSWORD) :
 ?>
 						<li class="nav-item">
 							<div id="password" class="navbar-form hidden">
-								<input type="password" id="passwordinput" placeholder="<?php echo I18n::_('Password (recommended)'); ?>" class="form-control" size="23" />
+								<input type="password" id="passwordinput" placeholder="<?php echo I18n::_('Password (recommended)'); ?>" aria-label="<?php echo I18n::_('Password (recommended)'); ?>" class="form-control" size="23" />
 							</div>
 						</li>
 <?php
@@ -296,7 +296,7 @@ endif;
 					<ul class="navbar-nav gap-2">
 						<li class="nav-item">
 							<div class="form-check form-switch navbar-text">
-								<input id="bd-theme" type="checkbox" class="form-check-input">
+								<input id="bd-theme" type="checkbox" class="form-check-input" />
 								<label for="bd-theme" class="form-check-label"><?php echo I18n::_('Dark Mode'); ?></label>
 							</div>
 						</li>
@@ -439,7 +439,13 @@ endif;
 						<pre id="prettyprint" class="card-body col-md-12 prettyprint linenums:1"></pre>
 					</div>
 					<div id="plaintext" class="col-md-12 hidden"></div>
-					<p class="col-md-12"><textarea id="message" name="message" cols="80" rows="25" class="form-control hidden"></textarea></p>
+					<p class="col-md-12"><textarea id="message" name="message" cols="80" rows="25" aria-label="<?php echo I18n::_('Paste text'); ?>" class="form-control hidden"></textarea></p>
+					<p class="col-md-12" id="message-controls">
+						<input id="message-tab" type="checkbox" class="form-check-input" checked="checked" />
+						<label for="message-tab" class="form-check-label">
+							<?php echo I18n::_('Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)'); ?>
+						</label>
+					</p>
 				</article>
 			</section>
 			<section class="container-fluid">