Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
quarto-dev
GitHub Repository: quarto-dev/quarto-cli
Path: blob/main/src/resources/formats/html/tabsets/tabsets.js
12923 views
1
// grouped tabsets
2
3
export function init() {
4
window.addEventListener("pageshow", (_event) => {
5
function getTabSettings() {
6
const data = localStorage.getItem("quarto-persistent-tabsets-data");
7
if (!data) {
8
localStorage.setItem("quarto-persistent-tabsets-data", "{}");
9
return {};
10
}
11
if (data) {
12
return JSON.parse(data);
13
}
14
}
15
16
function setTabSettings(data) {
17
localStorage.setItem(
18
"quarto-persistent-tabsets-data",
19
JSON.stringify(data)
20
);
21
}
22
23
function setTabState(groupName, groupValue) {
24
const data = getTabSettings();
25
data[groupName] = groupValue;
26
setTabSettings(data);
27
}
28
29
function toggleTab(tab, active) {
30
const tabPanelId = tab.getAttribute("aria-controls");
31
const tabPanel = document.getElementById(tabPanelId);
32
if (active) {
33
tab.classList.add("active");
34
tabPanel.classList.add("active");
35
} else {
36
tab.classList.remove("active");
37
tabPanel.classList.remove("active");
38
}
39
}
40
41
function toggleAll(selectedGroup, selectorsToSync) {
42
for (const [thisGroup, tabs] of Object.entries(selectorsToSync)) {
43
const active = selectedGroup === thisGroup;
44
for (const tab of tabs) {
45
toggleTab(tab, active);
46
}
47
}
48
}
49
50
function findSelectorsToSyncByLanguage() {
51
const result = {};
52
const tabs = Array.from(
53
document.querySelectorAll(`div[data-group] a[id^='tabset-']`)
54
);
55
for (const item of tabs) {
56
const div = item.parentElement.parentElement.parentElement;
57
const group = div.getAttribute("data-group");
58
if (!result[group]) {
59
result[group] = {};
60
}
61
const selectorsToSync = result[group];
62
const value = item.innerHTML;
63
if (!selectorsToSync[value]) {
64
selectorsToSync[value] = [];
65
}
66
selectorsToSync[value].push(item);
67
}
68
return result;
69
}
70
71
function setupSelectorSync() {
72
const selectorsToSync = findSelectorsToSyncByLanguage();
73
Object.entries(selectorsToSync).forEach(([group, tabSetsByValue]) => {
74
Object.entries(tabSetsByValue).forEach(([value, items]) => {
75
items.forEach((item) => {
76
item.addEventListener("click", (_event) => {
77
setTabState(group, value);
78
toggleAll(value, selectorsToSync[group]);
79
});
80
});
81
});
82
});
83
return selectorsToSync;
84
}
85
86
const selectorsToSync = setupSelectorSync();
87
for (const [group, selectedName] of Object.entries(getTabSettings())) {
88
const selectors = selectorsToSync[group];
89
// it's possible that stale state gives us empty selections, so we explicitly check here.
90
if (selectors) {
91
toggleAll(selectedName, selectors);
92
}
93
}
94
});
95
}
96
97