Tontonjo/smart-tab-mute-firefox-extension

★ 0Forks 0JavaScriptGitHub ↗Compare

README

Smart Tab Mute + icon

Smart Tab Mute +

One tab plays. The others stay quiet. And when it stops, the previous one gets its sound back.

Get it on AMO Users Rating Manifest v2 Support

Install for Firefox →


Why

You open a video. Then a second one in another tab. Now two things are playing at once, and you have to hunt for the tab that makes noise.

Smart Tab Mute takes care of it: the tab that starts playing wins, the others are muted, and as soon as it goes quiet the previously playing tab is unmuted — right where you left it.

What it does

  • 🔇 One tab at a time — a tab that starts playing mutes the other audible tabs.
  • 🔊 Gives the sound back — when it stops, the most recently muted tab is unmuted, then the one before it, and so on.
  • ✅ Whitelist — domains that are never muted (calls, meetings, radio).
  • 🙈 Ignore list — domains that never mute the others (notification sounds, games).
  • 🖱️ Click to listen — switching to a tab the add-on muted gives it the sound back and mutes the rest.
  • ✋ Never fights you — a tab you muted or unmuted by hand is left alone.
  • 🕵️ No data collected, no network access, no content script. Just tabs + storage.

Options

Smart Tab Mute + options page
Setting What it does
Whitelist These domains are never muted, whatever else starts playing.
Ignore list When these domains start playing, the other tabs are left alone.
Restore the previous tab Unmute the most recently muted tab when the current one goes quiet.
Unmute a muted tab when I switch to it Switching to a tab muted by the add-on gives it the sound back and mutes the others.
Log activity to the console Verbose logging, for troubleshooting only.

Writing the domain lists

One entry per line. Subdomains are matched automatically, so youtube.com also covers music.youtube.com.

# calls I never want muted
meet.google.com
teams.microsoft.com

# pasted URLs and wildcards work too
https://www.twitch.tv/some/channel   ->  twitch.tv
*.example.org                        ->  example.org

The options page shows, live under each field, the exact list of domains the add-on understands — and flags in orange anything that does not look like a domain name.

How it works

flowchart LR
    A([A tab starts<br/>playing]) --> B{On the<br/>ignore list?}
    B -- yes --> C[The other tabs<br/>are left alone]
    B -- no --> D[Mute the other audible tabs,<br/>whitelisted ones excepted]
    D --> E[(Muted tabs stack)]
    E -- later --> F([That tab goes quiet,<br/>or is closed])
    F --> G{Anything else<br/>still playing?}
    G -- yes --> H[Do nothing]
    G -- no --> I[Unmute the tab<br/>on top of the stack]
Loading

Muted tabs are pushed onto a stack, so restoring works for any number of tabs, not just the last one: mute A, mute B, mute C, and they come back C → B → A. Tabs that get closed, or that the user unmutes by hand, are dropped from the stack along the way.

Troubleshooting

Turn on Log activity to the console in the options, then open about:debugging#/runtime/this-firefox → Inspect next to Smart Tab Mute +. Every decision is printed there: which tab started, which list matched, which tab was muted or restored.

Development

npm install       # dependencies (Grunt only)
npm run build     # assembles build/
npm run dist      # build/ + dist/smart-tab-mute.zip, ready for AMO
npm run watch     # rebuild on every change
npm test          # scenario tests for the muting logic
npm run lint      # ESLint

src/public/ is copied as-is into build/, src/javascripts/ into build/js/. There is no preprocessing step: options.html and css/options.css are plain files.

Load it in Firefox

Run npm run build, open about:debugging#/runtime/this-firefox, click Load Temporary Add-on and pick build/manifest.json. (more about temporary installation)

Tests

test/background.test.js loads the real background.js in a sandbox with a fake WebExtension API and plays the tricky scenarios — subdomain matching, background tabs, stack of several muted tabs, closed tabs, manual mute by the user, whitelist priority. No dependency, no browser needed.

$ npm test
[1] basic mute / restore
  PASS  nothing muted when a single tab plays
  PASS  the previous tab gets muted
  PASS  the previous tab is restored
  ...
All tests passed

Changelog

3.2.0

  • Fixed: the domain lists were compared with a raw substring test, so www.example.com did not match example.com while unrelated domains could match by accident. Lists are now parsed and matched per domain/subdomain.
  • Fixed: when a background tab started playing, the add-on checked the URL of the active tab instead of the one actually playing.
  • Fixed: unmuting a tab id that no longer existed threw an error and could leave every tab muted.
  • Fixed: mixed browser.* / chrome.* calls and a broken if nesting in the tab listener.
  • Fixed: images/icon16.png was a 128px image; proper 16/32/48 icons added.
  • Added: stack of muted tabs, so more than one tab can be restored (previous known issue).
  • Added: manual mute/unmute by the user is now respected.
  • Added: rebuilt options page — live preview of the parsed domains, toggles, auto-save, dark theme, reset to defaults.
  • Added: npm test, scenario tests for the muting logic (no dependency).
  • Changed: build no longer needs Jade/Sass (and therefore node-sass).

Ideas for later

  • When a whitelisted tab is already playing, hold back a new tab instead of letting both play.
  • A toolbar popup listing the audible tabs, with a mute toggle on each.

Credits

Maintained by Tonton Jo — join the community & support my work.

Special thanks to @Gregoux06 who helped a lot in fixing this add-on.

Firefox port of neuling/smart-tab-mute-chrome-extension, itself forked from noniq/smart-tab-mute-chrome-extension.

Contributors

Tontonjononiqneuling

Issues