summaryrefslogtreecommitdiff
path: root/limittabsto2.js
diff options
context:
space:
mode:
authorYuchen Pei <id@ypei.org>2023-08-26 11:55:56 +1000
committerYuchen Pei <id@ypei.org>2023-08-26 11:59:46 +1000
commitb72fe68bf964fe386f76897296c87ea3b1fdf148 (patch)
tree588c8e7c46491b1afcf441600b0aac0cc407a574 /limittabsto2.js
First commit, imported from addons.mozilla.org, version 2.2.6HEADmaster
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.js509
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 ();
+});