design-tabs.js 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. // @ts-check
  2. // Extra JS capability for selected tabs to be synced
  3. // The selection is stored in local storage so that it persists across page loads.
  4. /**
  5. * @type {Record<string, HTMLElement[]>}
  6. */
  7. let sd_id_to_elements = {};
  8. const storageKeyPrefix = "sphinx-design-tab-id-";
  9. /**
  10. * Create a key for a tab element.
  11. * @param {HTMLElement} el - The tab element.
  12. * @returns {[string, string, string] | null} - The key.
  13. *
  14. */
  15. function create_key(el) {
  16. let syncId = el.getAttribute("data-sync-id");
  17. let syncGroup = el.getAttribute("data-sync-group");
  18. if (!syncId || !syncGroup) return null;
  19. return [syncGroup, syncId, syncGroup + "--" + syncId];
  20. }
  21. /**
  22. * Initialize the tab selection.
  23. *
  24. */
  25. function ready() {
  26. // Find all tabs with sync data
  27. /** @type {string[]} */
  28. let groups = [];
  29. document.querySelectorAll(".sd-tab-label").forEach((label) => {
  30. if (label instanceof HTMLElement) {
  31. let data = create_key(label);
  32. if (data) {
  33. let [group, id, key] = data;
  34. // add click event listener
  35. // @ts-ignore
  36. label.onclick = onSDLabelClick;
  37. // store map of key to elements
  38. if (!sd_id_to_elements[key]) {
  39. sd_id_to_elements[key] = [];
  40. }
  41. sd_id_to_elements[key].push(label);
  42. if (groups.indexOf(group) === -1) {
  43. groups.push(group);
  44. // Check if a specific tab has been selected via URL parameter
  45. const tabParam = new URLSearchParams(window.location.search).get(
  46. group
  47. );
  48. if (tabParam) {
  49. console.log(
  50. "sphinx-design: Selecting tab id for group '" +
  51. group +
  52. "' from URL parameter: " +
  53. tabParam
  54. );
  55. window.sessionStorage.setItem(storageKeyPrefix + group, tabParam);
  56. }
  57. }
  58. // Check is a specific tab has been selected previously
  59. let previousId = window.sessionStorage.getItem(
  60. storageKeyPrefix + group
  61. );
  62. if (previousId === id) {
  63. // console.log(
  64. // "sphinx-design: Selecting tab from session storage: " + id
  65. // );
  66. // @ts-ignore
  67. label.previousElementSibling.checked = true;
  68. }
  69. }
  70. }
  71. });
  72. }
  73. /**
  74. * Activate other tabs with the same sync id.
  75. *
  76. * @this {HTMLElement} - The element that was clicked.
  77. */
  78. function onSDLabelClick() {
  79. let data = create_key(this);
  80. if (!data) return;
  81. let [group, id, key] = data;
  82. for (const label of sd_id_to_elements[key]) {
  83. if (label === this) continue;
  84. // @ts-ignore
  85. label.previousElementSibling.checked = true;
  86. }
  87. window.sessionStorage.setItem(storageKeyPrefix + group, id);
  88. }
  89. document.addEventListener("DOMContentLoaded", ready, false);