From 10b14f06779fadba9195e3615e987270ba00eba8 Mon Sep 17 00:00:00 2001
From: NDevTK <31563761+NDevTK@users.noreply.github.com>
Date: Wed, 12 Nov 2025 20:37:31 +0000
Subject: [PATCH 01/18] Update background.js
---
background.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/background.js b/background.js
index b5a9662..a9abdf3 100644
--- a/background.js
+++ b/background.js
@@ -292,7 +292,7 @@ chrome.commands.onCommand.addListener(async (command) => {
chrome.tabs.update(tabs[0].id, {
active: true
});
- } else if (media.size > 0) {
+ } else if (state.media.size > 0) {
const result = getResumeTab();
if (result !== false) {
chrome.tabs.update(result, {
From 068aa819b5d50db470465c11a6490cb8b5b213ad Mon Sep 17 00:00:00 2001
From: NDevTK <31563761+NDevTK@users.noreply.github.com>
Date: Sun, 16 Nov 2025 03:05:01 +0000
Subject: [PATCH 02/18] Stop running scripts on calls
Fixes #58
---
background.js | 20 ++++++++++++++------
1 file changed, 14 insertions(+), 6 deletions(-)
diff --git a/background.js b/background.js
index a9abdf3..68c3d80 100644
--- a/background.js
+++ b/background.js
@@ -14,6 +14,7 @@ const setItems = [
];
var options = {};
+
state.media = new Set(); // List of tabs with media.
state.backgroundaudio = new Set();
state.mediaPlaying = null; // Tab ID of active media.
@@ -41,6 +42,12 @@ async function save() {
}
var exclude = [];
+
+// https://github.com/NDevTK/AutoPause/issues/31
+const unsupportedWindowScripts = ['https://*.netflix.com/*'];
+// Calls shouldn't work the same as other media if you get a call you probably want to hear it and when playing a video you likely don't want to mute the other person https://github.com/NDevTK/AutoPause/issues/58
+const unsupportedScripts = ['https://meet.google.com/*', 'https://discord.com/*', 'https://*.zoom.us/*'];
+
async function restore() {
let result = await chrome.storage.session.get('state');
if (typeof result.state === 'object' && result.state !== null) {
@@ -617,8 +624,8 @@ function matchPatternToRegExp(pattern) {
return new RegExp(re);
}
-function isUrlExcluded(url) {
- return exclude.some((pattern) => {
+function isUrlExcluded(url, extra = []) {
+ return exclude.concat(extra).some((pattern) => {
try {
return matchPatternToRegExp(pattern).test(url);
} catch (e) {
@@ -638,7 +645,7 @@ async function updateContentScripts() {
id: 'ContentScript',
js: ['ContentScript.js'],
matches: p.origins,
- excludeMatches: exclude,
+ excludeMatches: exclude.concat(unsupportedContentScripts),
allFrames: true,
matchOriginAsFallback: true,
runAt: 'document_start'
@@ -647,7 +654,7 @@ async function updateContentScripts() {
id: 'WindowScript',
js: ['WindowScript.js'],
matches: p.origins,
- excludeMatches: exclude,
+ excludeMatches: exclude.concat(unsupportedScripts).concat(unsupportedWindowScripts),
allFrames: true,
runAt: 'document_start',
world: 'MAIN'
@@ -661,9 +668,9 @@ async function updateExtensionScripts() {
await updateContentScripts();
const tabs = await chrome.tabs.query({});
tabs.forEach(async (tab) => {
- if (!tab.url || !tab.id || isUrlExcluded(tab.url)) return;
+ if (!tab.url || !tab.id) return;
chrome.tabs.sendMessage(tab.id, {type: 'hi ya!'}).catch(async () => {
- if (isUrlExcluded(tab.url)) return;
+ if (isUrlExcluded(tab.url, unsupportedScripts)) return;
await chrome.scripting.executeScript({
target: {
tabId: tab.id,
@@ -672,6 +679,7 @@ async function updateExtensionScripts() {
files: ['ContentScript.js'],
injectImmediately: true
});
+ if (isUrlExcluded(tab.url, unsupportedWindowScripts)) return;
await chrome.scripting.executeScript({
target: {
tabId: tab.id,
From bd8baaa4c6c302ff6a513abeff88ceeedbb0672e Mon Sep 17 00:00:00 2001
From: NDevTK <31563761+NDevTK@users.noreply.github.com>
Date: Sun, 16 Nov 2025 03:06:10 +0000
Subject: [PATCH 03/18] Prevented script injection
---
WindowScript.js | 3 ---
1 file changed, 3 deletions(-)
diff --git a/WindowScript.js b/WindowScript.js
index aeb4869..148ad14 100644
--- a/WindowScript.js
+++ b/WindowScript.js
@@ -3,9 +3,6 @@
(function () {
'use strict';
- // https://github.com/NDevTK/AutoPause/issues/31
- if (location.origin.endsWith('.netflix.com')) return;
-
// This is okay because the HTMLMediaElement prototype gets hooked.
// Note to self: DO NOT CHANGE NAME
if (window.autoPauseExtensionInjected) return;
From 8976a7214dd9953704c9ea1787284c82a1205463 Mon Sep 17 00:00:00 2001
From: NDevTK <31563761+NDevTK@users.noreply.github.com>
Date: Sun, 16 Nov 2025 03:08:03 +0000
Subject: [PATCH 04/18] unsupportedScripts
#58
---
background.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/background.js b/background.js
index 68c3d80..7d1a7e3 100644
--- a/background.js
+++ b/background.js
@@ -645,7 +645,7 @@ async function updateContentScripts() {
id: 'ContentScript',
js: ['ContentScript.js'],
matches: p.origins,
- excludeMatches: exclude.concat(unsupportedContentScripts),
+ excludeMatches: exclude.concat(unsupportedScripts),
allFrames: true,
matchOriginAsFallback: true,
runAt: 'document_start'
From 00f9a8fa733bcd58d0d40b12eee12331ba797eae Mon Sep 17 00:00:00 2001
From: NDevTK <31563761+NDevTK@users.noreply.github.com>
Date: Sun, 16 Nov 2025 03:30:58 +0000
Subject: [PATCH 05/18] Apply filter for excluded matches
Better UI #58
---
options.js | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/options.js b/options.js
index cd62a13..dd18858 100644
--- a/options.js
+++ b/options.js
@@ -50,6 +50,9 @@ chrome.storage.onChanged.addListener((result) => {
options = result.options.newValue;
applyChanges();
}
+ if (typeof result.exclude === 'object' && result.exclude !== null && Array.isArray(result.exclude.newValue)) {
+ exclude.value = result.exclude.join(' ');
+ }
});
function applyChanges() {
@@ -150,6 +153,8 @@ async function permissionUpdate() {
);
}
chrome.storage.sync.set({
- exclude: exclude.value.split(' ').filter((domain) => domain)
+ exclude: exclude.value.split(' ').filter(
+ (domain) => domain === '' || regex.test(domain)
+ );
});
}
From 75471e218c9f0ff67a064a577bced393dc792783 Mon Sep 17 00:00:00 2001
From: NDevTK <31563761+NDevTK@users.noreply.github.com>
Date: Sun, 16 Nov 2025 03:40:10 +0000
Subject: [PATCH 06/18] Update ContentScript.js
---
ContentScript.js | 2 --
1 file changed, 2 deletions(-)
diff --git a/ContentScript.js b/ContentScript.js
index eb48f48..3d7c359 100644
--- a/ContentScript.js
+++ b/ContentScript.js
@@ -300,8 +300,6 @@ async function resume(shouldPlay) {
});
}
-function validElement(e) {}
-
function checkShadow(DOM = document) {
// If we are checking this document also check documentPictureInPicture
if (
From 52df36b3f117208e0b3952713a174e8d2cec511e Mon Sep 17 00:00:00 2001
From: NDevTK <31563761+NDevTK@users.noreply.github.com>
Date: Sun, 16 Nov 2025 03:43:56 +0000
Subject: [PATCH 07/18] Update options.js
---
options.js | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/options.js b/options.js
index dd18858..219ea89 100644
--- a/options.js
+++ b/options.js
@@ -154,7 +154,7 @@ async function permissionUpdate() {
}
chrome.storage.sync.set({
exclude: exclude.value.split(' ').filter(
- (domain) => domain === '' || regex.test(domain)
- );
+ (domain) => domain === '' || regex.test(domain)
+ )
});
}
From 425a3e0b9867d45c22fb2f8c2b181b67775d71f1 Mon Sep 17 00:00:00 2001
From: NDevTK <31563761+NDevTK@users.noreply.github.com>
Date: Sun, 16 Nov 2025 03:46:22 +0000
Subject: [PATCH 08/18] Update options.js
---
options.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/options.js b/options.js
index 219ea89..0e52169 100644
--- a/options.js
+++ b/options.js
@@ -51,7 +51,7 @@ chrome.storage.onChanged.addListener((result) => {
applyChanges();
}
if (typeof result.exclude === 'object' && result.exclude !== null && Array.isArray(result.exclude.newValue)) {
- exclude.value = result.exclude.join(' ');
+ exclude.value = result.exclude.newValue.join(' ');
}
});
From d56c45733f5c2d8d2cb0b5eb59ef92b9a8b57f03 Mon Sep 17 00:00:00 2001
From: NDevTK <31563761+NDevTK@users.noreply.github.com>
Date: Sun, 16 Nov 2025 04:06:51 +0000
Subject: [PATCH 09/18] If no change was made still update input
#58
---
options.js | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/options.js b/options.js
index 0e52169..53e155c 100644
--- a/options.js
+++ b/options.js
@@ -152,9 +152,9 @@ async function permissionUpdate() {
}
);
}
- chrome.storage.sync.set({
- exclude: exclude.value.split(' ').filter(
- (domain) => domain === '' || regex.test(domain)
- )
- });
+
+ const newExclude = exclude.value.split(' ').filter((domain) => domain === '' || regex.test(domain));
+ chrome.storage.sync.set({ exclude: newExclude });
+ exclude.value = newExclude.join(' ');
+
}
From f3a8943adb9aa8c8b8135936c3a9ad72e3d98a28 Mon Sep 17 00:00:00 2001
From: NDevTK <31563761+NDevTK@users.noreply.github.com>
Date: Sun, 16 Nov 2025 04:09:06 +0000
Subject: [PATCH 10/18] Update background.js
---
background.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/background.js b/background.js
index 7d1a7e3..5eaa02a 100644
--- a/background.js
+++ b/background.js
@@ -70,7 +70,7 @@ restore();
chrome.storage.onChanged.addListener((result) => {
if (typeof result.options === 'object' && result.options !== null)
options = result.options.newValue;
- if (typeof result.exclude === 'object' && result.exclude !== null) {
+ if (typeof result.exclude === 'object' && result.exclude !== null && Array.isArray(result.exclude.newValue)) {
exclude = result.exclude.newValue;
updateContentScripts();
}
From 96f6607507fdf5b96f6c23a9ea25933361b1166a Mon Sep 17 00:00:00 2001
From: NDevTK <31563761+NDevTK@users.noreply.github.com>
Date: Sun, 16 Nov 2025 04:15:11 +0000
Subject: [PATCH 11/18] Fix race
#58
---
background.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/background.js b/background.js
index 5eaa02a..d8a480f 100644
--- a/background.js
+++ b/background.js
@@ -637,8 +637,8 @@ function isUrlExcluded(url, extra = []) {
async function updateContentScripts() {
await initializationCompletePromise;
- await chrome.scripting.unregisterContentScripts();
chrome.permissions.getAll(async (p) => {
+ await chrome.scripting.unregisterContentScripts();
if (p.origins.length < 1) return;
await chrome.scripting.registerContentScripts([
{
From 262e889ad73bcdb8bf41e5758c7b761e4f5a9bc2 Mon Sep 17 00:00:00 2001
From: NDevTK <31563761+NDevTK@users.noreply.github.com>
Date: Sun, 16 Nov 2025 04:28:58 +0000
Subject: [PATCH 12/18] Remove waslocked
---
background.js | 18 ++++++++----------
1 file changed, 8 insertions(+), 10 deletions(-)
diff --git a/background.js b/background.js
index d8a480f..fd0662d 100644
--- a/background.js
+++ b/background.js
@@ -26,7 +26,7 @@ state.ignoredTabs = new Set();
state.mutedMedia = new Set(); // Tab IDs of resumable muted media.
state.legacyMedia = new Set(); // Tab IDs of old media.
state.autoPauseWindow = null;
-state.denyPlayback = false;
+state.locked = false;
let resolveInitialization;
const initializationCompletePromise = new Promise((resolve) => {
@@ -405,7 +405,7 @@ function autoResume(id) {
hasProperty(options, 'disableresume') ||
state.media.size === 0 ||
(state.otherTabs.size > 0 && !hasProperty(options, 'ignoreother')) ||
- state.denyPlayback
+ state.locked
)
return;
if (
@@ -494,7 +494,7 @@ chrome.tabs.onUpdated.addListener(async (tabId, changeInfo, tab) => {
function denyPlay(tab, userActivation = false) {
// Security: Logic used to determine if videos are not allowed to play.
- if (state.denyPlayback) return true;
+ if (state.locked) return true;
if (userActivation) return false;
if (tab.id === state.activeTab) return false;
if (tab.id === state.lastPlaying) return false;
@@ -505,7 +505,7 @@ function denyPlay(tab, userActivation = false) {
async function denyPause(id, exclude, skipLast, allowbg, auto) {
// Security: Logic used to determine if the extension is not allowed to pause automatically.
- if (state.denyPlayback) return false;
+ if (state.locked) return false;
if (id === exclude) return true;
if (allowbg && state.backgroundaudio.has(id)) return true;
if (skipLast && id === state.lastPlaying) return true;
@@ -698,14 +698,12 @@ async function checkIdle(userState) {
await initializationCompletePromise;
if (!hasProperty(options, 'checkidle')) return;
if (userState === 'locked') {
- state.waslocked = true;
- // Security: While locked no media should be playing and state.denyPlayback should stay true.
- state.denyPlayback = true;
+ // Security: While locked no media should be playing and state.locked should stay true.
+ state.locked = true;
// Pause everything
pauseAll();
- } else if (state.waslocked) {
- state.waslocked = false;
- state.denyPlayback = false;
+ } else if (state.locked) {
+ state.locked = false;
const tabId = getResumeTab();
if (tabId !== false) play(tabId);
}
From d5cc8ef5871072e10d4cee862d02c761b5cd299b Mon Sep 17 00:00:00 2001
From: NDevTK <31563761+NDevTK@users.noreply.github.com>
Date: Sun, 16 Nov 2025 04:39:16 +0000
Subject: [PATCH 13/18] Update options.html
---
options.html | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/options.html b/options.html
index e658824..6170491 100644
--- a/options.html
+++ b/options.html
@@ -26,6 +26,10 @@
After changes press enter.
needed to detect audio.
+
+
+
After changes press enter.
-
-
-
From f77bf3594521e50640b327760edc0d4f7695941e Mon Sep 17 00:00:00 2001
From: NDevTK <31563761+NDevTK@users.noreply.github.com>
Date: Sun, 16 Nov 2025 04:42:50 +0000
Subject: [PATCH 14/18] Update manifest-chrome.json
---
manifest-chrome.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/manifest-chrome.json b/manifest-chrome.json
index 98528a9..f20b3e4 100644
--- a/manifest-chrome.json
+++ b/manifest-chrome.json
@@ -1,6 +1,6 @@
{
"name": "AutoPause",
- "version": "2.8.9",
+ "version": "2.9.0",
"description": "Pause other audio and video sources if audio is playing on active tab with automatic resume",
"content_security_policy": {
"extension_pages": "default-src 'none'; script-src 'self'; frame-ancestors 'none'; form-action 'none'; upgrade-insecure-requests; block-all-mixed-content"
From 64b2d03e5f91a620044250a1984355a7fc509a63 Mon Sep 17 00:00:00 2001
From: NDevTK <31563761+NDevTK@users.noreply.github.com>
Date: Sun, 16 Nov 2025 04:43:39 +0000
Subject: [PATCH 15/18] Update manifest-firefox.json
---
manifest-firefox.json | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)
diff --git a/manifest-firefox.json b/manifest-firefox.json
index b7146f7..735e882 100644
--- a/manifest-firefox.json
+++ b/manifest-firefox.json
@@ -1,6 +1,6 @@
{
"name": "AutoPause",
- "version": "2.8.9",
+ "version": "2.9.0",
"description": "Pause other audio and video sources if audio is playing on active tab with automatic resume",
"content_security_policy": {
"extension_pages": "default-src 'none'; script-src 'self'; frame-ancestors 'none'; form-action 'none'; upgrade-insecure-requests; block-all-mixed-content"
@@ -82,12 +82,6 @@
"name": "NDevTK",
"url": "https://github.com/NDevTK/AutoPause"
},
- "web_accessible_resources": [
- {
- "resources": ["WindowScript.js"],
- "matches": [""]
- }
- ],
"optional_permissions": [""],
"manifest_version": 3
}
From 221a21c0c2c3973b042b01ca1a8d4f7f572421f3 Mon Sep 17 00:00:00 2001
From: NDevTK <31563761+NDevTK@users.noreply.github.com>
Date: Sun, 16 Nov 2025 17:41:13 +0000
Subject: [PATCH 16/18] Update background.js
---
background.js | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/background.js b/background.js
index fd0662d..49e9c8b 100644
--- a/background.js
+++ b/background.js
@@ -45,8 +45,7 @@ var exclude = [];
// https://github.com/NDevTK/AutoPause/issues/31
const unsupportedWindowScripts = ['https://*.netflix.com/*'];
-// Calls shouldn't work the same as other media if you get a call you probably want to hear it and when playing a video you likely don't want to mute the other person https://github.com/NDevTK/AutoPause/issues/58
-const unsupportedScripts = ['https://meet.google.com/*', 'https://discord.com/*', 'https://*.zoom.us/*'];
+const unsupportedScripts = [];
async function restore() {
let result = await chrome.storage.session.get('state');
From 9631094646451ca70bed224c26bbea4f7a1eb041 Mon Sep 17 00:00:00 2001
From: NDevTK <31563761+NDevTK@users.noreply.github.com>
Date: Sun, 16 Nov 2025 17:54:18 +0000
Subject: [PATCH 17/18] Update options.js
---
options.js | 33 +++++++++++++++++++++++----------
1 file changed, 23 insertions(+), 10 deletions(-)
diff --git a/options.js b/options.js
index 53e155c..d774b9f 100644
--- a/options.js
+++ b/options.js
@@ -106,19 +106,32 @@ const common = new Map([
['pandora', 'https://*.pandora.com/*'],
['wrif', 'https://wrif.com/*'],
['ustvgo', 'https://ustvgo.tv/*'],
- ['picarto', 'https://picarto.tv/*']
+ ['picarto', 'https://picarto.tv/*'],
+ ['meet', 'https://meet.google.com/*'],
+ ['discord', 'https://discord.com/*'],
+ ['zoom', 'https://*.zoom.us/*'],
+ ['teams', 'https://teams.live.com/*'],
+ ['messenger', 'https://www.messenger.com/*'],
+ ['whatsapp', 'https://web.whatsapp.com/*'],
+ ['twitter', 'https://x.com/*'],
+ ['facebook', 'https://www.facebook.com/*']
]);
-userinput.oninput = () => {
- let result = userinput.value.split(' ');
- for (let [index, value] of result.entries()) {
- const key = value.toLowerCase();
- if (common.has(key)) {
- result[index] = common.get(key);
+function autoComplete(e) {
+ e.oninput = () => {
+ let result = e.value.split(' ');
+ for (let [index, value] of result.entries()) {
+ const key = value.toLowerCase();
+ if (common.has(key)) {
+ result[index] = common.get(key);
+ }
}
- }
- userinput.value = result.join(' ');
-};
+ e.value = result.join(' ');
+ };
+}
+
+autoComplete(userinput);
+autoComplete(exclude);
async function permissionUpdate() {
const domains = userinput.value.split(' ');
From 29199002877a0f5279be09e7009b9aa9bdbd997f Mon Sep 17 00:00:00 2001
From: NDevTK <31563761+NDevTK@users.noreply.github.com>
Date: Sun, 16 Nov 2025 18:03:32 +0000
Subject: [PATCH 18/18] Moved to a user-configurable system instead of forcing
it.
#58
---
options.html | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/options.html b/options.html
index 6170491..2040bd6 100644
--- a/options.html
+++ b/options.html
@@ -19,11 +19,11 @@
After changes press enter.
>Exclude Matches (space separated):
This permission is needed to pause, resume and fast forward media its not
- needed to detect audio.
+ needed to detect audio (You can opt-out of detecting media from other tabs below)
@@ -68,7 +68,7 @@
After changes press enter.
>
- Pause per media instead of per tab (Breaks some sites)