2024-04-25 22:15:39 +00:00
|
|
|
// 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);
|
2024-04-21 23:04:16 +00:00
|
|
|
}
|
2024-04-25 22:15:39 +00:00
|
|
|
} catch (error) {
|
|
|
|
const action = value ? 'add' : 'remove';
|
|
|
|
console.error(
|
|
|
|
`Docsy tabpane: unable to ${action} localStorage key '${key}': `,
|
|
|
|
error
|
|
|
|
);
|
|
|
|
}
|
2024-04-21 23:04:16 +00:00
|
|
|
}
|
2024-04-25 22:15:39 +00:00
|
|
|
|
|
|
|
// 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);
|
|
|
|
});
|
|
|
|
});
|
2024-04-21 23:04:16 +00:00
|
|
|
}
|
2024-04-25 22:15:39 +00:00
|
|
|
|
|
|
|
// Register listeners and activate tabs
|
|
|
|
|
|
|
|
window.addEventListener('DOMContentLoaded', () => {
|
|
|
|
if (!_tdSupportsLocalStorage()) return;
|
|
|
|
|
|
|
|
var allTabsInThisPage = document.querySelectorAll(_tdPersistCssSelector());
|
|
|
|
tdRegisterTabClickHandler(allTabsInThisPage);
|
|
|
|
tdGetAndActivatePersistedTabs(allTabsInThisPage);
|
|
|
|
});
|