From 38403ea22f47e665e2a1987a4c606b0955400591 Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Mon, 14 Jun 2021 09:37:40 +0200 Subject: [PATCH] Implement new shortcuts: - "/" for Focus search bar - "ESC" - clear highlighted text Fixes #691. Co-authored-by: Jakob Lykke Andersen --- CHANGES | 3 + doc/usage/theming.rst | 15 +++- sphinx/themes/basic/static/doctools.js | 72 +++++++++++++------ .../basic/static/documentation_options.js_t | 3 +- sphinx/themes/basic/theme.conf | 1 + 5 files changed, 70 insertions(+), 24 deletions(-) diff --git a/CHANGES b/CHANGES index 54b09e55635..d6b9124faae 100644 --- a/CHANGES +++ b/CHANGES @@ -49,6 +49,9 @@ Features added references for readability with standalone readers * #9822 (and #9062), add new Intersphinx role :rst:role:`external` for explict lookup in the external projects, without resolving to the local project. +* #9337: HTML theme, add option ``enable_search_shortcuts`` that enables :kbd:'/' as + a Quick search shortcut and :kbd:`Esc` shortcut that + removes search highlighting. Bugs fixed ---------- diff --git a/doc/usage/theming.rst b/doc/usage/theming.rst index f66734b9671..5f541706151 100644 --- a/doc/usage/theming.rst +++ b/doc/usage/theming.rst @@ -158,9 +158,18 @@ These themes are: dimension string such as '70em' or '50%'. Use 'none' if you don't want a width limit. Defaults may depend on the theme (often 800px). - - **navigation_with_keys** (true or false): Allow navigating to the - previous/next page using the keyboard's left and right arrows. Defaults to - ``False``. + - **navigation_with_keys** (true or false): Allow navigating + with the following keyboard shortcuts: + + - :kbd:`Left arrow`: previous page + - :kbd:`Right arrow`: next page + + Defaults to ``False``. + + - **enable_search_shortcuts** (true or false): Allow jumping to the search box + with :kbd:`/` and allow removal of search highlighting with :kbd:`Esc`. + + Defaults to ``True``. - **globaltoc_collapse** (true or false): Only expand subsections of the current document in ``globaltoc.html`` diff --git a/sphinx/themes/basic/static/doctools.js b/sphinx/themes/basic/static/doctools.js index e509e48349c..e1bfd708b7f 100644 --- a/sphinx/themes/basic/static/doctools.js +++ b/sphinx/themes/basic/static/doctools.js @@ -154,9 +154,7 @@ var Documentation = { this.fixFirefoxAnchorBug(); this.highlightSearchWords(); this.initIndexTable(); - if (DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) { - this.initOnKeyListeners(); - } + this.initOnKeyListeners(); }, /** @@ -269,6 +267,13 @@ var Documentation = { window.history.replaceState({}, '', url); }, + /** + * helper function to focus on search bar + */ + focusSearchBar : function() { + $('input[name=q]').first().focus(); + }, + /** * make the url absolute */ @@ -291,27 +296,54 @@ var Documentation = { }, initOnKeyListeners: function() { + // only install a listener if it is really needed + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS && + !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) + return; + $(document).keydown(function(event) { var activeElementType = document.activeElement.tagName; // don't navigate when in search box, textarea, dropdown or button if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT' - && activeElementType !== 'BUTTON' && !event.altKey && !event.ctrlKey && !event.metaKey - && !event.shiftKey) { - switch (event.keyCode) { - case 37: // left - var prevHref = $('link[rel="prev"]').prop('href'); - if (prevHref) { - window.location.href = prevHref; - return false; - } - break; - case 39: // right - var nextHref = $('link[rel="next"]').prop('href'); - if (nextHref) { - window.location.href = nextHref; - return false; - } - break; + && activeElementType !== 'BUTTON') { + if (event.altKey || event.ctrlKey || event.metaKey) + return; + + if (!event.shiftKey) { + switch (event.key) { + case 'ArrowLeft': + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) + break; + var prevHref = $('link[rel="prev"]').prop('href'); + if (prevHref) { + window.location.href = prevHref; + return false; + } + break; + case 'ArrowRight': + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) + break; + var nextHref = $('link[rel="next"]').prop('href'); + if (nextHref) { + window.location.href = nextHref; + return false; + } + break; + case 'Escape': + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) + break; + Documentation.hideSearchWords(); + return false; + } + } + + // some keyboard layouts may need Shift to get / + switch (event.key) { + case '/': + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) + break; + Documentation.focusSearchBar(); + return false; } } }); diff --git a/sphinx/themes/basic/static/documentation_options.js_t b/sphinx/themes/basic/static/documentation_options.js_t index 8afaac2f8d9..e40c788c747 100644 --- a/sphinx/themes/basic/static/documentation_options.js_t +++ b/sphinx/themes/basic/static/documentation_options.js_t @@ -8,5 +8,6 @@ var DOCUMENTATION_OPTIONS = { LINK_SUFFIX: '{{ link_suffix }}', HAS_SOURCE: {{ has_source|lower }}, SOURCELINK_SUFFIX: '{{ sourcelink_suffix }}', - NAVIGATION_WITH_KEYS: {{ 'true' if theme_navigation_with_keys|tobool else 'false'}} + NAVIGATION_WITH_KEYS: {{ 'true' if theme_navigation_with_keys|tobool else 'false'}}, + ENABLE_SEARCH_SHORTCUTS: {{ 'true' if enable_search_shortcuts|tobool else 'true'}}, }; diff --git a/sphinx/themes/basic/theme.conf b/sphinx/themes/basic/theme.conf index ff378cab406..45834f000f2 100644 --- a/sphinx/themes/basic/theme.conf +++ b/sphinx/themes/basic/theme.conf @@ -10,6 +10,7 @@ sidebarwidth = 230 body_min_width = 450 body_max_width = 800 navigation_with_keys = False +enable_search_shortcuts = True globaltoc_collapse = true globaltoc_includehidden = false globaltoc_maxdepth =