Use History API when available

This commit is contained in:
Anton Bershanskiy
2022-05-25 00:13:02 +03:00
parent e948e1e569
commit 9b9ea39260
3 changed files with 52 additions and 8 deletions

View File

@@ -23,13 +23,34 @@ if (utils.isFirefox()) {
}); });
} }
chrome.tabs.onUpdated.addListener(function(tabId) { function onTabUpdatedListener(tabId: number) {
chrome.tabs.sendMessage(tabId, { chrome.tabs.sendMessage(tabId, {
message: 'update', message: 'update',
}, () => void chrome.runtime.lastError ); // Suppress error on Firefox }, () => void chrome.runtime.lastError ); // Suppress error on Firefox
}); }
chrome.runtime.onMessage.addListener(function (request, sender, callback) { function onNavigationApiAvailableChange(changes: {[key: string]: chrome.storage.StorageChange}) {
if (changes.navigationApiAvailable) {
if (changes.navigationApiAvailable.newValue) {
chrome.tabs.onUpdated.removeListener(onTabUpdatedListener);
} else {
chrome.tabs.onUpdated.addListener(onTabUpdatedListener);
}
}
}
// If Navigation API is not supported, then background has to inform content script about video change.
// This happens on Safari, Firefox, and Chromium 101 (inclusive) and below.
utils.wait(() => Config.local !== null).then(() => {
if (!Config.local.navigationApiAvailable)
chrome.tabs.onUpdated.addListener(onTabUpdatedListener);
})
if (!Config.configSyncListeners.includes(onNavigationApiAvailableChange)) {
Config.configSyncListeners.push(onNavigationApiAvailableChange);
}
chrome.runtime.onMessage.addListener(function (request, _, callback) {
switch(request.message) { switch(request.message) {
case "openConfig": case "openConfig":
chrome.tabs.create({url: chrome.runtime.getURL('options/options.html' + (request.hash ? '#' + request.hash : ''))}); chrome.tabs.create({url: chrome.runtime.getURL('options/options.html' + (request.hash ? '#' + request.hash : ''))});

View File

@@ -101,9 +101,11 @@ export type VideoDownvotes = { segments: { uuid: HashedValue, hidden: SponsorHid
interface SBStorage { interface SBStorage {
/* VideoID prefixes to UUID prefixes */ /* VideoID prefixes to UUID prefixes */
downvotedSegments: Record<VideoID & HashedValue, VideoDownvotes>, downvotedSegments: Record<VideoID & HashedValue, VideoDownvotes>,
navigationApiAvailable: boolean,
} }
export interface SBObject { export interface SBObject {
configLocalListeners: Array<(changes: StorageChangesObject) => unknown>;
configSyncListeners: Array<(changes: StorageChangesObject) => unknown>; configSyncListeners: Array<(changes: StorageChangesObject) => unknown>;
syncDefaults: SBConfig; syncDefaults: SBConfig;
localDefaults: SBStorage; localDefaults: SBStorage;
@@ -120,6 +122,7 @@ const Config: SBObject = {
/** /**
* Callback function when an option is updated * Callback function when an option is updated
*/ */
configLocalListeners: [],
configSyncListeners: [], configSyncListeners: [],
syncDefaults: { syncDefaults: {
userID: null, userID: null,
@@ -283,7 +286,8 @@ const Config: SBObject = {
} }
}, },
localDefaults: { localDefaults: {
downvotedSegments: {} downvotedSegments: {},
navigationApiAvailable: null,
}, },
cachedSyncConfig: null, cachedSyncConfig: null,
cachedLocalStorage: null, cachedLocalStorage: null,
@@ -310,6 +314,10 @@ function configProxy(): { sync: SBConfig, local: SBStorage } {
for (const key in changes) { for (const key in changes) {
Config.cachedLocalStorage[key] = changes[key].newValue; Config.cachedLocalStorage[key] = changes[key].newValue;
} }
for (const callback of Config.configLocalListeners) {
callback(changes);
}
} }
}); });

View File

@@ -2204,3 +2204,18 @@ function checkForPreloadedSegment() {
Config.forceSyncUpdate("unsubmittedSegments"); Config.forceSyncUpdate("unsubmittedSegments");
} }
} }
// Register listener for URL change via Navigation API
const navigationApiAvailable = "navigation" in window;
if (navigationApiAvailable) {
// TODO: Remove type cast once type declarations are updated
(window as unknown as { navigation: EventTarget }).navigation.addEventListener("navigate", () => videoIDChange(getYouTubeVideoID(document)));
}
// Record availability of Navigation API
utils.wait(() => Config.local !== null).then(() => {
if (Config.local.navigationApiAvailable !== navigationApiAvailable) {
Config.local.navigationApiAvailable = navigationApiAvailable;
Config.forceLocalUpdate("navigationApiAvailable");
}
});