diff options
author | Yuchen Pei <id@ypei.org> | 2023-08-26 11:55:56 +1000 |
---|---|---|
committer | Yuchen Pei <id@ypei.org> | 2023-08-26 11:59:46 +1000 |
commit | b72fe68bf964fe386f76897296c87ea3b1fdf148 (patch) | |
tree | 588c8e7c46491b1afcf441600b0aac0cc407a574 /limittabsto2.js |
wget https://addons.mozilla.org/firefox/downloads/latest/rudolf-fernandes/latest.xpi
mkdir limit-tabs
unzip -d limit-tabs latest.xpi
Not including the mozilla signatures. The extension is licensed under
GNU GPLv3:
https://addons.mozilla.org/en-US/firefox/addon/rudolf-fernandes/
Diffstat (limited to 'limittabsto2.js')
-rw-r--r-- | limittabsto2.js | 509 |
1 files changed, 509 insertions, 0 deletions
diff --git a/limittabsto2.js b/limittabsto2.js new file mode 100644 index 0000000..228bc8c --- /dev/null +++ b/limittabsto2.js @@ -0,0 +1,509 @@ +// 1.2.3 04May2018. Original version +// 1.2.4 13Aug2018. Changed options.html to make maxtabs a "number" +// 1.2.5 13Aug2018. Added closenew option +// 1.3.0 13Aug2018. Removed some redundant code +// 1.3.1 14Aug2018. Added sound when blocking tab on right hand side +// 1.3.2 16May2019. Added option to disable sounds; sounds both sides +// Will ignore pinned tabs +// 1.3.3 23Jun2019. Added close lru; converted lru/left/right to radio button +// 1.3.4 27Jun2019. Added close newest; also catered to first run (immediately after +// install), setting defaults appropriately (see onMaxTabsGot, onCloseNewest) +// 1.4.0 28Sep2019. Removed the need to "Save" preference changes +// Introduced a validation to ensure "number of tabs" do not go below 2 +// 1.4.1 03Mar2020. Modified the "fail" sound to a "gong sound" +// Modified play_sound to avoid repeat sounds when multiple tabs closed +// 1.4.2 07Mar2020. Fixed some bug (not sure what) +// 1.4.3 10Jun2020. Bug in options.js, where "lru" selection would be overridden by "newest" because +// "newest_getting.then(setnewest, onError);" was being run AFTER +// "lru_getting.then(setlru, onError);" in restoreOptions() +// 1.4.4 24Jun2020. Under "Newest", a new tab spawned from an existing page (which is not rightmost) +// causes the right-most tab to be killed (instead of the new spawned tab) +// 1.4.5 24Jun2020. close_newest. Modified to use tab.id instead of tab.lastAccessed +// 2.0.0 25Jun2020. Modified to allow for toolbar icon that toggles addon status between +// active/inactive. See toggle_enable, limitEnabled, manifest.json:browser_action +// Also reintroduced TABLIMIT as a global variable (how was it working before?) +// 2.0.1 26Jun2020. Added option to disable toggle browser action (Roarke started toggling +// within a day +// 2.0.2 14Jul2020. Added BadgeText to display percent of used tabs. See updateBadgeCount, +// updateBadgeOnRemove +// 2.0.3 15Jul2020. Added option for BadgeText: percent or total used tabs +// Added addonRemoving to fix issue with tabArray.length: when tab killed by +// user it shows correctly, but when killed by add-on, it shows 1 greater +// 2.1.0 15Sep2020. Added option "currentonly" (options.html, options.js too) -- earlier, limit +// would apply to each FF window independent of others. currentonly (default= +// true) when set to false, would apply the limit globally +// 2.1.1 21Sep2020. Modified Math.round to Math.floor (so that 100% displays only when really at the limit) +// 2.2.0 23May2021. Added windowId to allow badgecount to update correctly. +// 2.2.1 25May2021. Added sound options -- gong, buzzer, doorbell, beep. Changed lt.js, options.js, options.html +// 2.2.2 27May2021. Modified options.js to play the sound selected +// 2.2.3 29May2021. doToggle-false. Cycle through all windows, using windowId +// 2.2.4 30May2021. close_lru, close_right, close_newest. Fixed bug arising when multiple windows exist +// 2.2.5 31May2021. cleanjs.sh. An FF reviewer suggested that I remove comments to speed js loading +// created cleanjs.sh, applied it to .js files, then redeployed. No functional changes +// 2.2.6 27Jul2022. Added resetmax. If enabled, resets TABLIMIT to current number when +// extension is toggled from disabled to enabled + + +//******************************************** +// Use cleanjs.sh to remove comments before submission +//******************************************** + +var TABLIMIT = 2; +var DEFAULTTABLIMIT = 2; +var SOUND_LAST_PLAYED = Date.now()-2000; +var limitEnabled = true; +var currentonly = true; +var addonRemoving = false; +var windowId = null; +var tabRemoved = false; + +function toggle_enable() { + // console.log ("toggle_enable called..."); + var getting = browser.storage.local.get("notoggle"); + getting.then(doToggle, onError); +} + +async function doToggle (result) { + if (! result.notoggle) { + if (limitEnabled) { + // console.log ("limitEnabled set to true"); + limitEnabled = false; + browser.storage.local.set({ limit_enabled: false }); + browser.browserAction.setIcon({path: "icons/disabled.png"}); + + // 29May21. Cycle through all windows + var gettingAll = browser.windows.getAll(); + gettingAll.then((windows) => { + for (var item of windows) { + browser.browserAction.setBadgeText({text: "", windowId: item.id}); + } + }); + + + } else { + limitEnabled = true; + browser.storage.local.set({ limit_enabled: true }); + browser.browserAction.setIcon({path: "icons/enabled.png"}); + + + var totalTabs = 0; + // First get the number of tabs in other windows + if (! currentonly) { + let tabArray = await browser.tabs.query({currentWindow: false, pinned: false}); + totalTabs = tabArray.length; + } + + // Now retrieve the number of tabs in the current window + let tabArray = await browser.tabs.query({currentWindow: true, pinned: false}); + totalTabs = totalTabs + tabArray.length; + + // 27Jul22. If setmax enabled, set TABLIMIT to current number of tabs + let result = await browser.storage.local.get("resetmax"); + + if (result.resetmax) { + TABLIMIT = totalTabs; + browser.storage.local.set({ maxtabs: TABLIMIT }); + + } + + updateBadgeCount(totalTabs, TABLIMIT); + + } + } +} + +function onError(error) { + console.log(`Error: ${error}`); +} + +async function updateBadgeCount(actualCount, limitTabs) { + + let myWindow = await browser.windows.getCurrent(); + windowId = myWindow.id; + + // 21Sep2020. Modified next line + // let percent = Math.round(actualCount * 100 / limitTabs); + let percent = Math.floor(actualCount * 100 / limitTabs); + + let result = await browser.storage.local.get("showtabs"); + // console.log ("updateBadgeCount. actualCount = " + actualCount); + + // console.log ("updateBadgeCount. windowId = " + windowId); + // Need to show %, rather than "tabs/limit" as max. of 4 characters + // appear to be allowed in BadgeText + + // 24May21. In theory, setBadgeText with windowId = null (or windowId excluded) should update all windows; + // in practice, it's flaky. Consequently, irrespective of whether the limit is currentonly or across + // all windows, only the current window is updated. Switching to the other window would show an incorrect + // number (when limit is global) until a tab is added/deleted + if (result.showtabs) { + browser.browserAction.setBadgeText({text: actualCount.toString(), windowId: windowId }); + } else { + browser.browserAction.setBadgeText({text: percent.toString() + "%", windowId: windowId}); + } + if (percent >= 90) { + browser.browserAction.setBadgeTextColor({color: "red", windowId}); + browser.browserAction.setBadgeBackgroundColor({color: "lightgray", windowId: windowId}); + } else { + browser.browserAction.setBadgeTextColor({color: "black", windowId}); + browser.browserAction.setBadgeBackgroundColor({color: "lightgray", windowId: windowId}); + } + +} + +function onTabsChanged() { + if (tabRemoved) { + var getting = browser.storage.local.get("limit_enabled"); + getting.then(isEnabled, onError); + } else { + var getting = browser.storage.local.get("firststart"); + getting.then(firststart, onError); + } +} + +function firststart(mt_item) { + // When the extension is first installed (firststart is null) and the aim is to + // set maxtabs (the tab limit) to the current number of tabs + + if (mt_item.firststart == null) { + + // 31May2021. Added code to set all defaults the first time + + browser.storage.local.set({ firststart: 1 }); + + browser.storage.local.set({ currentonly: true }); + + browser.storage.local.set({ buzzer: true }); + browser.storage.local.set({ gong: false }); + browser.storage.local.set({ doorbell: false }); + browser.storage.local.set({ nosound: false }); + + browser.storage.local.set({ newest: true }); + browser.storage.local.set({ lru: false }); + browser.storage.local.set({ left: false }); + browser.storage.local.set({ right: false }); + + browser.storage.local.set({ limit_enabled: true }); + + browser.storage.local.set({ showtabs: false }); + + browser.storage.local.set({ notoggle: false }); + + // Sets the limit to the current number of tabs. User can subsequently change it + first_limit(); + } else { + var getting = browser.storage.local.get("limit_enabled"); + getting.then(isEnabled, onError); + } +} + +// Sets the limit to the current number of tabs. User can subsequently change it +async function first_limit() { + // console.log ("Inside first_limit"); + + let tabArray = await browser.tabs.query({currentWindow: true, pinned: false}); + if (tabArray.length > DEFAULTTABLIMIT ) { + browser.storage.local.set({ maxtabs: tabArray.length }); + TABLIMIT=tabArray.length; + + } else { + browser.storage.local.set({ maxtabs: DEFAULTTABLIMIT }); + TABLIMIT=DEFAULTTABLIMIT; + } + +// console.log ("first_limit. tabArray.length= " + tabArray.length); + updateBadgeCount(tabArray.length, TABLIMIT); +} + +function isEnabled(result) { + // console.log ("isEnabled called..."); + limitEnabled = result.limit_enabled; + + // console.log ("isEnabled.limitEnabled = " + limitEnabled); + + if (limitEnabled == null) { + // console.log ("isEnabled. Setting limit_enabled "); + + browser.storage.local.set({ limit_enabled: true}); + limitEnabled = true; + } + if (limitEnabled) { + var getting = browser.storage.local.get("currentonly"); + getting.then(setCurrentOnly, onError); + } +} + +function setCurrentOnly(result) { + // console.log ("setCurrentOnly. result.currentonly = " + result.currentonly); + currentonly = result.currentonly; + if (currentonly == null) { + // console.log ("setCurrentOnly. Setting currentonly "); + + browser.storage.local.set({ currentonly: true}); + currentonly = true; + } + + // console.log ("setCurrentOnly. currentonly = " + currentonly); + // if (currentonly) { + // set window Id + var gettingCurrent = browser.windows.getCurrent(); + gettingCurrent.then(setCurrentId, onError); +} + +function setCurrentId (result) { + windowId = result.id; + // console.log ("setCurrentId. windowId = " + result.id); + doStuff(); +} + +async function doStuff() { + let resultTabs = await browser.storage.local.get("maxtabs"); + TABLIMIT = resultTabs.maxtabs; + + if (TABLIMIT < 1) { + TABLIMIT = 2; + } + + // console.log ("doStuff. currentonly = " + currentonly); + + var totalTabs = 0; + // First get the number of tabs in other windows + if (! currentonly) { + let tabArray = await browser.tabs.query({currentWindow: false, pinned: false}); + totalTabs = tabArray.length; + // console.log ("doStuff. totalTabs (false) = " + totalTabs); + } + + // Now retrieve the number of tabs in the current window + let tabArray = await browser.tabs.query({currentWindow: true, pinned: false}); + totalTabs = totalTabs + tabArray.length; + // console.log ("doStuff. totalTabs (all) = " + totalTabs); + + if (totalTabs > TABLIMIT) { + var getting = browser.storage.local.get("newest" || true); + getting.then(onCloseNewest, onError); + } else { + // For some reason, when manually removing a tab, the function gets called + // before the tab is removed, hence need to subtract 1 + if (tabRemoved) { + + // For some reason, when manually removing a tab, the function gets called + // before the tab is removed, hence need to subtract 1 + if (! addonRemoving) { + totalTabs = totalTabs-1 + } + addonRemoving = false; + } + updateBadgeCount(totalTabs, TABLIMIT); + } +} + +function onCloseNewest(result) { + var myResult = result.newest; + if (typeof result.newest == "undefined") { + myResult = true; + } + // console.log ("onCloseNewest.myResult = " + myResult ); + + if (myResult) { + close_newest(); + } else { + var getting = browser.storage.local.get("lru"); + getting.then(onCloseLru, onError); + } +} + +function onCloseLru(result) { + if (result.lru) { + close_lru(); + } else { + var getting = browser.storage.local.get("right"); + getting.then(onCloseRight, onError); + } +} + +function onCloseRight(result) { + if (result.right) { + right_close(); + } else { + left_close(); + } + +} + +async function close_newest () { + var totalTabs = 0; + // First get the number of tabs in other windows + if (! currentonly) { + let tabArray = await browser.tabs.query({currentWindow: false, pinned: false}); + totalTabs = tabArray.length; + } + + // console.log ("close_newest. totalTabs (other) =" + totalTabs); + + // Now retrieve the number of tabs in the current window + let tabArray = await browser.tabs.query({currentWindow: true, pinned: false}); + totalTabs = totalTabs + tabArray.length; + + // console.log ("close_newest. totalTabs (all) =" + totalTabs); + + if (totalTabs > TABLIMIT) { + // var getting = browser.storage.local.get("nosound"); + // getting.then(play_sound, onError); + play_sound(); + + // Code to close the newest, based on tab.id + var index=0, i; + var newestid=tabArray[0].id; + + for (i = 0; i < tabArray.length; i++) { + // console.log ("close_newest. i=" + i + // + " lastAccessed=" + tabArray[i].lastAccessed + // + " Id =" + tabArray[i].id); + + if (tabArray[i].id > newestid) { + index = i; + newestid = tabArray[i].id; + + // console.log ("close_newest. index changed to =" + i); + } + } + + await browser.tabs.remove(tabArray[index].id); + close_newest(); + addonRemoving = true; + // console.log ("close_newest. Inside for. tabArray.length =" + tabArray.length); + } +} + +async function close_lru () { + var totalTabs = 0; + // First get the number of tabs in other windows + if (! currentonly) { + let tabArray = await browser.tabs.query({currentWindow: false, pinned: false}); + totalTabs = tabArray.length; + } + + // Now retrieve the number of tabs in the current window + let tabArray = await browser.tabs.query({currentWindow: true, pinned: false}); + totalTabs = totalTabs + tabArray.length; + + if (totalTabs > TABLIMIT) { + // var getting = browser.storage.local.get("nosound"); + // getting.then(play_sound, onError); + play_sound(); + + + // Code to close the least recently used + var oldesttime=tabArray[0].lastAccessed, index=0, i; + + for (i = 0; i < tabArray.length-1; i++) { + + //console.log ("close_lru. i=" + i + " lastAccessed=" + tabArray[i].lastAccessed); + + if (tabArray[i].lastAccessed < oldesttime) { + index = i; + oldesttime = tabArray[i].lastAccessed; + + // console.log ("close_lru. index changed to =" + i); + } + } + + await browser.tabs.remove(tabArray[index].id); + close_lru(); + addonRemoving = true; + } +} + +async function right_close () { + var totalTabs = 0; + // First get the number of tabs in other windows + if (! currentonly) { + let tabArray = await browser.tabs.query({currentWindow: false, pinned: false}); + totalTabs = tabArray.length; + } + + // Now retrieve the number of tabs in the current window + let tabArray = await browser.tabs.query({currentWindow: true, pinned: false}); + totalTabs = totalTabs + tabArray.length; + + if (totalTabs > TABLIMIT) { + // var getting = browser.storage.local.get("nosound"); + // getting.then(play_sound, onError); + play_sound(); + + await browser.tabs.remove(tabArray[tabArray.length-1].id); + right_close(); + addonRemoving = true; + } +} + +async function left_close () { + var totalTabs = 0; + // First get the number of tabs in other windows + if (! currentonly) { + let tabArray = await browser.tabs.query({currentWindow: false, pinned: false}); + totalTabs = tabArray.length; + } + + // Now retrieve the number of tabs in the current window + let tabArray = await browser.tabs.query({currentWindow: true, pinned: false}); + totalTabs = totalTabs + tabArray.length; + + if (totalTabs > TABLIMIT) { + // var getting = browser.storage.local.get("nosound"); + // getting.then(play_sound, onError); + play_sound(); + + await browser.tabs.remove(tabArray[0].id); + left_close(); + addonRemoving = true; + } +} + +async function play_sound () { + var audiofile = ""; + + var arbit = await browser.storage.local.get("nosound"); + if (arbit.nosound) { + // Do nothing + // console.log("Within nosound if stmt"); + } else { + arbit = await browser.storage.local.get("buzzer"); + if (arbit.buzzer) { + audiofile = 'buzzer.ogg'; + } + arbit = await browser.storage.local.get("gong"); + if (arbit.gong) { + audiofile = 'gong.ogg'; + } + arbit = await browser.storage.local.get("doorbell"); + if (arbit.doorbell) { + audiofile = 'doorbell.ogg'; + } + arbit = await browser.storage.local.get("beep"); + if (arbit.beep) { + audiofile = 'beep.ogg'; + } + + if ((Date.now() - SOUND_LAST_PLAYED) > 2000) { + var audio = new Audio(audiofile); + audio.play(); + SOUND_LAST_PLAYED = Date.now(); + } + } + // console.log("audiofile = " + audiofile); + +} + +browser.browserAction.setTitle({title: "Toggle Limit Tabs"}); +browser.browserAction.onClicked.addListener(toggle_enable); +browser.tabs.onCreated.addListener(function (tab) { + tabRemoved = false; + onTabsChanged (); +}); +// browser.tabs.onRemoved.addListener(updateBadgeOnRemove); +browser.tabs.onRemoved.addListener(function (tab) { + tabRemoved = true; + onTabsChanged (); +}); |