tabpane-persist.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. // Storage key names and data attribute name:
  2. const td_persistStorageKeyNameBase = 'td-tp-persist';
  3. const td_persistCounterStorageKeyName = `${td_persistStorageKeyNameBase}-count`;
  4. const td_persistDataAttrName = `data-${td_persistStorageKeyNameBase}`;
  5. // Utilities
  6. const _tdPersistCssSelector = (attrValue) =>
  7. attrValue
  8. ? `[${td_persistDataAttrName}="${attrValue}"]`
  9. : `[${td_persistDataAttrName}]`;
  10. const _tdStoragePersistKey = (tabKey) =>
  11. td_persistStorageKeyNameBase + ':' + (tabKey || '');
  12. const _tdSupportsLocalStorage = () => typeof Storage !== 'undefined';
  13. // Helpers
  14. function tdPersistKey(key, value) {
  15. // @requires: tdSupportsLocalStorage();
  16. try {
  17. if (value) {
  18. localStorage.setItem(key, value);
  19. } else {
  20. localStorage.removeItem(key);
  21. }
  22. } catch (error) {
  23. const action = value ? 'add' : 'remove';
  24. console.error(
  25. `Docsy tabpane: unable to ${action} localStorage key '${key}': `,
  26. error
  27. );
  28. }
  29. }
  30. // Retrieve, increment, and store tab-select event count, then returns it.
  31. function tdGetTabSelectEventCountAndInc() {
  32. // @requires: tdSupportsLocalStorage();
  33. const storedCount = localStorage.getItem(td_persistCounterStorageKeyName);
  34. let numTabSelectEvents = parseInt(storedCount) || 0;
  35. numTabSelectEvents++;
  36. tdPersistKey(td_persistCounterStorageKeyName, numTabSelectEvents.toString());
  37. return numTabSelectEvents;
  38. }
  39. // Main functions
  40. function tdActivateTabsWithKey(key) {
  41. if (!key) return;
  42. document.querySelectorAll(_tdPersistCssSelector(key)).forEach((element) => {
  43. new bootstrap.Tab(element).show();
  44. });
  45. }
  46. function tdPersistActiveTab(activeTabKey) {
  47. if (!_tdSupportsLocalStorage()) return;
  48. tdPersistKey(
  49. _tdStoragePersistKey(activeTabKey),
  50. tdGetTabSelectEventCountAndInc()
  51. );
  52. tdActivateTabsWithKey(activeTabKey);
  53. }
  54. // Handlers
  55. function tdGetAndActivatePersistedTabs(tabs) {
  56. // Get unique persistence keys of tabs in this page
  57. var keyOfTabsInThisPage = [
  58. ...new Set(
  59. Array.from(tabs).map((el) => el.getAttribute(td_persistDataAttrName))
  60. ),
  61. ];
  62. // Create a list of active tabs with their age:
  63. let key_ageList = keyOfTabsInThisPage
  64. // Map to [tab-key, last-activated-age]
  65. .map((k) => [
  66. k,
  67. parseInt(localStorage.getItem(_tdStoragePersistKey(k))) || 0,
  68. ])
  69. // Exclude tabs that have never been activated
  70. .filter(([k, v]) => v)
  71. // Sort from oldest selected to most recently selected
  72. .sort((a, b) => a[1] - b[1]);
  73. // Activate tabs from the oldest to the newest
  74. key_ageList.forEach(([key]) => {
  75. tdActivateTabsWithKey(key);
  76. });
  77. return key_ageList;
  78. }
  79. function tdRegisterTabClickHandler(tabs) {
  80. tabs.forEach((tab) => {
  81. tab.addEventListener('click', () => {
  82. const activeTabKey = tab.getAttribute(td_persistDataAttrName);
  83. tdPersistActiveTab(activeTabKey);
  84. });
  85. });
  86. }
  87. // Register listeners and activate tabs
  88. window.addEventListener('DOMContentLoaded', () => {
  89. if (!_tdSupportsLocalStorage()) return;
  90. var allTabsInThisPage = document.querySelectorAll(_tdPersistCssSelector());
  91. tdRegisterTabClickHandler(allTabsInThisPage);
  92. tdGetAndActivatePersistedTabs(allTabsInThisPage);
  93. });