GithubHelp home page GithubHelp logo

tabmixplus's Introduction

tabmix-header


Tab Mix Plus is a very popular legacy extension for the Mozilla Firefox browser that enhances Firefox's tab browsing abilities. It includes such features as duplicating tabs, controlling tab focus, tab clicking options, undo closed tabs and windows, plus much more.

Session Manager feature is not included at the moment since it requires complete rewrite.

If you are interested in keeping Tab Mix Plus working, please donate. Donate


Exciting News! ✨

Excited to Announce a New Home for Tab Mix Plus Documentation!

I'm thrilled to share the launch of a brand-new website dedicated to the Tab Mix Plus extension documentation! If you've been looking for clearer instructions, smoother navigation, and an overall better experience with Tab Mix Plus documentation, this site is for you.

Here's what you can expect:

  • Step-by-step installation: Getting started with Tab Mix Plus just got easier thanks to detailed instructions and troubleshooting tips. Read More

  • Modern design: Say goodbye to clutter and hello to a clean, contemporary interface that's easy to read and navigate.

  • Improved search: Find the information you need instantly with my enhanced search functionality.

  • Accessible everywhere: Whether you're on a desktop, tablet, or mobile phone, the responsive design ensures a smooth experience.

I encourage you to explore the new documentation website and share your feedback! Your input is invaluable in helping me continuously improve the documentation and make it even more helpful for everyone.

Ready to take a look?


Table of Contents

Installation

  1. Legacy extensions loader
    Since Firefox removed the internal component that loads legacy extension, in order to install Tab Mix Plus, or any other legacy extension, you have to install 3rd party helper scripts.

    1.1. Open about:support and locate the path to your Application Binary and Profile Folder.

    screenshoot

    firefox

    1.2. Install configuration files to your Application Binary folder.

    fx-folder.zip files are packed with paths used by Firefox for Windows, Linux and MacOS users should follow the instructions below.

    Linux

    Note: The default path to Firefox on Linux is typically /usr/lib/firefox/.

    Verify the path:

    Check the actual path to your Firefox Application Binary. If it differs from /usr/lib/firefox/, replace the path accordingly in the following instructions.

    Copy the configuration files extracted from fx-folder.zip:

    • copy config.js to /usr/lib/firefox/config.js
    • copy config-prefs.js to /usr/lib/firefox/browser/defaults/preferences/config-prefs.js
    Linux with Snap

    Compatibility Note:

    Firefox snap for Linux versions prior to 108 are not supported.

    Instructions for Firefox snap 108 or newer

    Verify installation path:

    If you're uncertain about the installation path of your Firefox snap, use the command snap list firefox in your terminal to check.

    Copy the configuration files extracted from fx-folder.zip:

    • copy config.js to /etc/firefox/config.js
    • copy config-prefs.js to /etc/firefox/defaults/pref/config-prefs.js

    Create subfolders if necessary

    If the folders /defaults or /pref don't exist within /etc/firefox/ create them.

    MacOs

    Note:

    The default path to Firefox on MacOs is typically Firefox.app/Contents/Resources.

    Verify the path:

    Check the actual path to your Firefox Application Binary. If it differs from Firefox.app/Contents/Resources, replace the path accordingly in the following instructions.

    Copy the configuration files extracted from fx-folder.zip:

    • copy config.js to Firefox.app/Contents/Resources/config.js
    • copy config-prefs.js to Firefox.app/Contents/Resources/defaults/pref/config-prefs.js

    1.3. Create chrome folder in your Profile Folder (if one does not exist).

    1.4. Extract utils folder inside the chrome folder, the result should be [PROFILE_NAME]/chrome/utils, all the files should be in the utils folder (see the screenshot below).

    screenshoot

    firefox

    1.5. Open about:support page and click "Clear startup cache…" to force Firefox to load the installed scripts on the next startup.

    1.6. Start Firefox again.

    1.7. Follow the instructions below to install Tab Mix Plus.

  2. Download XPI

    Download xpi file from our releases page to your local computer.

    All Tab Mix Plus downloads are also located here.

    If you are using Firefox Beta, Developer Edition or Nightly we recommend using the latest Tab Mix Plus development build (tags with pre or test-build in the title)

  3. Install XPI

    To install the file you have just downloaded:

    • Open Add-ons Manager tab (about:addons) and select Extensions.
      or
      Click the menu button ☰, click Add-ons and Themes and select Extensions.
    • To add the downloaded add-on to the list of available add-ons, drag and drop the file into the Add-ons window. The add-on is added to the list.
    • The installation process should begin.

Troubleshooting

