123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 |
- try {
- var session = window.sessionStorage || {};
- } catch (e) {
- var session = {};
- }
- window.addEventListener("DOMContentLoaded", () => {
- const allTabs = document.querySelectorAll('.sphinx-tabs-tab');
- const tabLists = document.querySelectorAll('[role="tablist"]');
- allTabs.forEach(tab => {
- tab.addEventListener("click", changeTabs);
- });
- tabLists.forEach(tabList => {
- tabList.addEventListener("keydown", keyTabs);
- });
- // Restore group tab selection from session
- const lastSelected = session.getItem('sphinx-tabs-last-selected');
- if (lastSelected != null) selectNamedTabs(lastSelected);
- });
- /**
- * Key focus left and right between sibling elements using arrows
- * @param {Node} e the element in focus when key was pressed
- */
- function keyTabs(e) {
- const tab = e.target;
- let nextTab = null;
- if (e.keyCode === 39 || e.keyCode === 37) {
- tab.setAttribute("tabindex", -1);
- // Move right
- if (e.keyCode === 39) {
- nextTab = tab.nextElementSibling;
- if (nextTab === null) {
- nextTab = tab.parentNode.firstElementChild;
- }
- // Move left
- } else if (e.keyCode === 37) {
- nextTab = tab.previousElementSibling;
- if (nextTab === null) {
- nextTab = tab.parentNode.lastElementChild;
- }
- }
- }
- if (nextTab !== null) {
- nextTab.setAttribute("tabindex", 0);
- nextTab.focus();
- }
- }
- /**
- * Select or deselect clicked tab. If a group tab
- * is selected, also select tab in other tabLists.
- * @param {Node} e the element that was clicked
- */
- function changeTabs(e) {
- // Use this instead of the element that was clicked, in case it's a child
- const notSelected = this.getAttribute("aria-selected") === "false";
- const positionBefore = this.parentNode.getBoundingClientRect().top;
- const notClosable = !this.parentNode.classList.contains("closeable");
- deselectTabList(this);
- if (notSelected || notClosable) {
- selectTab(this);
- const name = this.getAttribute("name");
- selectNamedTabs(name, this.id);
- if (this.classList.contains("group-tab")) {
- // Persist during session
- session.setItem('sphinx-tabs-last-selected', name);
- }
- }
- const positionAfter = this.parentNode.getBoundingClientRect().top;
- const positionDelta = positionAfter - positionBefore;
- // Scroll to offset content resizing
- window.scrollTo(0, window.scrollY + positionDelta);
- }
- /**
- * Select tab and show associated panel.
- * @param {Node} tab tab to select
- */
- function selectTab(tab) {
- tab.setAttribute("aria-selected", true);
- // Show the associated panel
- document
- .getElementById(tab.getAttribute("aria-controls"))
- .removeAttribute("hidden");
- }
- /**
- * Hide the panels associated with all tabs within the
- * tablist containing this tab.
- * @param {Node} tab a tab within the tablist to deselect
- */
- function deselectTabList(tab) {
- const parent = tab.parentNode;
- const grandparent = parent.parentNode;
- Array.from(parent.children)
- .forEach(t => t.setAttribute("aria-selected", false));
- Array.from(grandparent.children)
- .slice(1) // Skip tablist
- .forEach(panel => panel.setAttribute("hidden", true));
- }
- /**
- * Select grouped tabs with the same name, but no the tab
- * with the given id.
- * @param {Node} name name of grouped tab to be selected
- * @param {Node} clickedId id of clicked tab
- */
- function selectNamedTabs(name, clickedId=null) {
- const groupedTabs = document.querySelectorAll(`.sphinx-tabs-tab[name="${name}"]`);
- const tabLists = Array.from(groupedTabs).map(tab => tab.parentNode);
- tabLists
- .forEach(tabList => {
- // Don't want to change the tabList containing the clicked tab
- const clickedTab = tabList.querySelector(`[id="${clickedId}"]`);
- if (clickedTab === null ) {
- // Select first tab with matching name
- const tab = tabList.querySelector(`.sphinx-tabs-tab[name="${name}"]`);
- deselectTabList(tab);
- selectTab(tab);
- }
- })
- }
- if (typeof exports === 'undefined') {
- exports = {};
- }
- exports.keyTabs = keyTabs;
- exports.changeTabs = changeTabs;
- exports.selectTab = selectTab;
- exports.deselectTabList = deselectTabList;
- exports.selectNamedTabs = selectNamedTabs;
|