selfprivacy.org/_vendor/github.com/google/docsy/static/js/tabpane-persist.js
2024-04-26 01:15:39 +03:00

117 lines
3.1 KiB
JavaScript

// 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
);
}
}
// 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);
tdGetAndActivatePersistedTabs(allTabsInThisPage);
});