If Tab Mix Plus stops working after Firefox update was installed or when you try to install Tab Mix you get a message that it appears to be corrupt, follow these instructions

  • Uninstall Tab Mix Plus.

  • Close Firefox and reinstall the latest versions of these scripts (see instructions above):

    • Install configuration files to your Application Binary folder.

    • Extract utils folder to chrome in your in your Profile Folder.

  • Some users report that their Firefox is not able to install or use Tab Mix Plus unless they set extensions.experiments.enabled to true in about:config.

  • Open about:support page and click "Clear startup cache…" to force Firefox to load the installed scripts on the next startup.

  • After Firefox starts Reinstall latest Tab Mix Plus again.

Browser Compatibility

  • Firefox 78 - Firefox Nightly
  • Waterfox G3 - G6 and beyond

For Pale Moon download Tab Mix Plus from here

Configuration

Tab Mix Plus comes with Options window that includes all of its preferences as well as adding user interface to important Firefox hidden preferences. It is recommended that you make all changes to the preference in the options window. The options window is available from the Add-ons Manager or from the Tools menu (unless you turn this option off).

Docs

Read the docs (please 🙏):

Help

Troubleshooting

Change Log

tabmixplus's People

Contributors

117649 avatar jaxkr avatar onemen avatar piroor avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tabmixplus's Issues

Cannot open any entries from the Library window

Getting the following error when trying to open any bookmark/history entry from the Library window (Ctrl + Shift + H)
Opening from the bookmarks toolbar, or library pop-up pane works (although history doesn't remember the container but I don't know if that's related to TMP)

Uncaught ReferenceError: BrowserWindowTracker is not defined
    getBrowserWindow chrome://tabmix-resource/content/Places.jsm:39
    PUIU_openNodeWithEvent chrome://tabmix-resource/content/Places.jsm line 71 > eval:4
    CT_openSelectedNode chrome://browser/content/places/places.js:1451
    CT_onClick chrome://browser/content/places/places.js:1461
    onclick chrome://browser/content/places/places.xhtml:1
Places.jsm:39:1

Firefox Developer Edition 87.0b9
Clean profile no other add-ons
Config only modified to allow for unsigned add-ons
Default TMP preferences

Firefox now has built-in spacers in tittle bar while window not maximized

/* :::: Space on tab bar :::: */
#tabbrowser-tabs[tabBarSpace] > .tabbrowser-arrowscrollbox {

change

#tabbrowser-tabs[tabBarSpace] > .tabbrowser-arrowscrollbox

to

#tabbrowser-tabs[tabBarSpace] > #tabbrowser-arrowscrollbox 

Will make the "Extra spaces on both sides" option function but it does look awkward when the browser window is not maximized.
May be adding more rules to take built-in spacer into consideration or directly manipulate them.

Localization

Report here about any issue with localization or If you are willing to work on translation

My Firefox Developer Edition 87.0b5 is not loading bootstrap addons right

I'm trying use multiple bootstrap addons and found that browser startup have a big chance been interrupt and hangs especially when having more than one addons enabled and restore a session. (most of the UI are loaded but not the tabs of restored session, tool bar button's menu, booksmark bar items)
I'm using script loader for addons.
And Tab Groups just not been loaded while browser start.
Are you seeing any of this?

Addons:
roomybookmarksredux
TMP
Tab-Groups

Main context menu need update

Error in the console from Firefox 91 - nightly

08:50:51.242 Tabmix:
TMP_updateMainContextMenu was unable to change gContextMenu.openLinkInTab.
can't find string
    /allowMixedContent:|charset:/

Try Tabmix latest development version from tabmixplus.org/tab_mix_plus-dev-build.xpi,
Report about this to Tabmix developer at http://tabmixplus.org/forum/
3 click.js:698:7

Screenshot Firefox 91 - nightly
menu

Tab relation detection not working

Due to the change of the Firefox we now no longer have a referrerURI in params.
referrerInfo seems replaced it.

