PageSourceSearch

https://www.abcjs.net/tabs.js

js abcjs.net collected 2026-10-02 03:51:47 UTC 4,361 bytes, 162 lines download raw bytes

1function initTabs() {
2	var index = 0;
3	var tabs = document.querySelectorAll('a.tab');
4	var mobileLinks = document.querySelectorAll(".mobile-menu a");
5
6	for (var i = 0; i < tabs.length; i++) {
7		var tab = tabs[i];
8		tab.addEventListener("keydown", keydownHandler);
9		tab.addEventListener("click", clickHandler);
10	}
11
12	for (i = 0; i < mobileLinks.length; i++) {
13		var link = mobileLinks[i];
14		link.addEventListener("click", mobileClickHandler);
15	}
16
17	// on keydown,
18	// determine which tab to select
19	function keydownHandler(ev) {
20		var LEFT_ARROW = 37;
21		var UP_ARROW = 38;
22		var RIGHT_ARROW = 39;
23		var DOWN_ARROW = 40;
24
25		var k = ev.which || ev.keyCode;
26
27		// if the key pressed was an arrow key
28		if (k >= LEFT_ARROW && k <= DOWN_ARROW) {
29			// move left one tab for left and up arrows
30			if (k === LEFT_ARROW || k === UP_ARROW) {
31				if (index > 0) {
32					index--;
33				}
34					// unless you are on the first tab,
35				// in which case select the last tab.
36				else {
37					index = tabs.length - 1;
38				}
39			}
40
41			// move right one tab for right and down arrows
42			else if (k === RIGHT_ARROW || k === DOWN_ARROW) {
43				if (index < (tabs.length - 1)) {
44					index++;
45				}
46					// unless you're at the last tab,
47				// in which case select the first one
48				else {
49					index = 0;
50				}
51			}
52
53			// trigger a click event on the tab to move to
54			tabs[index].click();
55			ev.preventDefault();
56		}
57	}
58
59	// just make the clicked tab the selected one
60	function clickHandler(ev) {
61		for (var i = 0; i < tabs.length; i++) {
62			if (ev.currentTarget.href === tabs[i].href)
63				index = i;
64		}
65		document.title = "abcjs: " + ev.currentTarget.innerText;
66		history.pushState(null, "", ev.currentTarget.href)
67		setFocus();
68		ev.preventDefault();
69	}
70
71	function mobileClickHandler(ev) {
72		// close the menu
73		document.querySelector(".animated-hamburger").click();
74		// Select the page
75		clickHandler(ev);
76	}
77
78	var setFocus = function () {
79		// undo tab control selected state,
80		// and make them not selectable with the tab key
81		// (all tabs)
82		for (var i = 0; i < tabs.length; i++) {
83			tabs[i].setAttribute("tabindex", "-1");
84			tabs[i].setAttribute("aria-selected", "false");
85			// handle parent <li> current class (for coloring the tabs)
86			tabs[i].parentElement.classList.remove("current");
87		}
88		for (i = 0; i < mobileLinks.length; i++) {
89			if (i === index) {
90				mobileLinks[i].setAttribute("aria-selected", "true");
91				mobileLinks[i].parentElement.classList.add("current");
92			} else {
93				mobileLinks[i].setAttribute("aria-selected", "false");
94				mobileLinks[i].parentElement.classList.remove("current");
95			}
96		}
97
98		// hide all tab panels.
99		var panels = document.querySelectorAll(".tab-panel");
100		for (var j = 0; j < panels.length; j++) {
101			panels[j].classList.remove('current');
102		}
103
104		// make the selected tab the selected one, shift focus to it
105		var currentTab = tabs[index];
106		currentTab.setAttribute("tabindex", "0");
107		currentTab.setAttribute("aria-selected", "true");
108		currentTab.parentElement.classList.add("current");
109		currentTab.scrollTo(0, 0);
110
111		// add a current class also to the tab panel
112		// controlled by the clicked tab
113		var tabName = currentTab.href.split("#");
114		tabName = tabName[tabName.length-1]
115		var currentPanel = document.getElementById(tabName);
116		if (currentPanel)
117			currentPanel.classList.add('current');
118	};
119
120	var hash = window.location.hash;
121	if (hash.length > 0) {
122		setPage(hash.substring(1));
123	}
124
125	//
126	// Hamburger menu
127	//
128	document.querySelector(".animated-hamburger").addEventListener("click", toggleMenu);
129	document.querySelector(".a11y-dropdown").addEventListener("click", closeMenu);
130
131	function toggleMenu(ev) {
132		var el = ev.currentTarget;
133		var isExpanded = el.getAttribute("aria-expanded") === "true";
134		isExpanded = !isExpanded;
135		el.setAttribute("aria-expanded", isExpanded);
136	}
137	function closeMenu(ev) {
138		ev.preventDefault();
139		var el = document.querySelector('[aria-expanded="true"]');
140		if (el)
141			el.setAttribute("aria-expanded", "false");
142	}
143}
144
145function setPage(hash) {
146	var first = document.getElementById("tab-" + hash);
147	if (first)
148		first.click();
149}
150
151window.addEventListener('load', (event) => {
152	initTabs();
153});
154
155window.addEventListener('popstate', function(event)
156{
157	var arr = (''+document.location).split('#');
158	if (arr.length > 1 && arr[1].length > 0)
159		setPage(arr[1]);
160	else
161		setPage('what');
162});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.