-
Notifications
You must be signed in to change notification settings - Fork 922
/
Copy pathtabpane-persist.js
128 lines (103 loc) · 3.46 KB
/
tabpane-persist.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// Storage key names and data attribute name:
const td_persistStorageKeyNameBase = 'td-tp-persist';
const td_persistCounterStorageKeyName = `${td_persistStorageKeyNameBase}-count`;
const td_persistDataAttrName = `data-${td_persistStorageKeyNameBase}`;
// Utilities
const _tdPersistCssSelector = (attrValue) =>
attrValue
? `[${td_persistDataAttrName}="${attrValue}"]`
: `[${td_persistDataAttrName}]`;
const _tdStoragePersistKey = (tabKey) =>
td_persistStorageKeyNameBase + ':' + (tabKey || '');
const _tdSupportsLocalStorage = () => typeof Storage !== 'undefined';
// Helpers
function tdPersistKey(key, value) {
// @requires: tdSupportsLocalStorage();
try {
if (value) {
localStorage.setItem(key, value);
} else {
localStorage.removeItem(key);
}
} catch (error) {
const action = value ? 'add' : 'remove';
console.error(
`Docsy tabpane: unable to ${action} localStorage key '${key}': `,
error
);
}
}
function getActiveTabFromURL() {
const urlParams = new URLSearchParams(window.location.search);
const activeTab = urlParams.get('tab');
return activeTab ? activeTab.toLowerCase() : null;
}
// Retrieve, increment, and store tab-select event count, then returns it.
function tdGetTabSelectEventCountAndInc() {
// @requires: tdSupportsLocalStorage();
const storedCount = localStorage.getItem(td_persistCounterStorageKeyName);
let numTabSelectEvents = parseInt(storedCount) || 0;
numTabSelectEvents++;
tdPersistKey(td_persistCounterStorageKeyName, numTabSelectEvents.toString());
return numTabSelectEvents;
}
// Main functions
function tdActivateTabsWithKey(key) {
if (!key) return;
document.querySelectorAll(_tdPersistCssSelector(key)).forEach((element) => {
new bootstrap.Tab(element).show();
});
}
function tdPersistActiveTab(activeTabKey) {
if (!_tdSupportsLocalStorage()) return;
tdPersistKey(
_tdStoragePersistKey(activeTabKey),
tdGetTabSelectEventCountAndInc()
);
tdActivateTabsWithKey(activeTabKey);
}
// Handlers
function tdGetAndActivatePersistedTabs(tabs) {
// Get unique persistence keys of tabs in this page
var keyOfTabsInThisPage = [
...new Set(
Array.from(tabs).map((el) => el.getAttribute(td_persistDataAttrName))
),
];
// Create a list of active tabs with their age:
let key_ageList = keyOfTabsInThisPage
// Map to [tab-key, last-activated-age]
.map((k) => [
k,
parseInt(localStorage.getItem(_tdStoragePersistKey(k))) || 0,
])
// Exclude tabs that have never been activated
.filter(([k, v]) => v)
// Sort from oldest selected to most recently selected
.sort((a, b) => a[1] - b[1]);
// Activate tabs from the oldest to the newest
key_ageList.forEach(([key]) => {
tdActivateTabsWithKey(key);
});
return key_ageList;
}
function tdRegisterTabClickHandler(tabs) {
tabs.forEach((tab) => {
tab.addEventListener('click', () => {
const activeTabKey = tab.getAttribute(td_persistDataAttrName);
tdPersistActiveTab(activeTabKey);
});
});
}
// Register listeners and activate tabs
window.addEventListener('DOMContentLoaded', () => {
if (!_tdSupportsLocalStorage()) return;
var allTabsInThisPage = document.querySelectorAll(_tdPersistCssSelector());
tdRegisterTabClickHandler(allTabsInThisPage);
const activeTabKeyFromURL = getActiveTabFromURL();
if (activeTabKeyFromURL) {
tdActivateTabsWithKey(activeTabKeyFromURL);
} else {
tdGetAndActivatePersistedTabs(allTabsInThisPage);
}
});