Skip to content

Commit f926aae

Browse files
committed
recentlyClosedTabsContextMenu.uc.js v2.0.4:
add a new pref that sets the behavior when clicking a recently closed tab/window item. middle click will remove it from the list, while ctrl+click will open it in new tab (instead of restoring in place) and ctrl + shift + click will open it in new window. this pref is userChrome.tabs.recentlyClosedTabs.middle-click-to-remove if you don't set it, the behavior will remain vanilla. (CSS) change font styles for hg.mozilla.org
1 parent 961f71a commit f926aae

3 files changed

Lines changed: 81 additions & 31 deletions

File tree

JS/recentlyClosedTabsContextMenu.uc.js

Lines changed: 70 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
// ==UserScript==
22
// @name Undo Recently Closed Tabs in Tab Context Menu
3-
// @version 2.0.3
3+
// @version 2.0.4
44
// @author aminomancer
55
// @homepage https://github.com/aminomancer/uc.css.js
6-
// @description Adds new menus to the context menu that appears when you right-click a tab (in the tab bar or in the TreeStyleTabs sidebar): one lists recently closed tabs so you can restore them, and another lists recently closed windows. These are basically the same functions that exist in the history toolbar button's popup, but I think the tab context menu is a more convenient location for them. Also optionally adds a context menu to the history panel's subview pages for "Recently closed tabs" and "Recently closed windows" with various functions for interacting with the closed tabs and their session history. You can right-click a closed tab item to open the context menu, then click "Remove from List" to get rid of it. You can click "Remove from History" to not only remove the closed tab item, but also forget all of the tab's history — that is, every page it navigated to. The same can be done with recently closed windows. From this menu you can also restore a tab in a new window or private window, bookmark a closed tab/window, and more.
6+
// @description Adds new menus to the context menu that appears when you right-click a tab (in the tab bar or in the TreeStyleTabs sidebar): one lists recently closed tabs so you can restore them, and another lists recently closed windows. These are basically the same functions that exist in the history toolbar button's popup, but I think the tab context menu is a more convenient location for them. Also optionally adds a context menu to the history panel's subview pages for "Recently closed tabs" and "Recently closed windows" with various functions for interacting with the closed tabs and their session history. You can right-click a closed tab item to open the context menu, then click "Remove from List" to get rid of it. You can click "Remove from History" to not only remove the closed tab item, but also forget all of the tab's history — that is, every page it navigated to. The same can be done with recently closed windows. From this menu you can also restore a tab in a new window or private window, bookmark a closed tab/window, and more. This script also adds a new preference (userChrome.tabs.recentlyClosedTabs.middle-click-to-remove) which changes the behavior when you click a recently closed tab/window item in the history panel. Middle clicking a tab or window item will remove it from the list (just like one of the context menu items). Ctrl+clicking a tab item it will open it in a new tab (instead of restoring it in its former place), and Ctrl+Shift+clicking it will open it in a new window.
77
// @license This Source Code Form is subject to the terms of the Creative Commons Attribution-NonCommercial-ShareAlike International License, v. 4.0. If a copy of the CC BY-NC-SA 4.0 was not distributed with this file, You can obtain one at http://creativecommons.org/licenses/by-nc-sa/4.0/ or send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.
88
// ==/UserScript==
99

