Skip to content

Commit

Permalink
fix: sync autoplay option
Browse files Browse the repository at this point in the history
Closes #7.
  • Loading branch information
dessant committed Mar 19, 2023
1 parent 95eb74f commit dd4dda9
Show file tree
Hide file tree
Showing 12 changed files with 237 additions and 197 deletions.
9 changes: 0 additions & 9 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
"@fontsource/roboto": "^4.5.8",
"buffer": "^6.0.3",
"core-js": "^3.29.0",
"js-cookie": "^3.0.1",
"vue": "^3.2.47",
"vuetify": "3.1.7",
"vueton": "^0.3.0",
Expand Down
3 changes: 2 additions & 1 deletion src/assets/manifest/chrome.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,9 @@
"content_scripts": [
{
"matches": ["*://www.youtube.com/*"],
"all_frames": false,
"run_at": "document_start",
"js": ["src/insert/script.js"]
"js": ["src/base/script.js"]
}
],

Expand Down
3 changes: 2 additions & 1 deletion src/assets/manifest/edge.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,9 @@
"content_scripts": [
{
"matches": ["*://www.youtube.com/*"],
"all_frames": false,
"run_at": "document_start",
"js": ["src/insert/script.js"]
"js": ["src/base/script.js"]
}
],

Expand Down
3 changes: 2 additions & 1 deletion src/assets/manifest/firefox.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,9 @@
"content_scripts": [
{
"matches": ["*://www.youtube.com/*"],
"all_frames": false,
"run_at": "document_start",
"js": ["src/insert/script.js"]
"js": ["src/base/script.js"]
}
]
}
111 changes: 43 additions & 68 deletions src/background/main.js
Original file line number Diff line number Diff line change
@@ -1,65 +1,38 @@
import {initStorage, migrateLegacyStorage} from 'storage/init';
import {isStorageReady} from 'storage/storage';
import storage from 'storage/storage';
import {
executeCode,
executeFile,
updateCookie,
getPlatform
} from 'utils/common';
import {getPlatform} from 'utils/common';
import {
showPage,
showOptionsPage,
processAppUse,
processMessageResponse
processMessageResponse,
insertBaseModule
} from 'utils/app';
import {targetEnv} from 'utils/config';

