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