@@ -396,11 +396,12 @@ class UndoListInTabmenu {
396396
let activeIndex = (tabData.index || tabData.entries.length) - 1;
397397
if (activeIndex >= 0 && tabData.entries[activeIndex])
398398
element.setAttribute("targetURI", tabData.entries[activeIndex].url);
399-
if (!aIsWindowsFragment && aTagName != "menuitem")
400-
element.addEventListener(
401-
"click",
402-
RecentlyClosedTabsAndWindowsMenuUtils._undoCloseMiddleClick
399+
if (aTagName != "menuitem") {
400+
element.setAttribute(
401+
"onclick",
402+
`undoTabSubmenu.on${aIsWindowsFragment ? "Window" : "Tab"}ItemClick(event)`
403403
);
404+
}
404405
if (!forContext && aTagName != "menuitem") {
405406
element.setAttribute("tooltip", "bhTooltip");
406407
if (UndoListInTabmenu.config["Enable context menus in panels"])
@@ -581,10 +582,18 @@ class RecentlyClosedPanelContext {
581582
constructor() {
582583
this.config = UndoListInTabmenu.config;
583584
let { l10n } = this.config;
584-
// override this function because there's some kind of weird old workaround in the built-in version.
585-
// I don't know why someone added this, but it goes out of its way to prevent a tab from being
586-
// restored properly if you only have 1 tab open and it's blank/new tab page.
587-
// I did as much testing as I know how, and couldn't find a problem caused by removing it. so I removed it
585+
XPCOMUtils.defineLazyPreferenceGetter(
586+
this,
587+
"REMOVE_ON_MID_CLICK",
588+
"userChrome.tabs.recentlyClosedTabs.middle-click-to-remove",
589+
false
590+
);
591+
// override this function because there's some kind of weird old
592+
// workaround in the built-in version. I don't know why someone added
593+
// this, but it goes out of its way to prevent a tab from being restored
594+
// properly if you only have 1 tab open and it's blank/new tab page. I
595+
// did as much testing as I know how, and couldn't find a problem caused
596+
// by removing it. so I removed it
588597
window.undoCloseTab = function (index) {
589598
let tab = null;
590599
// index is undefined if the function is called without a specific tab to restore.
@@ -683,7 +692,7 @@ class RecentlyClosedPanelContext {
683692
handleEvent(e) {
684693
switch (e.type) {
685694
case "popupshowing":
686-
this.onPopupShowing(e);
695+
this.onPopupShowing();
687696
break;
688697
case "command":
689698
this.onCommand(e);
@@ -701,7 +710,7 @@ class RecentlyClosedPanelContext {
701710
);
702711
delete this.updateTimer;
703712
}
704-
onPopupShowing(e) {
713+
onPopupShowing() {
705714
let button = this.menupopup.triggerNode;
706715
this.restoreInNewWindow.hidden = this.restoreInNewPrivateWindow.hidden =
707716
button.getAttribute("restore-type") !== "tab";
@@ -716,19 +725,19 @@ class RecentlyClosedPanelContext {
716725
this.onRestore(e, button);
717726
break;
718727
case this.restoreInNewWindow:
719-
this.onRestoreInNewWindow(e, button, panelview);
728+
this.onRestoreInNewWindow(button, panelview);
720729
break;
721730
case this.restoreInNewPrivateWindow:
722-
this.onRestoreInNewWindow(e, button, panelview, { private: true });
731+
this.onRestoreInNewWindow(button, panelview, { private: true });
723732
break;
724733
case this.removeFromList:
725-
this.onRemoveFromList(e, button);
734+
this.onRemoveFromList(button);
726735
break;
727736
case this.removeFromHistory:
728-
await this.onRemoveFromHistory(e, button);
737+
await this.onRemoveFromHistory(button);
729738
break;
730739
case this.bookmark:
731-
this.onBookmark(e, button, panelview);
740+
this.onBookmark(button, panelview);
732741
break;
733742
default:
734743
return;
@@ -750,14 +759,14 @@ class RecentlyClosedPanelContext {
750759
undoCloseTab(Number(button.getAttribute("value")));
751760
if (e.button === 1) gBrowser.moveTabToEnd();
752761
}
753-
onRestoreInNewWindow(e, button, panelview, params = {}) {
762+
onRestoreInNewWindow(button, panelview, params = {}) {
754763
// open a new window
755764
if (PrivateBrowsingUtils.isWindowPrivate(window)) params.private = true;
756765
let newWin = OpenBrowserWindow(params);
757766
let value = button.getAttribute("value");
758767
let tabData = SessionStore.getClosedTabData(window)[value];
759768
let { state } = tabData;
760-
function init() {
769+
let init = () => {
761770
let tabbrowser = newWin.gBrowser || newWin._gBrowser;
762771
let tab = tabbrowser.addTrustedTab(null, {
763772
pinned: state.pinned,
@@ -770,7 +779,7 @@ class RecentlyClosedPanelContext {
770779
SessionStore.setTabState(tab, state);
771780
SessionStore.forgetClosedTab(window, value);
772781
this.goBackOrHide(panelview, true);
773-
}
782+
};
774783
// wait until the new window's tabbrowser is initialized
775784
if (newWin.gBrowserInit?.delayedStartupFinished) init();
776785
else {
@@ -783,7 +792,7 @@ class RecentlyClosedPanelContext {
783792
Services.obs.addObserver(delayedListener, "browser-delayed-startup-finished");
784793
}
785794
}
786-
onRemoveFromList(e, button) {
795+
onRemoveFromList(button) {
787796
let value = button.getAttribute("value");
788797
switch (button.getAttribute("restore-type")) {
789798
case "tab":
@@ -795,25 +804,25 @@ class RecentlyClosedPanelContext {
795804
}
796805
button.remove();
797806
}
798-
async onRemoveFromHistory(e, button) {
807+
async onRemoveFromHistory(button) {
799808
let working;
800809
switch (button.getAttribute("restore-type")) {
801810
case "tab":
802-
working = await this.forgetClosedTab(e);
811+
working = await this.forgetClosedTab();
803812
break;
804813
case "window":
805-
working = await this.forgetClosedWindow(e);
814+
working = await this.forgetClosedWindow();
806815
break;
807816
}
808817
if (working) button.remove();
809818
}
810-
onBookmark(e, button, panelview) {
819+
onBookmark(button, panelview) {
811820
switch (button.getAttribute("restore-type")) {
812821
case "tab":
813-
this.bookmarkFromTab(e);
822+
this.bookmarkFromTab();
814823
break;
815824
case "window":
816-
this.bookmarkFromWindow(e);
825+
this.bookmarkFromWindow();
817826
break;
818827
}
819828
this.goBackOrHide(panelview, true);
@@ -824,7 +833,7 @@ class RecentlyClosedPanelContext {
824833
entries.forEach((entry) => entry.url && URIs.add(entry.url));
825834
if (URIs.size) await PlacesUtils.history.remove([...URIs]);
826835
}
827-
async forgetClosedTab(e) {
836+
async forgetClosedTab() {
828837
let button = this.menupopup.triggerNode;
829838
let value = button.getAttribute("value");
830839
let tabData = SessionStore.getClosedTabData(window)[value];
@@ -833,7 +842,7 @@ class RecentlyClosedPanelContext {
833842
SessionStore.forgetClosedTab(window, value);
834843
return true;
835844
}
836-
async forgetClosedWindow(e) {
845+
async forgetClosedWindow() {
837846
let button = this.menupopup.triggerNode;
838847
let value = button.getAttribute("value");
839848
let winData = SessionStore.getClosedWindowData()[value];
@@ -844,7 +853,7 @@ class RecentlyClosedPanelContext {
844853
SessionStore.forgetClosedWindow(value);
845854
return true;
846855
}
847-
bookmarkFromTab(e) {
856+
bookmarkFromTab() {
848857
let button = this.menupopup.triggerNode;
849858
let value = button.getAttribute("value");
850859
let tabData = SessionStore.getClosedTabData(window)[value];
@@ -856,7 +865,7 @@ class RecentlyClosedPanelContext {
856865
window.top
857866
);
858867
}
859-
bookmarkFromWindow(e) {
868+
bookmarkFromWindow() {
860869
let button = this.menupopup.triggerNode;
861870
let value = button.getAttribute("value");
862871
let winData = SessionStore.getClosedWindowData()[value];
@@ -870,6 +879,36 @@ class RecentlyClosedPanelContext {
870879
window.top
871880
);
872881
}
882+
onTabItemClick(e) {
883+
let target = e.currentTarget;
884+
if (this.REMOVE_ON_MID_CLICK) {
885+
switch (e.button) {
886+
case 0:
887+
let shiftKey = e.shiftKey;
888+
let accelKey = e.getModifierState("Accel");
889+
if (accelKey) {
890+
if (shiftKey) {
891+
let panelview = target.closest("panelview");
892+
this.onRestoreInNewWindow(target, panelview);
893+
e.preventDefault();
894+
} else break;
895+
}
896+
return;
897+
case 1:
898+
this.onRemoveFromList(target);
899+
// fall through
900+
default:
901+
return;
902+
}
903+
} else if (e.button != 1) return;
904+
undoCloseTab(target.getAttribute("value"));
905+
gBrowser.moveTabToEnd();
906+
let ancestorPanel = target.closest("panel");
907+
if (ancestorPanel) ancestorPanel.hidePopup();
908+
}
909+
onWindowItemClick(e) {
910+
if (this.REMOVE_ON_MID_CLICK && e.button === 1) this.onRemoveFromList(e.currentTarget);
911+
}
873912
}
874913

875914
// wait until the tab context menu exists

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1122,6 +1122,8 @@ Also optionally adds a context menu to the history panel's subview pages for "Re
11221122

11231123
With another option, the script will add container colors to recently closed tab items. As with container tabs in general, this is meant to work in tandem with [Firefox Multi-Account Containers](https://addons.mozilla.org/firefox/addon/multi-account-containers) but does not require the extension, since a slimmer version of it is built into Firefox. If you open a tab with the "Personal" container and then close it and open the recently closed tabs menu, the tab you closed will show up with a little blue stripe on its edge. This feature (and several others) can be configured from within the script file.
11241124

1125+
This script also adds a new preference `userChrome.tabs.recentlyClosedTabs.middle-click-to-remove` which changes the behavior when you click a recently closed tab/window item in the history panel. Middle clicking a tab item or a window item will remove it from the list (just like one of the context menu items). Ctrl + clicking a tab item it will open it in a new tab (instead of restoring it in its former place), and Ctrl + Shift + clicking it will open it in a new _window_.
1126+
11251127
</details>
11261128

11271129
_This script used to be named `undoListInTabContextMenu.uc.js` so make sure you delete that one if you still have it. This version is a huge update._

resources/in-content/site-mozilla.css

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,15 @@
2525
}
2626
}
2727

28+
@-moz-document domain("hg.mozilla.org") {
29+
xmp,
30+
pre,
31+
plaintext {
32+
font-family: Fira Code UC, Fira Code, SF Mono, Menlo, Consolas, Monaco, monospace;
33+
font-weight: 300;
34+
}
35+
}
36+
2837
@-moz-document domain("searchfox.org") {
2938
tt,
3039
code,

0 commit comments

Comments
 (0)