async function syncState(autoplay) {
if (!autoplay) {
({autoplay} = await storage.get('autoplay'));
}

async function syncState() {
const tabs = await browser.tabs.query({url: 'https://www.youtube.com/*'});
for (const tab of tabs) {
const tabId = tab.id;
if (await executeCode(`typeof setSwitchState === 'undefined'`, tabId)) {
await executeFile('/src/content/script.js', tabId);
}
await executeCode(`setSwitchState(${autoplay})`, tabId);
browser.tabs
.sendMessage(tab.id, {id: 'syncState'}, {frameId: 0})
.catch(err => null);
}

const stores = await browser.cookies.getAllCookieStores();
for (const store of stores) {
const params = {
domain: 'youtube.com',
name: 'PREF',
storeId: store.id
};
if (targetEnv === 'firefox') {
params.firstPartyDomain = null;
}
const cookies = await browser.cookies.getAll(params);

for (const cookie of cookies) {
const value = new URLSearchParams(cookie.value);
const autoplayValue = value.get('f5');

if (autoplay && ['30000', '30030'].includes(autoplayValue)) {
value.set('f5', '20000');
await updateCookie(cookie, 'https://www.youtube.com/', {
value: value.toString()
});
continue;
}
await processAppUse();
}

if (!autoplay && [null, '20000', '30', '20030'].includes(autoplayValue)) {
value.set('f5', '30000');
await updateCookie(cookie, 'https://www.youtube.com/', {
value: value.toString()
});
}
}
function getCookieAutoplayValue(cookie) {
// old layout values ('f5') - initial (on): 30, on: 20030, off: 30030
// new layout values ('f5') - initial (on): none, on: 200(0|3)0, off: 300(0|3)0
const autoplayValue = new URLSearchParams(cookie.value).get('f5');

if (['20000', '20030'].includes(autoplayValue)) {
return true;
} else if (['30000', '30030'].includes(autoplayValue)) {
return false;
} else {
return null;
}
}

Expand All @@ -70,27 +43,14 @@ async function onCookieChange(changeInfo) {
cookie.name === 'PREF' &&
!changeInfo.removed
) {
const {autoplay} = await storage.get('autoplay');

// old layout values ('f5') - initial (on): 30, on: 20030, off: 30030
// new layout values ('f5') - initial (on): none, on: 200(0|3)0, off: 300(0|3)0
const value = new URLSearchParams(cookie.value);
const autoplayValue = value.get('f5');

if (autoplay && ['30000', '30030'].includes(autoplayValue)) {
return await storage.set({autoplay: false});
}
const autoplayValue = getCookieAutoplayValue(cookie);

if (!autoplay) {
if ([null, '30'].includes(autoplayValue)) {
value.set('f5', '30000');
return await updateCookie(cookie, 'https://www.youtube.com/', {
value: value.toString()
});
}
if (autoplayValue !== null) {
const {autoplay} = await storage.get('autoplay');

if (['20000', '20030'].includes(autoplayValue)) {
return await storage.set({autoplay: true});
if (autoplayValue !== autoplay) {
await storage.set({autoplay: autoplayValue});
await syncState();
}
}
}
Expand Down Expand Up @@ -146,6 +106,18 @@ async function onActionButtonClick(tab) {
await showOptionsPage({activeTab: tab});
}

async function onInstall(details) {
if (
['install', 'update'].includes(details.reason) &&
['chrome', 'edge', 'opera', 'samsung'].includes(targetEnv)
) {
await insertBaseModule({
url: 'https://www.youtube.com/*',
allFrames: false
});
}
}

function addBrowserActionListener() {
browser.browserAction.onClicked.addListener(onActionButtonClick);
}
Expand All @@ -158,18 +130,21 @@ function addCookieListener() {
browser.cookies.onChanged.addListener(onCookieChange);
}

function addInstallListener() {
browser.runtime.onInstalled.addListener(onInstall);
}

async function setup() {
if (!(await isStorageReady())) {
await migrateLegacyStorage();
await initStorage();
}

await syncState();
}

function init() {
addBrowserActionListener();
addMessageListener();
addInstallListener();
addCookieListener();

setup();
Expand Down
127 changes: 127 additions & 0 deletions src/base/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
import storage from 'storage/storage';
import {findNode} from 'utils/common';

const contentStorage = {
autoplay: false,
videoNodes: []
};

function addVideo(video) {
if (!contentStorage.videoNodes.includes(video)) {
contentStorage.videoNodes.push(video);

const events = ['play', 'progress', 'ended'];
for (const event of events) {
video.addEventListener(event, setAutoplay);
}
}
}

function removeVideo(video) {
const index = contentStorage.videoNodes.indexOf(video);

if (index !== -1) {
contentStorage.videoNodes.splice(index, 1);

const events = ['play', 'progress', 'ended'];
for (const event of events) {
video.removeEventListener(event, setAutoplay);
}
}
}

async function setAutoplay() {
const button = await findNode(
'.ytp-right-controls button[data-tooltip-target-id="ytp-autonav-toggle-button"]',
{throwError: false}
);

if (button) {
const isOn = button.querySelector('[aria-checked="true"]') !== null;
if (contentStorage.autoplay !== isOn) {
button.click();
}
}
}

function syncAutoplay(autoplay) {
contentStorage.autoplay = autoplay;

setAutoplay();
}

function syncPlaylistAutoplay(autoplay) {
const script = document.createElement('script');
script.textContent = `(async function() {
const manager = await ${findNode.toString()}('yt-playlist-manager', {
throwError: false
});
if (manager) {
Object.defineProperty(manager, 'canAutoAdvance_', {
get: function() {
return ${autoplay};
},
set: function() {}
});
}
})()`;
document.documentElement.appendChild(script);
script.remove();
}

async function syncState() {
const {autoplay, autoplayPlaylist} = await storage.get([
'autoplay',
'autoplayPlaylist'
]);

syncAutoplay(autoplay);
syncPlaylistAutoplay(autoplayPlaylist);
}

function onMessage(request, sender) {
// Samsung Internet 13: extension messages are sometimes also dispatched
// to the sender frame.
if (sender.url === document.URL) {
return;
}

if (request.id === 'syncState') {
syncState();
}
}

function setup() {
const videos = document.getElementsByTagName('video');
for (const video of videos) {
addVideo(video);
}

const observer = new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) {
mutation.addedNodes.forEach(function (node) {
if (node.nodeName.toLowerCase() === 'video') {
addVideo(node);
}
});

mutation.removedNodes.forEach(function (node) {
if (node.nodeName.toLowerCase() === 'video') {
removeVideo(node);
}
});
});
});

observer.observe(document, {childList: true, subtree: true});

syncState();
}

function init() {
browser.runtime.onMessage.addListener(onMessage);

setup();
}

init();
25 changes: 0 additions & 25 deletions src/content/main.js

This file was deleted.

Loading

0 comments on commit dd4dda9

Please sign in to comment.