Python Library Caching
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

doctools.js 4.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. /*
  2. * doctools.js
  3. * ~~~~~~~~~~~
  4. *
  5. * Base JavaScript utilities for all Sphinx HTML documentation.
  6. *
  7. * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS.
  8. * :license: BSD, see LICENSE for details.
  9. *
  10. */
  11. "use strict";
  12. const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([
  13. "TEXTAREA",
  14. "INPUT",
  15. "SELECT",
  16. "BUTTON",
  17. ]);
  18. const _ready = (callback) => {
  19. if (document.readyState !== "loading") {
  20. callback();
  21. } else {
  22. document.addEventListener("DOMContentLoaded", callback);
  23. }
  24. };
  25. /**
  26. * Small JavaScript module for the documentation.
  27. */
  28. const Documentation = {
  29. init: () => {
  30. Documentation.initDomainIndexTable();
  31. Documentation.initOnKeyListeners();
  32. },
  33. /**
  34. * i18n support
  35. */
  36. TRANSLATIONS: {},
  37. PLURAL_EXPR: (n) => (n === 1 ? 0 : 1),
  38. LOCALE: "unknown",
  39. // gettext and ngettext don't access this so that the functions
  40. // can safely bound to a different name (_ = Documentation.gettext)
  41. gettext: (string) => {
  42. const translated = Documentation.TRANSLATIONS[string];
  43. switch (typeof translated) {
  44. case "undefined":
  45. return string; // no translation
  46. case "string":
  47. return translated; // translation exists
  48. default:
  49. return translated[0]; // (singular, plural) translation tuple exists
  50. }
  51. },
  52. ngettext: (singular, plural, n) => {
  53. const translated = Documentation.TRANSLATIONS[singular];
  54. if (typeof translated !== "undefined")
  55. return translated[Documentation.PLURAL_EXPR(n)];
  56. return n === 1 ? singular : plural;
  57. },
  58. addTranslations: (catalog) => {
  59. Object.assign(Documentation.TRANSLATIONS, catalog.messages);
  60. Documentation.PLURAL_EXPR = new Function(
  61. "n",
  62. `return (${catalog.plural_expr})`
  63. );
  64. Documentation.LOCALE = catalog.locale;
  65. },
  66. /**
  67. * helper function to focus on search bar
  68. */
  69. focusSearchBar: () => {
  70. document.querySelectorAll("input[name=q]")[0]?.focus();
  71. },
  72. /**
  73. * Initialise the domain index toggle buttons
  74. */
  75. initDomainIndexTable: () => {
  76. const toggler = (el) => {
  77. const idNumber = el.id.substr(7);
  78. const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`);
  79. if (el.src.substr(-9) === "minus.png") {
  80. el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`;
  81. toggledRows.forEach((el) => (el.style.display = "none"));
  82. } else {
  83. el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`;
  84. toggledRows.forEach((el) => (el.style.display = ""));
  85. }
  86. };
  87. const togglerElements = document.querySelectorAll("img.toggler");
  88. togglerElements.forEach((el) =>
  89. el.addEventListener("click", (event) => toggler(event.currentTarget))
  90. );
  91. togglerElements.forEach((el) => (el.style.display = ""));
  92. if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler);
  93. },
  94. initOnKeyListeners: () => {
  95. // only install a listener if it is really needed
  96. if (
  97. !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS &&
  98. !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS
  99. )
  100. return;
  101. document.addEventListener("keydown", (event) => {
  102. // bail for input elements
  103. if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return;
  104. // bail with special keys
  105. if (event.altKey || event.ctrlKey || event.metaKey) return;
  106. if (!event.shiftKey) {
  107. switch (event.key) {
  108. case "ArrowLeft":
  109. if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break;
  110. const prevLink = document.querySelector('link[rel="prev"]');
  111. if (prevLink && prevLink.href) {
  112. window.location.href = prevLink.href;
  113. event.preventDefault();
  114. }
  115. break;
  116. case "ArrowRight":
  117. if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break;
  118. const nextLink = document.querySelector('link[rel="next"]');
  119. if (nextLink && nextLink.href) {
  120. window.location.href = nextLink.href;
  121. event.preventDefault();
  122. }
  123. break;
  124. }
  125. }
  126. // some keyboard layouts may need Shift to get /
  127. switch (event.key) {
  128. case "/":
  129. if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break;
  130. Documentation.focusSearchBar();
  131. event.preventDefault();
  132. }
  133. });
  134. },
  135. };
  136. // quick alias for translations
  137. const _ = Documentation.gettext;
  138. _ready(Documentation.init);