PageSourceSearch

https://www.beacontechnologies.com/_global/js/accessible-basic-tabs.js

js beacontechnologies.com collected 2026-09-25 20:41:47 UTC 3,223 bytes, 109 lines download raw bytes

1/* This content is licensed according to the W3C Software License at
2 * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
3 * File: tabs-automatic.js
4 * Desc: Tablist widget that implements ARIA Authoring Practices
5 */
6'use strict';
7class TabsAutomatic {
8  constructor(groupNode) {
9    this.tablistNode = groupNode;
10    this.tabs = [];
11    this.firstTab = null;
12    this.lastTab = null;
13    this.tabs = Array.from(this.tablistNode.querySelectorAll('[role=tab]'));
14    this.tabpanels = [];
15    for (var i = 0; i < this.tabs.length; i += 1) {
16      var tab = this.tabs[i];
17      var tabpanel = document.getElementById(tab.getAttribute('aria-controls'));
18      tab.tabIndex = -1;
19      tab.setAttribute('aria-selected', 'false');
20      this.tabpanels.push(tabpanel);
21      tab.addEventListener('keydown', this.onKeydown.bind(this));
22      tab.addEventListener('click', this.onClick.bind(this));
23      if (!this.firstTab) {
24        this.firstTab = tab;
25      }
26      this.lastTab = tab;
27    }
28    this.setSelectedTab(this.firstTab, false);
29  }
30  setSelectedTab(currentTab, setFocus) {
31    if (typeof setFocus !== 'boolean') {
32      setFocus = true;
33    }
34    for (var i = 0; i < this.tabs.length; i += 1) {
35      var tab = this.tabs[i];
36      if (currentTab === tab) {
37        tab.setAttribute('aria-selected', 'true');
38        tab.removeAttribute('tabindex');
39        this.tabpanels[i].classList.remove('is-hidden');
40        if (setFocus) {
41          tab.focus();
42        }
43      } else {
44        tab.setAttribute('aria-selected', 'false');
45        tab.tabIndex = -1;
46        this.tabpanels[i].classList.add('is-hidden');
47      }
48    }
49  }
50
51  setSelectedToPreviousTab(currentTab) {
52    var index;
53    if (currentTab === this.firstTab) {
54      this.setSelectedTab(this.lastTab);
55    } else {
56      index = this.tabs.indexOf(currentTab);
57      this.setSelectedTab(this.tabs[index - 1]);
58    }
59  }
60  setSelectedToNextTab(currentTab) {
61    var index;
62    if (currentTab === this.lastTab) {
63      this.setSelectedTab(this.firstTab);
64    } else {
65      index = this.tabs.indexOf(currentTab);
66      this.setSelectedTab(this.tabs[index + 1]);
67    }
68  }
69
70  /* EVENT HANDLERS */
71  onKeydown(event) {
72    var tgt = event.currentTarget,
73      flag = false;
74    switch (event.key) {
75      case 'ArrowLeft':
76        this.setSelectedToPreviousTab(tgt);
77        flag = true;
78        break;
79      case 'ArrowRight':
80        this.setSelectedToNextTab(tgt);
81        flag = true;
82        break;
83      case 'Home':
84        this.setSelectedTab(this.firstTab);
85        flag = true;
86        break;
87      case 'End':
88        this.setSelectedTab(this.lastTab);
89        flag = true;
90        break;
91      default:
92        break;
93    }
94    if (flag) {
95      event.stopPropagation();
96      event.preventDefault();
97    }
98  }
99  onClick(event) {
100    this.setSelectedTab(event.currentTarget);
101  }
102}
103// Initialize tablist
104window.addEventListener('load', function () {
105  var tablists = document.querySelectorAll('[role=tablist].automatic');
106  for (var i = 0; i < tablists.length; i++) {
107    new TabsAutomatic(tablists[i]);
108  }
109});

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.