Skip to content
Merged

Dev #59

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions ContentScript.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
Expand Down
3 changes: 0 additions & 3 deletions WindowScript.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
43 changes: 24 additions & 19 deletions background.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -25,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) => {
Expand All @@ -41,6 +42,11 @@ async function save() {
}

var exclude = [];

// https://github.com/NDevTK/AutoPause/issues/31
const unsupportedWindowScripts = ['https://*.netflix.com/*'];
const unsupportedScripts = [];

async function restore() {
let result = await chrome.storage.session.get('state');
if (typeof result.state === 'object' && result.state !== null) {
Expand All @@ -63,7 +69,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();
}
Expand Down Expand Up @@ -292,7 +298,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, {
Expand Down Expand Up @@ -398,7 +404,7 @@ function autoResume(id) {
hasProperty(options, 'disableresume') ||
state.media.size === 0 ||
(state.otherTabs.size > 0 && !hasProperty(options, 'ignoreother')) ||
state.denyPlayback
state.locked
)
return;
if (
Expand Down Expand Up @@ -487,7 +493,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;
Expand All @@ -498,7 +504,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;
Expand Down Expand Up @@ -617,8 +623,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) {
Expand All @@ -630,15 +636,15 @@ function isUrlExcluded(url) {

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([
{
id: 'ContentScript',
js: ['ContentScript.js'],
matches: p.origins,
excludeMatches: exclude,
excludeMatches: exclude.concat(unsupportedScripts),
allFrames: true,
matchOriginAsFallback: true,
runAt: 'document_start'
Expand All @@ -647,7 +653,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'
Expand All @@ -661,9 +667,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,
Expand All @@ -672,6 +678,7 @@ async function updateExtensionScripts() {
files: ['ContentScript.js'],
injectImmediately: true
});
if (isUrlExcluded(tab.url, unsupportedWindowScripts)) return;
await chrome.scripting.executeScript({
target: {
tabId: tab.id,
Expand All @@ -690,14 +697,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);
}
Expand Down
2 changes: 1 addition & 1 deletion manifest-chrome.json
Original file line number Diff line number Diff line change
@@ -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"
Expand Down
8 changes: 1 addition & 7 deletions manifest-firefox.json
Original file line number Diff line number Diff line change
@@ -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"
Expand Down Expand Up @@ -82,12 +82,6 @@
"name": "NDevTK",
"url": "https://github.com/NDevTK/AutoPause"
},
"web_accessible_resources": [
{
"resources": ["WindowScript.js"],
"matches": ["<all_urls>"]
}
],
"optional_permissions": ["<all_urls>"],
"manifest_version": 3
}
14 changes: 7 additions & 7 deletions options.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,17 @@ <h1>After changes press enter.</h1>
>Exclude Matches (space separated): <br /><input
id="exclude"
size="500"
placeholder="Examples: https://*.youtube.com/*"
placeholder="Examples: zoom or https://meet.google.com/* https://discord.com/* https://teams.live.com/*"
/></label>
<p>
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)
</p>
<br />
<div>
<label for="ignoreother"> Ignore media from other tabs</label
><input type="checkbox" id="ignoreother" />
</div>
<div>
<label for="nopermission">
No permission mode, discards tabs when needed.</label
Expand Down Expand Up @@ -64,11 +68,7 @@ <h1>After changes press enter.</h1>
><input type="checkbox" id="multipletabs" />
</div>
<div>
<label for="ignoreother"> Ignore media from other tabs</label
><input type="checkbox" id="ignoreother" />
</div>
<div>
<label for="permediapause"> Pause per media instead of per tab</label
<label for="permediapause"> Pause per media instead of per tab (Breaks some sites)</label
><input type="checkbox" id="permediapause" />
</div>
<div>
Expand Down
44 changes: 31 additions & 13 deletions options.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.newValue.join(' ');
}
});

function applyChanges() {
Expand Down Expand Up @@ -103,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(' ');
Expand Down Expand Up @@ -149,7 +165,9 @@ async function permissionUpdate() {
}
);
}
chrome.storage.sync.set({
exclude: exclude.value.split(' ').filter((domain) => domain)
});

const newExclude = exclude.value.split(' ').filter((domain) => domain === '<all_urls>' || regex.test(domain));
chrome.storage.sync.set({ exclude: newExclude });
exclude.value = newExclude.join(' ');

}
Loading