gBrowser.addTab = function(...args) {
let dontMove, isPending, referrerURI, relatedToCurrent = null,
callerTrace = Tabmix.callerTrace(),
isRestoringTab = callerTrace.contain("ssi_restoreWindow"),
openerBrowser;
// we prevents the original function from moving the new tab by setting
// params.relatedToCurrent to false
let params = args[1];
if (args.length <= 6 && params &&
(typeof params != "object" || params instanceof Ci.nsIURI)) {
referrerURI = params;
params = {
referrerURI,
charset: args[2],
postData: args[3],
ownerTab: args[4],
allowThirdPartyFixup: args[5],
};
let uri = args[0];
args = [uri, params];
} else if (args.length == 2 &&
typeof params == "object" &&
!(params instanceof Ci.nsIURI)) {
dontMove = params.dontMove;
isPending = params.isPending;
referrerURI = params.referrerURI;
relatedToCurrent = params.relatedToCurrent || null;
openerBrowser = params.openerBrowser;
args[1] = params;
}
if (relatedToCurrent === null) {
relatedToCurrent = Boolean(referrerURI);
}

https://github.com/mozilla/gecko-dev/blob/0db73daa4b03ce7513a7dd5f31109143dc3b149e/browser/base/content/tabbrowser.js#L1616-L1641

New Tab options are broken

Two are broken options are broken

  1. setting/resetting custom New Tab Page (browser.newtab.url) not working.
    This function throw an error on both option. Tabmix not working at all when Firefox start with browser.newtab.url not as "about:newtab"
  modules/NewTabURL.jsm
  updateNewTabURL() {
    let value = Services.prefs.getStringPref(FIREFOX_PREF);
    if (value == ABOUT_NEW_TAB) {
      aboutNewTabService.resetNewTabURL();
    } else {
      aboutNewTabService.newTabURL = value;
    }
  }
  1. setting this option to Home page prevents any new tab command (clicking on new tab button, using shortcut)
  userInterface.js:48:7
  Uncaught ReferenceError: gHomeButton is not defined
  TMP_BrowserOpenTab chrome://tabmixplus/content/links/userInterface.js:48
  oncommand chrome://browser/content/browser.xhtml:1

new_tab

Changing permission submenu (from tab context menu) throw an error

 NS_ERROR_FILE_NOT_FOUND: content.js:74
      receiveMessage chrome://tabmixplus/content/scripts/content.js:74
      (Async: MessageListener.receiveMessage)
      init chrome://tabmixplus/content/scripts/content.js:58
      forEach self-hosted:205
      init chrome://tabmixplus/content/scripts/content.js:58
      <anonymous> chrome://tabmixplus/content/scripts/content.js:519

Error when using data-l10n localization

when window start i see this error in the console

23:11:16.682 [Exception... "Component returned failure code: 0x80520001 (NS_ERROR_FILE_UNRECOGNIZED_PATH) [nsIXPCComponents_Utils.readUTF8URI]"  nsresult: "0x80520001 (NS_ERROR_FILE_UNRECOGNIZED_PATH)"  location: "JS frame :: resource://gre/modules/L10nRegistry.jsm :: L10nRegistry.loadSync :: line 692"  data: no] 2 L10nRegistry.jsm:692:19

The error when loading the preference window, Uncaught (in promise) undefined also related to l10n.
when i removed all data-l10n attribute from the xhtml files (menu.xhtml, mouse.xhtml) the error is gone.

However Firefox stile crashing when loading from Add-ons page so it probably not related.

MergeWindows - Place popups next to their openers not working

let openerTab = tabbrowser._getTabForContentWindow(openerWindow);

@117649 ,

Old code to Place popups next to their openers does not work.

  1. the function gBrowser._getTabForContentWindow was removed.
  2. "Tabmix:collectOpener" content message listener does not work.

using browser.ownerGlobal.opener return ChromeWindow and i don't know how to get the opener tab from it
let me know if you can find solution to this issue.

I can also remove this option and just merge popup window at the end

Merge Windows in tab context menu not working

Error:

Uncaught TypeError: Services.wm.getZOrderDOMWindowEnumerator is not a function
    getWindowsList chrome://tabmix-resource/content/MergeWindows.jsm:266
    _mergeWindows chrome://tabmix-resource/content/MergeWindows.jsm:44
    oncommand chrome://browser/content/browser.xhtml:1

'Services.wm.getZOrderDOMWindowEnumerator' is no more but there is a 'Services.wm.getZOrderAppWindowEnumerator'.
I'll bet they just change the name.

Removed: Reload skip cache – for bookmarks open in tabs

I have just removed this feature (commit a0c1fca)

Reason for removing it:

  • it does not work!!, and throw an error:
    [Exception... "Component returned failure code: 0x80004001
    (NS_ERROR_NOT_IMPLEMENTED) [nsIRequest.loadFlags]"  nsresult:
    "0x80004001 (NS_ERROR_NOT_IMPLEMENTED)"  location: "JS frame ::
    chrome://tabmixplus/content/tab/tab.js :: TMP_onStateChange ::
    line 2660"  data: no]
  • it was only used by:
    • our session manager that now doesn't work.
    • when user open group of bookmarks while the feature Load tabs progressively was on.

@117649, i don't find important but if you know about a simple fix let me know.

Add option to toggle compact mode for tab height

We can add option to toggle compact mode for tab height, with a simple checkbox.
compact: preference browser.uidensity = 1
normal: preference browser.uidensity = 0

Currently in Firefox 91 the value for compact height is 29px.

We can also add slider to allow the user to set custom height, values can be from 21px to 40px

event.target.localName not match tab or tabs

event.target.localName gBrowser.tabContainer no longer match tab or tabs

we need to scan the code and replace event.target.localName with the proper value
some of the issues related to #21 and #26 caused by this issue

Firefox crashing when loading Tab Mix options from Add-ons

Firefox crashing when loading Tab Mix options from Add-ons:
it crash when trying to open options from this view (all extensions):
image

but it work OK from extension view (only Tab mix):
image

Originally posted by @onemen in #17 (comment)

I think i have a fix for this issue.
The problem is in aboutaddons.js, we add click event for the option button after load event and from MutationObserver.
when you open Add-ons tabs for the first time both load event and mutation add click listener to the button.
when we click it both listeners runs and Firefox try to open the same window twice

It work for me with this patch, if it look right to you i will commit it

diff --git a/addon/chrome/content/preferences/overlay/aboutaddons.js b/addon/chrome/content/preferences/overlay/aboutaddons.js
index 14d8f245..f296fbe2 100644
--- a/addon/chrome/content/preferences/overlay/aboutaddons.js
+++ b/addon/chrome/content/preferences/overlay/aboutaddons.js
@@ -38,13 +38,16 @@ function updateShowItemPreferences() {
   //   }
   const tabmixItem = getHtmlBrowser().contentDocument.querySelector(`addon-card[addon-id="${ID}"]`);
   if (tabmixItem) {
-    tabmixItem.querySelector(`panel-item[action="preferences"]`)
-        .button.addEventListener("click", event => {
-          event.stopPropagation();
-          try {
-            windowRoot.ownerGlobal.Tabmix.openOptionsDialog(-1);
-          } catch (ex) { }
-        });
+    const optionsButton = tabmixItem.querySelector(`panel-item[action="preferences"]`).button;
+    optionsButton._tabmix_command_installed = true;
+    if (!optionsButton._tabmix_command_installed) {
+      optionsButton.addEventListener("click", event => {
+        event.stopPropagation();
+        try {
+          windowRoot.ownerGlobal.Tabmix.openOptionsDialog(-1);
+        } catch (ex) { }
+      });
+    }
   }
   // const addonOptionsItem = getHtmlBrowser().contentDocument.querySelector(`template[name="addon-options"]`).content.querySelector(`[action="preferences"]`);
   // addonOptionsItem.setAttribute("onclick",

Be careful with prefs-ce.js

I've just tried packing a new .xpi from rewrite/main after some css change. And the add-on option dialog window broken thus I have to revert most changes done on the 'prefs-ce.js'
Since the old add-on dialog is planed to be replaced may be just leave the file as it is.

#7

Can not open Options window with Firefox Nightly 93 build 2021-08-11

19:02:09.146 XML Parsing Error: undefined entity
Location: moz-nullprincipal:{2902ddbc-8191-47f0-b59b-099122e6dc7d}
Line Number 9, Column 9: {2902ddbc-8191-47f0-b59b-099122e6dc7d}:9:9
19:02:09.146
Uncaught Error: not well-formed XML
    parseXULToFragment chrome://global/content/customElements.js:566
    connectedCallback chrome://tabmixplus/content/preferences/prefs-ce.js:1091
    setDialog chrome://tabmixplus/content/preferences/preferences.js:722
    onload chrome://tabmixplus/content/preferences/preferences.xhtml:1
customElements.js:566:17
    parseXULToFragment chrome://global/content/customElements.js:566
    connectedCallback chrome://tabmixplus/content/preferences/prefs-ce.js:1091
    setDialog chrome://tabmixplus/content/preferences/preferences.js:722
    onload chrome://tabmixplus/content/preferences/preferences.xhtml:1

Append button not create good widgets

I just got Fx86.0b4 dropped.
Then:
ReferenceError: Windows is not defined Overlays.jsm:755:5
Shows up and it look like everything else is not load correctly due to it.

code for close button on tab need update

legacy code:

          <xul:toolbarbutton anonid="tmp-close-button"
                             xbl:inherits="fadein,pinned,selected,visuallyselected"
                             class="tab-close-button close-icon"/>

changed to:

         <image class="tab-close-button close-icon" role="presentation"/>

these places need update

7 results - 4 files

addon\chrome\content\click\click.js:
   32      this._blockDblClick = target.classList.contains("tabs-newtab-button") ||
   33:       !Tabmix.isVersion(270) && leftClick && anonid == "tmp-close-button";
   34  

   36      if (leftClick &&
   37:         (anonid == "tmp-close-button" || aEvent.target._overPlayingIcon ||
   38           target.localName == "toolbarbutton")) {

   44      if (aEvent.button == 1 && target.localName == "toolbarbutton" &&
   45:         anonid != "tmp-close-button") {
   46        return;

  113      // don't do anything if user left click on tab or tabbar button
  114:     if (anonid == "tmp-close-button" || aEvent.target._overPlayingIcon ||
  115          target.localName == "toolbarbutton") {

addon\chrome\content\extensions\extensions.js:
  296          'node = doc.getAnonymousElementByAttribute(tab, "class", "tab-close-button");',
  297:         'node = doc.getAnonymousElementByAttribute(tab, "anonid", "tmp-close-button");', {silent: true}
  298        )._replace(

addon\chrome\content\minit\minit.js:
  170      if (event.originalTarget && typeof event.originalTarget.getAttribute == "function" &&
  171:         event.originalTarget.getAttribute("anonid") == "tmp-close-button") {
  172        event.stopPropagation();

addon\chrome\content\tab\tabBindings.js:
  256          aEvent.originalTarget.getAttribute("anonid");
  257:       if (anonid == "tmp-close-button") {
  258          this.mOverCloseButton = aOver;

Rename tab function not working

I'm trying to fix it. And got some positive result. Have you already worked on that?
Just want to be sure I'm not reinventing wheel.

I'll make a PR for the fix as soon as finish if it is needed.

Remove all remining xul files

chrome\content\dialogs\about.xul
chrome\content\extensions\sage.xul
chrome\content\extensions\wizzrss.xul
chrome\content\links\links.xul
chrome\content\overlay\newtab.xul
chrome\content\overlay\removeblanktab.xul
chrome\content\preferences\overlay\incontentpreferences.xul
chrome\content\preferences\overlay\main.xul
chrome\content\preferences\overlay\overlaysanitizeui.xul
chrome\content\preferences\overlay\tabs.xul

These files are leftover for our legacy extension
some of the files already converted to xhtml.

File that are not yet converted to xhtml should either be converted or deleted with its related js file/code

Tabmix Options window spinners (html:input type="number") should have a min value

Some spinner are missing min value.

For Tab Width (id="minWidth" id="maxWidth") the min value should be the size of pinned tab

Changing the value for Dispkay > Tab Bar > Scroll Delay id="scrollDelay" throw an error TypeError: setting getter-only property "_scrollDelay", I will address this issue but the pref need a min

there are others without a min.

@117649 can you take this one ?

Can we remove progress meter on tabs?

I think that progress meter on tabs is obsolete.
with the new design of burst animation it have no real value to the user.

according to my testing, for most of the tab the progress value get at most 2 hits, the value change from 0 to 50% to 80% and 100%. it also happens to fast to be visible.

Maybe we can improve the code to get move visible update, but it stile think that we don't really need it.

How to use extension from folder on development

In the good old days before Webextensions I could place a file in profile/extensions folder with a link to my working directory.
that configuration eliminate the need to create XPI file and install it after each change

for extension with id [email protected] the file name was the same as the id ([email protected])
and its content was

path\to\working\direcory

Is it possible to do the same with Firefox nightly when using helper loader ?

How to use helper loader

@117649, you post this on #3

For the Firefox versions compatibility it is a little bizarre situation here:

1. For the latest Waterfox G3 which is based on Firefox 78ESR the compatibility should just be straightforward.

2. You need a [helper](https://github.com/117649/firefox-scripts) to load the bootstrap legacy add-on, Waterfox already came with one.

3. The helper came in two types [extension](https://github.com/117649/firefox-scripts/tree/master/extensions/bootstrapLoader) and [script](https://github.com/117649/firefox-scripts/tree/master/chrome/utils). I would consider the one waterfox provided is script type.

4. The two types of the helper CAN co-exist BUT SHOULD NOT since this will cause two helper in the browser and load every bootstrap legacy add-on twice. Which will cause problem.

If i understand it correctly, the user of Tab Mix Plus will have to install the helper loader (script or extension), we are not going to wrap the loader with Tab Mix xpi file

new tab button on tabs bar not displayed right while option set to "After last tab"

If the tabs is overflowing the new tab button will not show.
At this moment disable and re-enable the option would cause new tab button show on right of the tab bar and it will stay on there even if tabs stop overflow.
Stop overflowing disable and re-enable the option can make new tab button show after last tab.
Found out that when disable then re-enable the option the attribute would be set to "right-side" regardless what the menu selection is while tab bar is overflowing.
image

Error in auto reload

Error when auto reload try to reload tab

18:30:01.899 TypeError: docShell.QueryInterface(...).sessionHistory.QueryInterface is not a functioncontent.js:129:14
    receiveMessage chrome://tabmixplus/content/scripts/content.js:129
    (Async: MessageListener.receiveMessage)
    init chrome://tabmixplus/content/scripts/content.js:65
    forEach self-hosted:206
    init chrome://tabmixplus/content/scripts/content.js:65
    <anonymous> chrome://tabmixplus/content/scripts/content.js:555

auto reload code is in AutoReload.jsm

Error when clicking on a link

    TypeError: can't access property "mixedContentChannel", this.docShell is undefined 
    contentAreaClick chrome://tabmixplus/content/scripts/content.js:332
    handleEvent chrome://tabmixplus/content/scripts/content.js:216
    (Async: EventListener.handleEvent)
    init chrome://tabmixplus/content/scripts/content.js:210
    <anonymous> chrome://tabmixplus/content/scripts/content.js:556
content.js:332:11

Merging codes that is greatly different between old and new.

So, this:

let warnAboutClosingTabs = function(whatToClose, aTab, aDomain) {
      // see Tabmix.tablib.closeWindow comment
      if (Tabmix.callerTrace("BG__onQuitRequest")) {
        return true;
      }
      var closing = this.closingTabsEnum;
      // try to catch call from other extensions to warnAboutClosingTabs (before Firefox 24)
      if (typeof (whatToClose) == "boolean")
        whatToClose = whatToClose ? closing.ALL_ONEXIT : closing.OTHER;

      var onExit = whatToClose == closing.ALL_ONEXIT;
      var tabs = !onExit ? this.visibleTabs : this.tabs;
      var numTabs = tabs.length;
      // calc the number of tab to close when there is protected tabs.
      let protectedTabs = [];
      function addProtected(aTabs) {
        for (let i = 0; i < aTabs.length; i++) {
          let tab = aTabs[i];
          if (protectedTabs.indexOf(tab) == -1 &&
              (onExit || !tab.hidden)) {
            protectedTabs.push(aTabs[i]);
          }
        }
      }
      // we always restore pinned tabs no need to warn about closing
      if (this._numPinnedTabs && !onExit) {
        addProtected(this.tabContainer.getElementsByAttribute("pinned", true));
      }
      if ("permaTabs" in window) {
        addProtected(this.tabContainer.getElementsByAttribute("isPermaTab", true));
      }
      addProtected(this.tabContainer.getElementsByAttribute("protected", true));

      var numProtected = protectedTabs.length;
      var shouldPrompt = 0;
      var prefs = ["extensions.tabmix.tabs.warnOnClose",
        "extensions.tabmix.protectedtabs.warnOnClose",
        "browser.tabs.warnOnClose"];
      if (onExit) {
        let openTabs = numTabs - this._removingTabs.length;
        if (openTabs > 1 && Services.prefs.getBoolPref(prefs[2]))
          shouldPrompt = 3;
        else if (numProtected > 0 && Services.prefs.getBoolPref(prefs[1]))
          shouldPrompt = 2;
      } else if (numTabs > 1) {
        if (Services.prefs.getBoolPref(prefs[0]))
          shouldPrompt = 1;
        // when we close window with last tab and we don't have protected tabs
        // we need to warn the user with the proper warning
        if (Services.prefs.getBoolPref("browser.tabs.closeWindowWithLastTab") &&
            !Tabmix.prefs.getBoolPref("keepLastTab") &&
            Services.prefs.getBoolPref(prefs[2])) {
          if (whatToClose == closing.GROUP)
            shouldPrompt = -1;
          else if (whatToClose == closing.ALL && numProtected === 0 &&
              numTabs == this.tabs.length) {
            whatToClose = closing.ALL_ONEXIT;
            shouldPrompt = 3;
          }
        }
      }

      if (shouldPrompt === 0)
        return true;

      var tabPos, tabsToClose = 0;
      switch (whatToClose) {
        case closing.ALL:
          tabsToClose = numTabs - numProtected;
          break;
        case closing.ALL_ONEXIT:
          tabsToClose = numTabs - this._removingTabs.length;
          break;
        case closing.OTHER:
          if (!aTab)
            aTab = this.mCurrentTab;
          if (aTab._isProtected)
            --numProtected;
          tabsToClose = numTabs - 1 - numProtected;
          break;
        case closing.GROUP:
          for (let i = numTabs - 1; i > -1; --i) {
            let tab = tabs[i];
            if (this.getBrowserForTab(tab).currentURI.spec.indexOf(aDomain) != -1 &&
                !tab._isProtected)
              tabsToClose++;
          }
          if (shouldPrompt == -1) {
            if (tabsToClose == this.tabs.length)
              shouldPrompt = 3;
            else if (Services.prefs.getBoolPref(prefs[0]))
              shouldPrompt = 1;
            else
              return true;
          }
          break;
        case closing.TO_END:
          if (!aTab)
            throw new Error("Required argument missing: aTab");
          tabPos = tabs.indexOf(aTab);
          for (let i = 0; i < protectedTabs.length; i++) {
            let index = tabs.indexOf(protectedTabs[i]);
            if (index <= tabPos)
              --numProtected;
          }
          tabsToClose = numTabs - tabPos - 1 - numProtected;
          break;
        case closing.TO_START:
          if (!aTab)
            throw new Error("Required argument missing: aTab");
          tabPos = tabs.indexOf(aTab);
          for (let i = 0; i < protectedTabs.length; i++) {
            let index = tabs.indexOf(protectedTabs[i]);
            if (index >= tabPos)
              --numProtected;
          }
          tabsToClose = tabPos - numProtected;
          break;
        default:
          throw new Error("Invalid argument: " + whatToClose);
      }

      if (whatToClose != closing.ALL_ONEXIT && tabsToClose == numTabs &&
          Tabmix.prefs.getBoolPref("keepLastTab"))
        tabsToClose--;

      if (tabsToClose <= 1 && shouldPrompt < 2)
        return true;

      // default to true: if it were false, we wouldn't get this far
      var warnOnClose = {value: true};

      var message, chkBoxLabel;
      if (shouldPrompt == 1 || numProtected === 0) {
        if (Tabmix.isVersion(290)) {
          message = PluralForm.get(tabsToClose, Tabmix.getString("tabs.closeWarningMultiple"))
              .replace("#1", tabsToClose);
        } else {
          message = Tabmix.getFormattedString("tabs.closeWarningMultipleTabs", [tabsToClose]);
        }
        chkBoxLabel = shouldPrompt == 1 ? Tabmix.getString("tabs.closeWarningPromptMe") :
          TabmixSvc.getString("window.closeWarning.2");
      } else {
        let messageKey = "protectedtabs.closeWarning.";
        messageKey += (numProtected < tabsToClose) ? "3" : (numProtected == 1) ? "1" : "2";
        message = TabmixSvc.getFormattedString(messageKey, [tabsToClose, numProtected]);
        var chkBoxKey = shouldPrompt == 3 ? "window.closeWarning.2" : "protectedtabs.closeWarning.5";
        chkBoxLabel = TabmixSvc.getString(chkBoxKey);
      }

      var buttonLabel = shouldPrompt == 1 ? Tabmix.getString("tabs.closeButtonMultiple") :
        TabmixSvc.getString("closeWindow.label");

      window.focus();
      var promptService = Services.prompt;
      var buttonPressed = promptService.confirmEx(window,
        Tabmix.getString("tabs.closeWarningTitle"),
        message,
        (promptService.BUTTON_TITLE_IS_STRING * promptService.BUTTON_POS_0) +
        (promptService.BUTTON_TITLE_CANCEL * promptService.BUTTON_POS_1),
        buttonLabel,
        null, null,
        chkBoxLabel,
        warnOnClose);
      var reallyClose = (buttonPressed === 0);
      // don't set the pref unless they press OK and it's false
      if (reallyClose && !warnOnClose.value) {
        Services.prefs.setBoolPref(prefs[shouldPrompt - 1], false);
      }

      return reallyClose;
    };

has to be merge into this:

warnAboutClosingTabs(tabsToClose, aCloseTabs) {
      if (tabsToClose <= 1) {
        return true;
      }

      const pref =
        aCloseTabs == this.closingTabsEnum.ALL
          ? "browser.tabs.warnOnClose"
          : "browser.tabs.warnOnCloseOtherTabs";
      var shouldPrompt = Services.prefs.getBoolPref(pref);
      if (!shouldPrompt) {
        return true;
      }

      const maxTabsUndo = Services.prefs.getIntPref(
        "browser.sessionstore.max_tabs_undo"
      );
      if (
        aCloseTabs != this.closingTabsEnum.ALL &&
        tabsToClose <= maxTabsUndo
      ) {
        return true;
      }

      var ps = Services.prompt;

      // default to true: if it were false, we wouldn't get this far
      var warnOnClose = { value: true };

      // focus the window before prompting.
      // this will raise any minimized window, which will
      // make it obvious which window the prompt is for and will
      // solve the problem of windows "obscuring" the prompt.
      // see bug #350299 for more details
      window.focus();
      let warningMessage = gTabBrowserBundle.GetStringFromName(
        "tabs.closeWarningMultiple"
      );
      warningMessage = PluralForm.get(tabsToClose, warningMessage).replace(
        "#1",
        tabsToClose
      );
      let flags =
        ps.BUTTON_TITLE_IS_STRING * ps.BUTTON_POS_0 +
        ps.BUTTON_TITLE_CANCEL * ps.BUTTON_POS_1;
      let checkboxLabel =
        aCloseTabs == this.closingTabsEnum.ALL
          ? gTabBrowserBundle.GetStringFromName("tabs.closeWarningPromptMe")
          : null;
      var buttonPressed = ps.confirmEx(
        window,
        gTabBrowserBundle.GetStringFromName("tabs.closeTitleTabs"),
        warningMessage,
        flags,
        gTabBrowserBundle.GetStringFromName("tabs.closeButtonMultiple"),
        null,
        null,
        checkboxLabel,
        warnOnClose
      );
      var reallyClose = buttonPressed == 0;

      // don't set the pref unless they press OK and it's false
      if (
        aCloseTabs == this.closingTabsEnum.ALL &&
        reallyClose &&
        !warnOnClose.value
      ) {
        Services.prefs.setBoolPref(pref, false);
      }

      return reallyClose;
    },

Any ideals?

Mouse clicking not working.

Error log for Close Tab and Open anew tab not seeing any others so far.

TypeError: can't access property "audioMuted", browser is undefined
TabState.jsm:108:9
    _collectBaseTabData resource:///modules/sessionstore/TabState.jsm:108
    collect resource:///modules/sessionstore/TabState.jsm:67
    collect resource:///modules/sessionstore/TabState.jsm:34
    ssi_onTabClose resource:///modules/sessionstore/SessionStore.jsm:2667
    ssi_handleEvent resource:///modules/sessionstore/SessionStore.jsm:1616
    _beginRemoveTab chrome://tabmixplus/content/changecode.js line 218 > eval:155
    removeTab chrome://browser/content/tabbrowser.js:3386
    removeTab chrome://tabmixplus/content/minit/tablib.js:255
    TMP_doCommand chrome://tabmixplus/content/click/click.js:156
    TMP_clickAction chrome://tabmixplus/content/click/click.js:137
    TMP_onTabBarDblClick chrome://tabmixplus/content/click/click.js:129
    handleEvent chrome://tabmixplus/content/tab/tab.js:748
TypeError: can't access property "isRemoteBrowser", e.target.linkedBrowser is undefined
Browsers.jsm:170:8
    handleEvent chrome://tabgroups-resource/content/modules/utils/Browsers.jsm:170
    _beginRemoveTab chrome://tabmixplus/content/changecode.js line 218 > eval:155
    removeTab chrome://browser/content/tabbrowser.js:3386
    removeTab chrome://tabmixplus/content/minit/tablib.js:255
    TMP_doCommand chrome://tabmixplus/content/click/click.js:156
    TMP_clickAction chrome://tabmixplus/content/click/click.js:137
    TMP_onTabBarDblClick chrome://tabmixplus/content/click/click.js:129
    handleEvent chrome://tabmixplus/content/tab/tab.js:748
TypeError: can't access property "ownerGlobal", aBrowser is undefined
PrivateBrowsingUtils.jsm:40:21
    isBrowserPrivate resource://gre/modules/PrivateBrowsingUtils.jsm:40
    isPrivateTab chrome://browser/content/parent/ext-browser.js:44
    emitRemoved chrome://browser/content/parent/ext-browser.js:746
    handleEvent chrome://browser/content/parent/ext-browser.js:578
    _beginRemoveTab chrome://tabmixplus/content/changecode.js line 218 > eval:155
    removeTab chrome://browser/content/tabbrowser.js:3386
    removeTab chrome://tabmixplus/content/minit/tablib.js:255
    TMP_doCommand chrome://tabmixplus/content/click/click.js:156
    TMP_clickAction chrome://tabmixplus/content/click/click.js:137
    TMP_onTabBarDblClick chrome://tabmixplus/content/click/click.js:129
    handleEvent chrome://tabmixplus/content/tab/tab.js:748
Uncaught TypeError: can't access property "registeredOpenURI", browser is undefined
    _beginRemoveTab chrome://tabmixplus/content/changecode.js line 218 > eval:188
    removeTab chrome://browser/content/tabbrowser.js:3386
    removeTab chrome://tabmixplus/content/minit/tablib.js:255
    TMP_doCommand chrome://tabmixplus/content/click/click.js:156
    TMP_clickAction chrome://tabmixplus/content/click/click.js:137
    TMP_onTabBarDblClick chrome://tabmixplus/content/click/click.js:129
    handleEvent chrome://tabmixplus/content/tab/tab.js:748

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.