12
.github/workflows/ci.yml
vendored
@@ -14,7 +14,7 @@ jobs:
|
|||||||
- uses: actions/setup-node@v1
|
- uses: actions/setup-node@v1
|
||||||
- run: npm install
|
- run: npm install
|
||||||
- name: Copy configuration
|
- name: Copy configuration
|
||||||
run: cp config.js.example config.js
|
run: cp config.json.example config.json
|
||||||
|
|
||||||
# Create Chrome artifacts
|
# Create Chrome artifacts
|
||||||
- name: Create Chrome artifacts
|
- name: Create Chrome artifacts
|
||||||
@@ -22,17 +22,15 @@ jobs:
|
|||||||
- uses: actions/upload-artifact@v1
|
- uses: actions/upload-artifact@v1
|
||||||
with:
|
with:
|
||||||
name: Chrome Extension
|
name: Chrome Extension
|
||||||
path: web-ext-artifacts
|
path: dist
|
||||||
|
|
||||||
# Create Firefox artifacts
|
# Create Firefox artifacts
|
||||||
- name: Move manifest
|
- name: Move manifest
|
||||||
run: mv manifest.json manifest.json.original
|
run: mv ./dist/manifest.json ./dist/manifest.json.original
|
||||||
- name: Combine manifest for Firefox
|
- name: Combine manifest for Firefox
|
||||||
run: jq -s '.[0] * .[1]' manifest.json.original firefox_manifest-extra.json > manifest.json
|
run: jq -s '.[0] * .[1]' ./dist/manifest.json.original ./dist/firefox_manifest-extra.json > manifest.json
|
||||||
- name: Create Firefox artifacts
|
|
||||||
run: npm run build
|
|
||||||
- uses: actions/upload-artifact@v1
|
- uses: actions/upload-artifact@v1
|
||||||
with:
|
with:
|
||||||
name: Firefox Extension
|
name: Firefox Extension
|
||||||
path: web-ext-artifacts
|
path: dist
|
||||||
|
|
||||||
|
|||||||
4
.gitignore
vendored
@@ -1,6 +1,8 @@
|
|||||||
config.js
|
config.json
|
||||||
ignored
|
ignored
|
||||||
.idea/
|
.idea/
|
||||||
node_modules
|
node_modules
|
||||||
web-ext-artifacts
|
web-ext-artifacts
|
||||||
.vscode/
|
.vscode/
|
||||||
|
dist/
|
||||||
|
tmp/
|
||||||
@@ -50,13 +50,13 @@ You can read the API docs [here](https://github.com/ajayyy/SponsorBlockServer#ap
|
|||||||
|
|
||||||
# Build Yourself
|
# Build Yourself
|
||||||
|
|
||||||
You can load this project as an unpacked extension. Make sure to rename the `config.js.example` file to `config.js` before installing.
|
You can load this project as an unpacked extension. Make sure to rename the `config.json.example` file to `config.json` before installing.
|
||||||
|
|
||||||
There are also other build scripts available. Install `npm`, then run `npm install` in the repository.
|
There are also other build scripts available. Install `npm`, then run `npm install` in the repository.
|
||||||
|
|
||||||
## Developing with a clean profile
|
## Developing with a clean profile
|
||||||
|
|
||||||
Run `npm run dev` to run the extension using a clean browser profile with hot reloading [(by default Firefox)](https://hacks.mozilla.org/2019/10/developing-cross-browser-extensions-with-web-ext-3-2-0/). This uses [`web-ext run`](https://extensionworkshop.com/documentation/develop/web-ext-command-reference/#commands).
|
Run `npm run dev` to run the extension using a clean browser profile with hot reloading. Use `npm run dev:firefox` for Firefox. This uses [`web-ext run`](https://extensionworkshop.com/documentation/develop/web-ext-command-reference/#commands).
|
||||||
|
|
||||||
## Packing
|
## Packing
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
//this file is loaded along iwth content.js
|
|
||||||
//this file sets the server to connect to, and is gitignored
|
|
||||||
var serverAddress = "https://api.sponsor.ajay.app";
|
|
||||||
4
config.json.example
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"serverAddress": "https://sponsor.ajay.app",
|
||||||
|
"serverAddressComment": "This specifies the default SponsorBlock server to conect to"
|
||||||
|
}
|
||||||
8
jest.config.js
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
module.exports = {
|
||||||
|
"roots": [
|
||||||
|
"src"
|
||||||
|
],
|
||||||
|
"transform": {
|
||||||
|
"^.+\\.ts$": "ts-jest"
|
||||||
|
},
|
||||||
|
};
|
||||||
5405
package-lock.json
generated
31
package.json
@@ -3,14 +3,35 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "background.js",
|
"main": "background.js",
|
||||||
"dependencies": {},
|
"dependencies": {
|
||||||
|
"concurrently": "^5.1.0"
|
||||||
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"web-ext": "^4.0.0"
|
"web-ext": "^4.0.0",
|
||||||
|
"@types/chrome": "0.0.91",
|
||||||
|
"@types/firefox-webext-browser": "70.0.1",
|
||||||
|
"@types/jest": "^24.0.23",
|
||||||
|
"@types/jquery": "^3.3.31",
|
||||||
|
"copy-webpack-plugin": "^5.0.5",
|
||||||
|
"jest": "^24.9.0",
|
||||||
|
"ts-jest": "^24.2.0",
|
||||||
|
"rimraf": "^3.0.0",
|
||||||
|
"ts-loader": "^6.2.1",
|
||||||
|
"typescript": "~3.7.3",
|
||||||
|
"webpack": "~4.41.2",
|
||||||
|
"webpack-cli": "~3.3.10",
|
||||||
|
"webpack-merge": "~4.2.2"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "echo \"Error: no test specified\" && exit 1",
|
"web-run": "npm run web-run:chrome",
|
||||||
"dev": "web-ext run --start-url https://chrome.google.com/webstore/detail/ublock-origin/cjpalhdlnbpafiamejdnhcphjbkeiagm",
|
"web-run:firefox": "cd dist && web-ext run --start-url https://chrome.google.com/webstore/detail/ublock-origin/cjpalhdlnbpafiamejdnhcphjbkeiagm",
|
||||||
"build": "web-ext build --overwrite-dest -i \"*(package-lock.json|README.md|package.json|config.js.example|firefox_manifest-extra.json|manifest.json.original|ignored|crowdin.yml)\""
|
"web-run:chrome": "cd dist && web-ext run --start-url https://chrome.google.com/webstore/detail/ublock-origin/cjpalhdlnbpafiamejdnhcphjbkeiagm -t chromium",
|
||||||
|
"build:watch": "webpack --config webpack/webpack.dev.js --watch",
|
||||||
|
"dev": "concurrently \"npm run web-run\" \"npm run build:watch\"",
|
||||||
|
"dev:firefox": "concurrently \"npm run web-run:firefox\" \"npm run build:watch\"",
|
||||||
|
"build": "webpack --config webpack/webpack.prod.js",
|
||||||
|
"clean": "rimraf dist",
|
||||||
|
"test": "npx jest"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 551 B After Width: | Height: | Size: 551 B |
|
Before Width: | Height: | Size: 6.7 KiB After Width: | Height: | Size: 6.7 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 9.1 KiB After Width: | Height: | Size: 9.1 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.3 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 6.1 KiB |
|
Before Width: | Height: | Size: 7.1 KiB After Width: | Height: | Size: 7.1 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 6.4 KiB After Width: | Height: | Size: 6.4 KiB |
|
Before Width: | Height: | Size: 83 KiB After Width: | Height: | Size: 83 KiB |
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 6.4 KiB After Width: | Height: | Size: 6.4 KiB |
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
@@ -13,13 +13,8 @@
|
|||||||
],
|
],
|
||||||
"all_frames": true,
|
"all_frames": true,
|
||||||
"js": [
|
"js": [
|
||||||
"config.js",
|
"./js/vendor.js",
|
||||||
"SB.js",
|
"./js/content.js"
|
||||||
"utils/previewBar.js",
|
|
||||||
"utils/skipNotice.js",
|
|
||||||
"utils.js",
|
|
||||||
"content.js",
|
|
||||||
"popup.js"
|
|
||||||
],
|
],
|
||||||
"css": [
|
"css": [
|
||||||
"content.css",
|
"content.css",
|
||||||
@@ -58,10 +53,8 @@
|
|||||||
},
|
},
|
||||||
"background": {
|
"background": {
|
||||||
"scripts":[
|
"scripts":[
|
||||||
"config.js",
|
"./js/vendor.js",
|
||||||
"SB.js",
|
"./js/background.js"
|
||||||
"utils.js",
|
|
||||||
"background.js"
|
|
||||||
],
|
],
|
||||||
"persistent": false
|
"persistent": false
|
||||||
},
|
},
|
||||||
@@ -6,9 +6,8 @@
|
|||||||
|
|
||||||
<link href="options.css" rel="stylesheet"/>
|
<link href="options.css" rel="stylesheet"/>
|
||||||
|
|
||||||
<script src="../utils.js"></script>
|
<script src="../js/vendor.js"></script>
|
||||||
<script src="../SB.js"></script>
|
<script src="../js/options.js"></script>
|
||||||
<script src="options.js"></script>
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="sponsorBlockPageBody">
|
<body class="sponsorBlockPageBody">
|
||||||
@@ -1,9 +1,8 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>__MSG_openPopup__</title>
|
<title>__MSG_openPopup__</title>
|
||||||
<script src="SB.js"></script>
|
<link id="sponsorBlockPopupFont" rel="stylesheet" type="text/css" href="/libs/Source+Sans+Pro.css"/>
|
||||||
<link id="sponorBlockPopupFont" rel="stylesheet" type="text/css" href="/libs/Source+Sans+Pro.css"/>
|
<link id="sponsorBlockStyleSheet" rel="stylesheet" type="text/css" href="popup.css"/>
|
||||||
<link id="sponorBlockStyleSheet" rel="stylesheet" type="text/css" href="popup.css"/>
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="popupBody">
|
<body class="popupBody">
|
||||||
@@ -210,7 +209,6 @@
|
|||||||
</body>
|
</body>
|
||||||
|
|
||||||
<!-- Scripts that need to load after the html -->
|
<!-- Scripts that need to load after the html -->
|
||||||
<script src="config.js"></script>
|
<script src="./js/vendor.js"></script>
|
||||||
<script src="utils.js"></script>
|
<script src="./js/popup.js"></script>
|
||||||
<script src="popup.js"></script>
|
|
||||||
</html>
|
</html>
|
||||||
@@ -1,33 +1,100 @@
|
|||||||
SB = {
|
interface SBConfig {
|
||||||
|
sponsorTimes: SBMap<string, any>,
|
||||||
|
startSponsorKeybind: string,
|
||||||
|
submitKeybind: string,
|
||||||
|
minutesSaved: number,
|
||||||
|
skipCount: number,
|
||||||
|
sponsorTimesContributed: number,
|
||||||
|
disableSkipping: boolean,
|
||||||
|
disableAutoSkip: boolean,
|
||||||
|
trackViewCount: boolean,
|
||||||
|
dontShowNotice: boolean,
|
||||||
|
hideVideoPlayerControls: boolean,
|
||||||
|
hideInfoButtonPlayerControls: boolean,
|
||||||
|
hideDeleteButtonPlayerControls: boolean,
|
||||||
|
hideDiscordLaunches: number,
|
||||||
|
hideDiscordLink: boolean,
|
||||||
|
invidiousInstances: string[],
|
||||||
|
invidiousUpdateInfoShowCount: number,
|
||||||
|
autoUpvote: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
interface SBObject {
|
||||||
|
configListeners: Array<Function>;
|
||||||
|
defaults: SBConfig;
|
||||||
|
localConfig: any;
|
||||||
|
config: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allows a SBMap to be conveted into json form
|
||||||
|
// Currently used for local storage
|
||||||
|
class SBMap<T, U> extends Map {
|
||||||
|
constructor(entries?: [T, U][]) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
// Import all entries if they were given
|
||||||
|
if (entries !== undefined) {
|
||||||
|
for (const item of entries) {
|
||||||
|
this.set(item[0], item[1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
toJSON() {
|
||||||
|
return Array.from(this.entries());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: Rename to something more meaningful
|
||||||
|
var SB: SBObject = {
|
||||||
/**
|
/**
|
||||||
* Callback function when an option is updated
|
* Callback function when an option is updated
|
||||||
*
|
|
||||||
* @type {CallableFunction}
|
|
||||||
*/
|
*/
|
||||||
configListeners: []
|
configListeners: [],
|
||||||
|
defaults: {
|
||||||
|
sponsorTimes: new SBMap(),
|
||||||
|
startSponsorKeybind: ";",
|
||||||
|
submitKeybind: "'",
|
||||||
|
minutesSaved: 0,
|
||||||
|
skipCount: 0,
|
||||||
|
sponsorTimesContributed: 0,
|
||||||
|
disableSkipping: false,
|
||||||
|
disableAutoSkip: false,
|
||||||
|
trackViewCount: true,
|
||||||
|
dontShowNotice: false,
|
||||||
|
hideVideoPlayerControls: false,
|
||||||
|
hideInfoButtonPlayerControls: false,
|
||||||
|
hideDeleteButtonPlayerControls: false,
|
||||||
|
hideDiscordLaunches: 0,
|
||||||
|
hideDiscordLink: false,
|
||||||
|
invidiousInstances: ["invidio.us", "invidiou.sh", "invidious.snopyta.org"],
|
||||||
|
invidiousUpdateInfoShowCount: 0,
|
||||||
|
autoUpvote: true
|
||||||
|
},
|
||||||
|
localConfig: null,
|
||||||
|
config: null
|
||||||
};
|
};
|
||||||
|
|
||||||
// Function setup
|
// Function setup
|
||||||
|
|
||||||
// Allows a map to be conveted into json form
|
|
||||||
// Currently used for local storage
|
|
||||||
Map.prototype.toJSON = function() {
|
|
||||||
return Array.from(this.entries());
|
|
||||||
};
|
|
||||||
|
|
||||||
// Proxy Map changes to Map in SB.localConfig
|
// Proxy Map changes to Map in SB.localConfig
|
||||||
// Saves the changes to chrome.storage in json form
|
// Saves the changes to chrome.storage in json form
|
||||||
class MapIO {
|
class MapIO {
|
||||||
|
id: string;
|
||||||
|
map: SBMap<String, any>;
|
||||||
|
|
||||||
constructor(id) {
|
constructor(id) {
|
||||||
// The name of the item in the array
|
// The name of the item in the array
|
||||||
this.id = id;
|
this.id = id;
|
||||||
// A local copy of the map (SB.config.mapname.map)
|
// A local copy of the SBMap (SB.config.SBMapname.SBMap)
|
||||||
this.map = SB.localConfig[this.id];
|
this.map = SB.localConfig[this.id];
|
||||||
}
|
}
|
||||||
|
|
||||||
set(key, value) {
|
set(key, value) {
|
||||||
// Proxy to map
|
// Proxy to SBMap
|
||||||
this.map.set(key, value);
|
this.map.set(key, value);
|
||||||
// Store updated map locally
|
// Store updated SBMap locally
|
||||||
chrome.storage.sync.set({
|
chrome.storage.sync.set({
|
||||||
[this.id]: encodeStoredItem(this.map)
|
[this.id]: encodeStoredItem(this.map)
|
||||||
});
|
});
|
||||||
@@ -47,36 +114,36 @@ class MapIO {
|
|||||||
}
|
}
|
||||||
|
|
||||||
delete(key) {
|
delete(key) {
|
||||||
// Proxy to map
|
// Proxy to SBMap
|
||||||
this.map.delete(key);
|
this.map.delete(key);
|
||||||
// Store updated map locally
|
// Store updated SBMap locally
|
||||||
chrome.storage.sync.set({
|
chrome.storage.sync.set({
|
||||||
[this.id]: encodeStoredItem(this.map)
|
[this.id]: encodeStoredItem(this.map)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
clear() {
|
clear() {
|
||||||
this.map.clear();
|
this.map.clear();
|
||||||
chrome.storage.sync.set({
|
chrome.storage.sync.set({
|
||||||
[this.id]: encodeStoredItem(this.map)
|
[this.id]: encodeStoredItem(this.map)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Map cannot be stored in the chrome storage.
|
* A SBMap cannot be stored in the chrome storage.
|
||||||
* This data will be encoded into an array instead as specified by the toJSON function.
|
* This data will be encoded into an array instead as specified by the toJSON function.
|
||||||
*
|
*
|
||||||
* @param {*} data
|
* @param data
|
||||||
*/
|
*/
|
||||||
function encodeStoredItem(data) {
|
function encodeStoredItem(data) {
|
||||||
// if data is Map convert to json for storing
|
// if data is SBMap convert to json for storing
|
||||||
if(!(data instanceof Map)) return data;
|
if(!(data instanceof SBMap)) return data;
|
||||||
return JSON.stringify(data);
|
return JSON.stringify(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Map cannot be stored in the chrome storage.
|
* A SBMap cannot be stored in the chrome storage.
|
||||||
* This data will be decoded from the array it is stored in
|
* This data will be decoded from the array it is stored in
|
||||||
*
|
*
|
||||||
* @param {*} data
|
* @param {*} data
|
||||||
@@ -88,7 +155,7 @@ function decodeStoredItem(data) {
|
|||||||
let str = JSON.parse(data);
|
let str = JSON.parse(data);
|
||||||
|
|
||||||
if(!Array.isArray(str)) return data;
|
if(!Array.isArray(str)) return data;
|
||||||
return new Map(str);
|
return new SBMap(str);
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
|
|
||||||
// If all else fails, return the data
|
// If all else fails, return the data
|
||||||
@@ -96,7 +163,7 @@ function decodeStoredItem(data) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function configProxy() {
|
function configProxy(): any {
|
||||||
chrome.storage.onChanged.addListener((changes, namespace) => {
|
chrome.storage.onChanged.addListener((changes, namespace) => {
|
||||||
for (const key in changes) {
|
for (const key in changes) {
|
||||||
SB.localConfig[key] = decodeStoredItem(changes[key].newValue);
|
SB.localConfig[key] = decodeStoredItem(changes[key].newValue);
|
||||||
@@ -107,24 +174,28 @@ function configProxy() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var handler = {
|
var handler: ProxyHandler<any> = {
|
||||||
set(obj, prop, value) {
|
set(obj, prop, value) {
|
||||||
SB.localConfig[prop] = value;
|
SB.localConfig[prop] = value;
|
||||||
|
|
||||||
chrome.storage.sync.set({
|
chrome.storage.sync.set({
|
||||||
[prop]: encodeStoredItem(value)
|
[prop]: encodeStoredItem(value)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
get(obj, prop) {
|
get(obj, prop): any {
|
||||||
let data = SB.localConfig[prop];
|
let data = SB.localConfig[prop];
|
||||||
if(data instanceof Map) data = new MapIO(prop);
|
if(data instanceof SBMap) data = new MapIO(prop);
|
||||||
|
|
||||||
return obj[prop] || data;
|
return obj[prop] || data;
|
||||||
},
|
},
|
||||||
|
|
||||||
deleteProperty(obj, prop) {
|
deleteProperty(obj, prop) {
|
||||||
chrome.storage.sync.remove(prop);
|
chrome.storage.sync.remove(<string> prop);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
@@ -158,27 +229,6 @@ async function setupConfig() {
|
|||||||
migrateOldFormats();
|
migrateOldFormats();
|
||||||
}
|
}
|
||||||
|
|
||||||
SB.defaults = {
|
|
||||||
"sponsorTimes": new Map(),
|
|
||||||
"startSponsorKeybind": ";",
|
|
||||||
"submitKeybind": "'",
|
|
||||||
"minutesSaved": 0,
|
|
||||||
"skipCount": 0,
|
|
||||||
"sponsorTimesContributed": 0,
|
|
||||||
"disableSkipping": false,
|
|
||||||
"disableAutoSkip": false,
|
|
||||||
"trackViewCount": true,
|
|
||||||
"dontShowNotice": false,
|
|
||||||
"hideVideoPlayerControls": false,
|
|
||||||
"hideInfoButtonPlayerControls": false,
|
|
||||||
"hideDeleteButtonPlayerControls": false,
|
|
||||||
"hideDiscordLaunches": 0,
|
|
||||||
"hideDiscordLink": false,
|
|
||||||
"invidiousInstances": ["invidio.us", "invidiou.sh", "invidious.snopyta.org"],
|
|
||||||
"invidiousUpdateInfoShowCount": 0,
|
|
||||||
"autoUpvote": true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset config
|
// Reset config
|
||||||
function resetConfig() {
|
function resetConfig() {
|
||||||
SB.config = SB.defaults;
|
SB.config = SB.defaults;
|
||||||
@@ -186,7 +236,7 @@ function resetConfig() {
|
|||||||
|
|
||||||
function convertJSON() {
|
function convertJSON() {
|
||||||
Object.keys(SB.defaults).forEach(key => {
|
Object.keys(SB.defaults).forEach(key => {
|
||||||
SB.localConfig[key] = decodeStoredItem(SB.localConfig[key], key);
|
SB.localConfig[key] = decodeStoredItem(SB.localConfig[key]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -194,10 +244,12 @@ function convertJSON() {
|
|||||||
function addDefaults() {
|
function addDefaults() {
|
||||||
for (const key in SB.defaults) {
|
for (const key in SB.defaults) {
|
||||||
if(!SB.localConfig.hasOwnProperty(key)) {
|
if(!SB.localConfig.hasOwnProperty(key)) {
|
||||||
SB.localConfig[key] = SB.defaults[key];
|
SB.localConfig[key] = SB.defaults[key];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Sync config
|
// Sync config
|
||||||
setupConfig();
|
setupConfig();
|
||||||
|
|
||||||
|
export default SB;
|
||||||
@@ -1,12 +1,19 @@
|
|||||||
isBackgroundScript = true;
|
import * as Types from "./types";
|
||||||
|
import SB from "./SB";
|
||||||
|
|
||||||
|
import Utils from "./utils";
|
||||||
|
var utils = new Utils({
|
||||||
|
registerFirefoxContentScript,
|
||||||
|
unregisterFirefoxContentScript
|
||||||
|
});
|
||||||
|
|
||||||
// Used only on Firefox, which does not support non persistent background pages.
|
// Used only on Firefox, which does not support non persistent background pages.
|
||||||
var contentScriptRegistrations = {};
|
var contentScriptRegistrations = {};
|
||||||
|
|
||||||
// Register content script if needed
|
// Register content script if needed
|
||||||
if (isFirefox()) {
|
if (utils.isFirefox()) {
|
||||||
wait(() => SB.config !== undefined).then(function() {
|
utils.wait(() => SB.config !== null).then(function() {
|
||||||
if (SB.config.supportInvidious) setupExtraSiteContentScripts();
|
if (SB.config.supportInvidious) utils.setupExtraSiteContentScripts();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,8 +42,8 @@ chrome.runtime.onMessage.addListener(function (request, sender, callback) {
|
|||||||
case "getSponsorTimes":
|
case "getSponsorTimes":
|
||||||
getSponsorTimes(request.videoID, function(sponsorTimes) {
|
getSponsorTimes(request.videoID, function(sponsorTimes) {
|
||||||
callback({
|
callback({
|
||||||
sponsorTimes: sponsorTimes
|
sponsorTimes
|
||||||
})
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
//this allows the callback to be called later
|
//this allows the callback to be called later
|
||||||
@@ -57,9 +64,7 @@ chrome.runtime.onMessage.addListener(function (request, sender, callback) {
|
|||||||
registerFirefoxContentScript(request);
|
registerFirefoxContentScript(request);
|
||||||
return false;
|
return false;
|
||||||
case "unregisterContentScript":
|
case "unregisterContentScript":
|
||||||
contentScriptRegistrations[request.id].unregister();
|
unregisterFirefoxContentScript(request.id)
|
||||||
delete contentScriptRegistrations[request.id];
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -77,7 +82,7 @@ chrome.runtime.onInstalled.addListener(function (object) {
|
|||||||
chrome.tabs.create({url: chrome.extension.getURL("/help/index_en.html")});
|
chrome.tabs.create({url: chrome.extension.getURL("/help/index_en.html")});
|
||||||
|
|
||||||
//generate a userID
|
//generate a userID
|
||||||
const newUserID = generateUserID();
|
const newUserID = utils.generateUserID();
|
||||||
//save this UUID
|
//save this UUID
|
||||||
SB.config.userID = newUserID;
|
SB.config.userID = newUserID;
|
||||||
|
|
||||||
@@ -106,6 +111,16 @@ function registerFirefoxContentScript(options) {
|
|||||||
}).then((registration) => void (contentScriptRegistrations[options.id] = registration));
|
}).then((registration) => void (contentScriptRegistrations[options.id] = registration));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Only works on Firefox.
|
||||||
|
* Firefox requires that this is handled by the background script
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
function unregisterFirefoxContentScript(id: string) {
|
||||||
|
contentScriptRegistrations[id].unregister();
|
||||||
|
delete contentScriptRegistrations[id];
|
||||||
|
}
|
||||||
|
|
||||||
//gets the sponsor times from memory
|
//gets the sponsor times from memory
|
||||||
function getSponsorTimes(videoID, callback) {
|
function getSponsorTimes(videoID, callback) {
|
||||||
let sponsorTimes = [];
|
let sponsorTimes = [];
|
||||||
@@ -143,12 +158,12 @@ function submitVote(type, UUID, callback) {
|
|||||||
|
|
||||||
if (userID == undefined || userID === "undefined") {
|
if (userID == undefined || userID === "undefined") {
|
||||||
//generate one
|
//generate one
|
||||||
userID = generateUserID();
|
userID = utils.generateUserID();
|
||||||
SB.config.userID = userID;
|
SB.config.userID = userID;
|
||||||
}
|
}
|
||||||
|
|
||||||
//publish this vote
|
//publish this vote
|
||||||
sendRequestToServer("POST", "/api/voteOnSponsorTime?UUID=" + UUID + "&userID=" + userID + "&type=" + type, function(xmlhttp, error) {
|
utils.sendRequestToServer("POST", "/api/voteOnSponsorTime?UUID=" + UUID + "&userID=" + userID + "&type=" + type, function(xmlhttp, error) {
|
||||||
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
|
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
|
||||||
callback({
|
callback({
|
||||||
successType: 1
|
successType: 1
|
||||||
@@ -176,7 +191,7 @@ async function submitTimes(videoID, callback) {
|
|||||||
let userID = SB.config.userID;
|
let userID = SB.config.userID;
|
||||||
|
|
||||||
if (sponsorTimes != undefined && sponsorTimes.length > 0) {
|
if (sponsorTimes != undefined && sponsorTimes.length > 0) {
|
||||||
let durationResult = await new Promise((resolve, reject) => {
|
let durationResult = <Types.videoDurationResponse> await new Promise((resolve, reject) => {
|
||||||
chrome.tabs.query({
|
chrome.tabs.query({
|
||||||
active: true,
|
active: true,
|
||||||
currentWindow: true
|
currentWindow: true
|
||||||
@@ -196,51 +211,30 @@ async function submitTimes(videoID, callback) {
|
|||||||
|
|
||||||
//submit these times
|
//submit these times
|
||||||
for (let i = 0; i < sponsorTimes.length; i++) {
|
for (let i = 0; i < sponsorTimes.length; i++) {
|
||||||
//to prevent it from happeneing twice
|
//to prevent it from happeneing twice
|
||||||
let increasedContributionAmount = false;
|
let increasedContributionAmount = false;
|
||||||
|
|
||||||
//submit the sponsorTime
|
//submit the sponsorTime
|
||||||
sendRequestToServer("GET", "/api/postVideoSponsorTimes?videoID=" + videoID + "&startTime=" + sponsorTimes[i][0] + "&endTime=" + sponsorTimes[i][1]
|
utils.sendRequestToServer("GET", "/api/postVideoSponsorTimes?videoID=" + videoID + "&startTime=" + sponsorTimes[i][0] + "&endTime=" + sponsorTimes[i][1]
|
||||||
+ "&userID=" + userID, function(xmlhttp, error) {
|
+ "&userID=" + userID, function(xmlhttp, error) {
|
||||||
if (xmlhttp.readyState == 4 && !error) {
|
if (xmlhttp.readyState == 4 && !error) {
|
||||||
callback({
|
callback({
|
||||||
statusCode: xmlhttp.status
|
statusCode: xmlhttp.status
|
||||||
});
|
});
|
||||||
|
|
||||||
if (xmlhttp.status == 200) {
|
if (xmlhttp.status == 200) {
|
||||||
//add these to the storage log
|
//save the amount contributed
|
||||||
currentContributionAmount = SB.config.sponsorTimesContributed;
|
if (!increasedContributionAmount) {
|
||||||
//save the amount contributed
|
increasedContributionAmount = true;
|
||||||
if (!increasedContributionAmount) {
|
SB.config.sponsorTimesContributed = SB.config.sponsorTimesContribute + sponsorTimes.length;
|
||||||
increasedContributionAmount = true;
|
|
||||||
SB.config.sponsorTimesContributed = currentContributionAmount + sponsorTimes.length;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if (error) {
|
} else if (error) {
|
||||||
callback({
|
callback({
|
||||||
statusCode: -1
|
statusCode: -1
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendRequestToServer(type, address, callback) {
|
|
||||||
let xmlhttp = new XMLHttpRequest();
|
|
||||||
|
|
||||||
xmlhttp.open(type, serverAddress + address, true);
|
|
||||||
|
|
||||||
if (callback != undefined) {
|
|
||||||
xmlhttp.onreadystatechange = function () {
|
|
||||||
callback(xmlhttp, false);
|
|
||||||
};
|
|
||||||
|
|
||||||
xmlhttp.onerror = function(ev) {
|
|
||||||
callback(xmlhttp, true);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
//submit this request
|
|
||||||
xmlhttp.send();
|
|
||||||
}
|
|
||||||
@@ -1,3 +1,13 @@
|
|||||||
|
import SB from "./SB";
|
||||||
|
|
||||||
|
import Utils from "./utils";
|
||||||
|
var utils = new Utils();
|
||||||
|
|
||||||
|
import runThePopup from "./popup";
|
||||||
|
|
||||||
|
import PreviewBar from "./js-components/previewBar";
|
||||||
|
import SkipNotice from "./js-components/skipNotice";
|
||||||
|
|
||||||
//was sponsor data found when doing SponsorsLookup
|
//was sponsor data found when doing SponsorsLookup
|
||||||
var sponsorDataFound = false;
|
var sponsorDataFound = false;
|
||||||
var previousVideoID = null;
|
var previousVideoID = null;
|
||||||
@@ -16,7 +26,7 @@ var sponsorSkipped = [];
|
|||||||
//the video
|
//the video
|
||||||
var v;
|
var v;
|
||||||
|
|
||||||
var listenerAdded;
|
var onInvidious;
|
||||||
|
|
||||||
//the video id of the last preview bar update
|
//the video id of the last preview bar update
|
||||||
var lastPreviewBarUpdate;
|
var lastPreviewBarUpdate;
|
||||||
@@ -39,8 +49,8 @@ var previewBar = null;
|
|||||||
//the player controls on the YouTube player
|
//the player controls on the YouTube player
|
||||||
var controls = null;
|
var controls = null;
|
||||||
|
|
||||||
// Direct Links
|
// Direct Links after the config is loaded
|
||||||
videoIDChange(getYouTubeVideoID(document.URL));
|
utils.wait(() => SB.config !== null).then(() => videoIDChange(getYouTubeVideoID(document.URL)));
|
||||||
|
|
||||||
//the last time looked at (used to see if this time is in the interval)
|
//the last time looked at (used to see if this time is in the interval)
|
||||||
var lastTime = -1;
|
var lastTime = -1;
|
||||||
@@ -65,10 +75,23 @@ var sponsorTimesSubmitting = [];
|
|||||||
//this is used to close the popup on YouTube when the other popup opens
|
//this is used to close the popup on YouTube when the other popup opens
|
||||||
var popupInitialised = false;
|
var popupInitialised = false;
|
||||||
|
|
||||||
|
// Contains all of the functions and variables needed by the skip notice
|
||||||
|
var skipNoticeContentContainer = () => ({
|
||||||
|
vote,
|
||||||
|
dontShowNoticeAgain,
|
||||||
|
unskipSponsorTime,
|
||||||
|
sponsorTimes,
|
||||||
|
UUIDs,
|
||||||
|
v,
|
||||||
|
reskipSponsorTime,
|
||||||
|
hiddenSponsorTimes,
|
||||||
|
updatePreviewBar
|
||||||
|
});
|
||||||
|
|
||||||
//get messages from the background script and the popup
|
//get messages from the background script and the popup
|
||||||
chrome.runtime.onMessage.addListener(messageListener);
|
chrome.runtime.onMessage.addListener(messageListener);
|
||||||
|
|
||||||
function messageListener(request, sender, sendResponse) {
|
function messageListener(request: any, sender: any, sendResponse: (response: any) => void): void {
|
||||||
//messages from popup script
|
//messages from popup script
|
||||||
switch(request.message){
|
switch(request.message){
|
||||||
case "update":
|
case "update":
|
||||||
@@ -106,7 +129,7 @@ function messageListener(request, sender, sendResponse) {
|
|||||||
break;
|
break;
|
||||||
case "getVideoDuration":
|
case "getVideoDuration":
|
||||||
sendResponse({
|
sendResponse({
|
||||||
duration: v.duration
|
duration: v.duration
|
||||||
});
|
});
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -165,8 +188,7 @@ if (!SB.configListeners.includes(contentConfigUpdateListener)) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//check for hotkey pressed
|
//check for hotkey pressed
|
||||||
document.onkeydown = async function(e){
|
document.onkeydown = function(e: KeyboardEvent){
|
||||||
e = e || window.event;
|
|
||||||
var key = e.key;
|
var key = e.key;
|
||||||
|
|
||||||
let video = document.getElementById("movie_player");
|
let video = document.getElementById("movie_player");
|
||||||
@@ -177,10 +199,10 @@ document.onkeydown = async function(e){
|
|||||||
|
|
||||||
//is the video in focus, otherwise they could be typing a comment
|
//is the video in focus, otherwise they could be typing a comment
|
||||||
if (document.activeElement === video) {
|
if (document.activeElement === video) {
|
||||||
if(key == startSponsorKey.startSponsorKeybind){
|
if(key == startSponsorKey){
|
||||||
//semicolon
|
//semicolon
|
||||||
startSponsorClicked();
|
startSponsorClicked();
|
||||||
} else if (key == submitKey.submitKeybind) {
|
} else if (key == submitKey) {
|
||||||
//single quote
|
//single quote
|
||||||
submitSponsorTimes();
|
submitSponsorTimes();
|
||||||
}
|
}
|
||||||
@@ -217,13 +239,15 @@ function videoIDChange(id) {
|
|||||||
//id is not valid
|
//id is not valid
|
||||||
if (!id) return;
|
if (!id) return;
|
||||||
|
|
||||||
let channelIDPromise = wait(getChannelID);
|
// TODO: Use a better method here than using type any
|
||||||
|
// This is done to be able to do channelIDPromise.isFulfilled and channelIDPromise.isRejected
|
||||||
|
let channelIDPromise: any = utils.wait(getChannelID);
|
||||||
channelIDPromise.then(() => channelIDPromise.isFulfilled = true).catch(() => channelIDPromise.isRejected = true);
|
channelIDPromise.then(() => channelIDPromise.isFulfilled = true).catch(() => channelIDPromise.isRejected = true);
|
||||||
|
|
||||||
//setup the preview bar
|
//setup the preview bar
|
||||||
if (previewBar == null) {
|
if (previewBar == null) {
|
||||||
//create it
|
//create it
|
||||||
wait(getControls).then(result => {
|
utils.wait(getControls).then(result => {
|
||||||
const progressElementSelectors = [
|
const progressElementSelectors = [
|
||||||
// For YouTube
|
// For YouTube
|
||||||
"ytp-progress-bar-container",
|
"ytp-progress-bar-container",
|
||||||
@@ -274,7 +298,7 @@ function videoIDChange(id) {
|
|||||||
sponsorTimesSubmitting = [];
|
sponsorTimesSubmitting = [];
|
||||||
|
|
||||||
//see if the onvideo control image needs to be changed
|
//see if the onvideo control image needs to be changed
|
||||||
wait(getControls).then(result => {
|
utils.wait(getControls).then(result => {
|
||||||
chrome.runtime.sendMessage({
|
chrome.runtime.sendMessage({
|
||||||
message: "getSponsorTimes",
|
message: "getSponsorTimes",
|
||||||
videoID: id
|
videoID: id
|
||||||
@@ -304,11 +328,12 @@ function videoIDChange(id) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function sponsorsLookup(id, channelIDPromise) {
|
function sponsorsLookup(id: string, channelIDPromise?) {
|
||||||
|
|
||||||
v = document.querySelector('video') // Youtube video player
|
v = document.querySelector('video') // Youtube video player
|
||||||
//there is no video here
|
//there is no video here
|
||||||
if (v == null) {
|
if (v == null) {
|
||||||
setTimeout(() => sponsorsLookup(id), 100);
|
setTimeout(() => sponsorsLookup(id, channelIDPromise), 100);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -319,12 +344,12 @@ function sponsorsLookup(id, channelIDPromise) {
|
|||||||
v.addEventListener('durationchange', updatePreviewBar);
|
v.addEventListener('durationchange', updatePreviewBar);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (channelIDPromise != null) {
|
if (channelIDPromise !== undefined) {
|
||||||
if (channelIDPromise.isFulfilled) {
|
if (channelIDPromise.isFulfilled) {
|
||||||
whitelistCheck();
|
whitelistCheck();
|
||||||
} else if (channelIDPromise.isRejected) {
|
} else if (channelIDPromise.isRejected) {
|
||||||
//try again
|
//try again
|
||||||
wait(getChannelID).then(whitelistCheck).catch();
|
utils.wait(getChannelID).then(whitelistCheck).catch();
|
||||||
} else {
|
} else {
|
||||||
//add it as a then statement
|
//add it as a then statement
|
||||||
channelIDPromise.then(whitelistCheck);
|
channelIDPromise.then(whitelistCheck);
|
||||||
@@ -334,7 +359,7 @@ function sponsorsLookup(id, channelIDPromise) {
|
|||||||
//check database for sponsor times
|
//check database for sponsor times
|
||||||
//made true once a setTimeout has been created to try again after a server error
|
//made true once a setTimeout has been created to try again after a server error
|
||||||
let recheckStarted = false;
|
let recheckStarted = false;
|
||||||
sendRequestToServer('GET', "/api/getVideoSponsorTimes?videoID=" + id, function(xmlhttp) {
|
utils.sendRequestToServer('GET', "/api/getVideoSponsorTimes?videoID=" + id, function(xmlhttp) {
|
||||||
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
|
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
|
||||||
sponsorDataFound = true;
|
sponsorDataFound = true;
|
||||||
|
|
||||||
@@ -365,7 +390,7 @@ function sponsorsLookup(id, channelIDPromise) {
|
|||||||
//if less than 3 days old
|
//if less than 3 days old
|
||||||
if ((Date.now() / 1000) - unixTimePublished < 259200) {
|
if ((Date.now() / 1000) - unixTimePublished < 259200) {
|
||||||
//TODO lower when server becomes better
|
//TODO lower when server becomes better
|
||||||
setTimeout(() => sponsorsLookup(id), 180000);
|
setTimeout(() => sponsorsLookup(id, channelIDPromise), 180000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -376,7 +401,7 @@ function sponsorsLookup(id, channelIDPromise) {
|
|||||||
|
|
||||||
//TODO lower when server becomes better (back to 1 second)
|
//TODO lower when server becomes better (back to 1 second)
|
||||||
//some error occurred, try again in a second
|
//some error occurred, try again in a second
|
||||||
setTimeout(() => sponsorsLookup(id), 10000);
|
setTimeout(() => sponsorsLookup(id, channelIDPromise), 10000);
|
||||||
|
|
||||||
sponsorLookupRetries++;
|
sponsorLookupRetries++;
|
||||||
}
|
}
|
||||||
@@ -390,30 +415,44 @@ function sponsorsLookup(id, channelIDPromise) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function updatePreviewBar() {
|
function getYouTubeVideoID(url: string) {
|
||||||
let localSponsorTimes = sponsorTimes;
|
// For YouTube TV support
|
||||||
if (localSponsorTimes == null) localSponsorTimes = [];
|
if(url.startsWith("https://www.youtube.com/tv#/")) url = url.replace("#", "");
|
||||||
|
|
||||||
let allSponsorTimes = localSponsorTimes.concat(sponsorTimesSubmitting);
|
//Attempt to parse url
|
||||||
|
let urlObject = null;
|
||||||
|
try {
|
||||||
|
urlObject = new URL(url);
|
||||||
|
} catch (e) {
|
||||||
|
console.error("[SB] Unable to parse URL: " + url);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
//create an array of the sponsor types
|
// Check if valid hostname
|
||||||
let types = [];
|
if (SB.config && SB.config.invidiousInstances.includes(urlObject.host)) {
|
||||||
for (let i = 0; i < localSponsorTimes.length; i++) {
|
onInvidious = true;
|
||||||
if (!hiddenSponsorTimes.includes(i)) {
|
} else if (!["www.youtube.com", "www.youtube-nocookie.com"].includes(urlObject.host)) {
|
||||||
types.push("sponsor");
|
if (!SB.config) {
|
||||||
} else {
|
// Call this later, in case this is an Invidious tab
|
||||||
// Don't show this sponsor
|
utils.wait(() => SB.config !== null).then(() => videoIDChange(getYouTubeVideoID(url)));
|
||||||
types.push(null);
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
//Get ID from searchParam
|
||||||
|
if (urlObject.searchParams.has("v") && ["/watch", "/watch/"].includes(urlObject.pathname) || urlObject.pathname.startsWith("/tv/watch")) {
|
||||||
|
let id = urlObject.searchParams.get("v");
|
||||||
|
return id.length == 11 ? id : false;
|
||||||
|
} else if (urlObject.pathname.startsWith("/embed/")) {
|
||||||
|
try {
|
||||||
|
return urlObject.pathname.substr(7, 11);
|
||||||
|
} catch (e) {
|
||||||
|
console.error("[SB] Video ID not valid for " + url);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (let i = 0; i < sponsorTimesSubmitting.length; i++) {
|
return false;
|
||||||
types.push("previewSponsor");
|
|
||||||
}
|
|
||||||
|
|
||||||
wait(() => previewBar !== null).then((result) => previewBar.set(allSponsorTimes, types, v.duration));
|
|
||||||
|
|
||||||
//update last video id
|
|
||||||
lastPreviewBarUpdate = sponsorVideoID;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getChannelID() {
|
function getChannelID() {
|
||||||
@@ -443,7 +482,7 @@ function getChannelID() {
|
|||||||
let titleInfoContainer = document.getElementById("info-contents");
|
let titleInfoContainer = document.getElementById("info-contents");
|
||||||
let currentTitle = "";
|
let currentTitle = "";
|
||||||
if (titleInfoContainer != null) {
|
if (titleInfoContainer != null) {
|
||||||
currentTitle = titleInfoContainer.firstElementChild.firstElementChild.querySelector(".title").firstElementChild.innerText;
|
currentTitle = (<HTMLElement> titleInfoContainer.firstElementChild.firstElementChild.querySelector(".title").firstElementChild).innerText;
|
||||||
} else if (onInvidious) {
|
} else if (onInvidious) {
|
||||||
// Unfortunately, the Invidious HTML doesn't have much in the way of element identifiers...
|
// Unfortunately, the Invidious HTML doesn't have much in the way of element identifiers...
|
||||||
currentTitle = document.querySelector("body > div > div.pure-u-1.pure-u-md-20-24 div.pure-u-1.pure-u-lg-3-5 > div > a > div > span").textContent;
|
currentTitle = document.querySelector("body > div > div.pure-u-1.pure-u-md-20-24 div.pure-u-1.pure-u-lg-3-5 > div > a > div > span").textContent;
|
||||||
@@ -465,6 +504,32 @@ function getChannelID() {
|
|||||||
channelWhitelisted = false;
|
channelWhitelisted = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updatePreviewBar() {
|
||||||
|
let localSponsorTimes = sponsorTimes;
|
||||||
|
if (localSponsorTimes == null) localSponsorTimes = [];
|
||||||
|
|
||||||
|
let allSponsorTimes = localSponsorTimes.concat(sponsorTimesSubmitting);
|
||||||
|
|
||||||
|
//create an array of the sponsor types
|
||||||
|
let types = [];
|
||||||
|
for (let i = 0; i < localSponsorTimes.length; i++) {
|
||||||
|
if (!hiddenSponsorTimes.includes(i)) {
|
||||||
|
types.push("sponsor");
|
||||||
|
} else {
|
||||||
|
// Don't show this sponsor
|
||||||
|
types.push(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (let i = 0; i < sponsorTimesSubmitting.length; i++) {
|
||||||
|
types.push("previewSponsor");
|
||||||
|
}
|
||||||
|
|
||||||
|
utils.wait(() => previewBar !== null).then((result) => previewBar.set(allSponsorTimes, types, v.duration));
|
||||||
|
|
||||||
|
//update last video id
|
||||||
|
lastPreviewBarUpdate = sponsorVideoID;
|
||||||
|
}
|
||||||
|
|
||||||
//checks if this channel is whitelisted, should be done only after the channelID has been loaded
|
//checks if this channel is whitelisted, should be done only after the channelID has been loaded
|
||||||
function whitelistCheck() {
|
function whitelistCheck() {
|
||||||
//see if this is a whitelisted channel
|
//see if this is a whitelisted channel
|
||||||
@@ -509,12 +574,12 @@ function sponsorCheck() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//don't keep track until they are loaded in
|
//don't keep track until they are loaded in
|
||||||
if (sponsorTimes != null || sponsorTimesSubmitting.length > 0) {
|
if (sponsorTimes !== null || sponsorTimesSubmitting.length > 0) {
|
||||||
lastTime = v.currentTime;
|
lastTime = v.currentTime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkSponsorTime(sponsorTimes, index, openNotice) {
|
function checkSponsorTime(sponsorTimes, index, openNotice): boolean {
|
||||||
//this means part of the video was just skipped
|
//this means part of the video was just skipped
|
||||||
if (Math.abs(v.currentTime - lastTime) > 1 && lastTime != -1) {
|
if (Math.abs(v.currentTime - lastTime) > 1 && lastTime != -1) {
|
||||||
//make lastTime as if the video was playing normally
|
//make lastTime as if the video was playing normally
|
||||||
@@ -555,14 +620,7 @@ function skipToTime(v, index, sponsorTimes, openNotice) {
|
|||||||
if (openNotice) {
|
if (openNotice) {
|
||||||
//send out the message saying that a sponsor message was skipped
|
//send out the message saying that a sponsor message was skipped
|
||||||
if (!SB.config.dontShowNotice) {
|
if (!SB.config.dontShowNotice) {
|
||||||
let skipNotice = new SkipNotice(this, currentUUID, SB.config.disableAutoSkip);
|
let skipNotice = new SkipNotice(this, currentUUID, SB.config.disableAutoSkip, skipNoticeContentContainer);
|
||||||
|
|
||||||
//TODO: Remove this when Invidious support is old
|
|
||||||
if (SB.config.invidiousUpdateInfoShowCount < 5) {
|
|
||||||
skipNotice.addNoticeInfoMessage(chrome.i18n.getMessage("invidiousInfo1"), chrome.i18n.getMessage("invidiousInfo2"));
|
|
||||||
|
|
||||||
SB.config.invidiousUpdateInfoShowCount += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//auto-upvote this sponsor
|
//auto-upvote this sponsor
|
||||||
if (SB.config.trackViewCount && !SB.config.disableAutoSkip && SB.config.autoUpvote) {
|
if (SB.config.trackViewCount && !SB.config.disableAutoSkip && SB.config.autoUpvote) {
|
||||||
@@ -573,7 +631,7 @@ function skipToTime(v, index, sponsorTimes, openNotice) {
|
|||||||
|
|
||||||
//send telemetry that a this sponsor was skipped
|
//send telemetry that a this sponsor was skipped
|
||||||
if (SB.config.trackViewCount && !sponsorSkipped[index]) {
|
if (SB.config.trackViewCount && !sponsorSkipped[index]) {
|
||||||
sendRequestToServer("POST", "/api/viewedVideoSponsorTime?UUID=" + currentUUID);
|
utils.sendRequestToServer("POST", "/api/viewedVideoSponsorTime?UUID=" + currentUUID);
|
||||||
|
|
||||||
if (!SB.config.disableAutoSkip) {
|
if (!SB.config.disableAutoSkip) {
|
||||||
// Count this as a skip
|
// Count this as a skip
|
||||||
@@ -637,7 +695,7 @@ function getControls() {
|
|||||||
|
|
||||||
//adds all the player controls buttons
|
//adds all the player controls buttons
|
||||||
async function createButtons() {
|
async function createButtons() {
|
||||||
let result = await wait(getControls).catch();
|
let result = await utils.wait(getControls).catch();
|
||||||
|
|
||||||
//set global controls variable
|
//set global controls variable
|
||||||
controls = result;
|
controls = result;
|
||||||
@@ -718,7 +776,7 @@ async function changeStartSponsorButton(showStartSponsor, uploadButtonVisible) {
|
|||||||
if(!sponsorVideoID) return false;
|
if(!sponsorVideoID) return false;
|
||||||
|
|
||||||
//make sure submit button is loaded
|
//make sure submit button is loaded
|
||||||
await wait(isSubmitButtonLoaded);
|
await utils.wait(isSubmitButtonLoaded);
|
||||||
|
|
||||||
//if it isn't visible, there is no data
|
//if it isn't visible, there is no data
|
||||||
let shouldHide = (uploadButtonVisible && !(SB.config.hideDeleteButtonPlayerControls || onInvidious)) ? "unset" : "none"
|
let shouldHide = (uploadButtonVisible && !(SB.config.hideDeleteButtonPlayerControls || onInvidious)) ? "unset" : "none"
|
||||||
@@ -726,7 +784,7 @@ async function changeStartSponsorButton(showStartSponsor, uploadButtonVisible) {
|
|||||||
|
|
||||||
if (showStartSponsor) {
|
if (showStartSponsor) {
|
||||||
showingStartSponsor = true;
|
showingStartSponsor = true;
|
||||||
document.getElementById("startSponsorImage").src = chrome.extension.getURL("icons/PlayerStartIconSponsorBlocker256px.png");
|
(<HTMLImageElement> document.getElementById("startSponsorImage")).src = chrome.extension.getURL("icons/PlayerStartIconSponsorBlocker256px.png");
|
||||||
document.getElementById("startSponsorButton").setAttribute("title", chrome.i18n.getMessage("sponsorStart"));
|
document.getElementById("startSponsorButton").setAttribute("title", chrome.i18n.getMessage("sponsorStart"));
|
||||||
|
|
||||||
if (document.getElementById("startSponsorImage").style.display != "none" && uploadButtonVisible && !SB.config.hideInfoButtonPlayerControls) {
|
if (document.getElementById("startSponsorImage").style.display != "none" && uploadButtonVisible && !SB.config.hideInfoButtonPlayerControls) {
|
||||||
@@ -737,7 +795,7 @@ async function changeStartSponsorButton(showStartSponsor, uploadButtonVisible) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
showingStartSponsor = false;
|
showingStartSponsor = false;
|
||||||
document.getElementById("startSponsorImage").src = chrome.extension.getURL("icons/PlayerStopIconSponsorBlocker256px.png");
|
(<HTMLImageElement> document.getElementById("startSponsorImage")).src = chrome.extension.getURL("icons/PlayerStopIconSponsorBlocker256px.png");
|
||||||
document.getElementById("startSponsorButton").setAttribute("title", chrome.i18n.getMessage("sponsorEND"));
|
document.getElementById("startSponsorButton").setAttribute("title", chrome.i18n.getMessage("sponsorEND"));
|
||||||
|
|
||||||
//disable submit button
|
//disable submit button
|
||||||
@@ -769,7 +827,7 @@ function openInfoMenu() {
|
|||||||
//close button
|
//close button
|
||||||
let closeButton = document.createElement("div");
|
let closeButton = document.createElement("div");
|
||||||
closeButton.innerText = "Close Popup";
|
closeButton.innerText = "Close Popup";
|
||||||
closeButton.classList = "smallLink";
|
closeButton.classList.add("smallLink");
|
||||||
closeButton.setAttribute("align", "center");
|
closeButton.setAttribute("align", "center");
|
||||||
closeButton.addEventListener("click", closeInfoMenu);
|
closeButton.addEventListener("click", closeInfoMenu);
|
||||||
|
|
||||||
@@ -791,17 +849,17 @@ function openInfoMenu() {
|
|||||||
|
|
||||||
//make the logo source not 404
|
//make the logo source not 404
|
||||||
//query selector must be used since getElementByID doesn't work on a node and this isn't added to the document yet
|
//query selector must be used since getElementByID doesn't work on a node and this isn't added to the document yet
|
||||||
let logo = popup.querySelector("#sponsorBlockPopupLogo");
|
let logo = <HTMLImageElement> popup.querySelector("#sponsorBlockPopupLogo");
|
||||||
logo.src = chrome.extension.getURL("icons/LogoSponsorBlocker256px.png");
|
logo.src = chrome.extension.getURL("icons/LogoSponsorBlocker256px.png");
|
||||||
|
|
||||||
//remove the style sheet and font that are not necessary
|
//remove the style sheet and font that are not necessary
|
||||||
popup.querySelector("#sponorBlockPopupFont").remove();
|
popup.querySelector("#sponsorBlockPopupFont").remove();
|
||||||
popup.querySelector("#sponorBlockStyleSheet").remove();
|
popup.querySelector("#sponsorBlockStyleSheet").remove();
|
||||||
|
|
||||||
parentNode.insertBefore(popup, parentNode.firstChild);
|
parentNode.insertBefore(popup, parentNode.firstChild);
|
||||||
|
|
||||||
//run the popup init script
|
//run the popup init script
|
||||||
runThePopup();
|
runThePopup(messageListener);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -889,7 +947,7 @@ function vote(type, UUID, skipNotice) {
|
|||||||
skipNotice.addNoticeInfoMessage.bind(skipNotice)(chrome.i18n.getMessage("voteFail"))
|
skipNotice.addNoticeInfoMessage.bind(skipNotice)(chrome.i18n.getMessage("voteFail"))
|
||||||
skipNotice.resetVoteButtonInfo.bind(skipNotice)();
|
skipNotice.resetVoteButtonInfo.bind(skipNotice)();
|
||||||
} else if (response.successType == -1) {
|
} else if (response.successType == -1) {
|
||||||
skipNotice.addNoticeInfoMessage.bind(skipNotice)(getErrorMessage(response.statusCode))
|
skipNotice.addNoticeInfoMessage.bind(skipNotice)(utils.getErrorMessage(response.statusCode))
|
||||||
skipNotice.resetVoteButtonInfo.bind(skipNotice)();
|
skipNotice.resetVoteButtonInfo.bind(skipNotice)();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -961,7 +1019,7 @@ function submitSponsorTimes() {
|
|||||||
//called after all the checks have been made that it's okay to do so
|
//called after all the checks have been made that it's okay to do so
|
||||||
function sendSubmitMessage(){
|
function sendSubmitMessage(){
|
||||||
//add loading animation
|
//add loading animation
|
||||||
document.getElementById("submitImage").src = chrome.extension.getURL("icons/PlayerUploadIconSponsorBlocker256px.png");
|
(<HTMLImageElement> document.getElementById("submitImage")).src = chrome.extension.getURL("icons/PlayerUploadIconSponsorBlocker256px.png");
|
||||||
document.getElementById("submitButton").style.animation = "rotate 1s 0s infinite";
|
document.getElementById("submitButton").style.animation = "rotate 1s 0s infinite";
|
||||||
|
|
||||||
let currentVideoID = sponsorVideoID;
|
let currentVideoID = sponsorVideoID;
|
||||||
@@ -994,7 +1052,7 @@ function sendSubmitMessage(){
|
|||||||
sponsorTimes = sponsorTimes.concat(sponsorTimesSubmitting);
|
sponsorTimes = sponsorTimes.concat(sponsorTimesSubmitting);
|
||||||
for (let i = 0; i < sponsorTimesSubmitting.length; i++) {
|
for (let i = 0; i < sponsorTimesSubmitting.length; i++) {
|
||||||
// Add some random IDs
|
// Add some random IDs
|
||||||
UUIDs.push(generateUserID());
|
UUIDs.push(utils.generateUserID());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Empty the submitting times
|
// Empty the submitting times
|
||||||
@@ -1004,9 +1062,9 @@ function sendSubmitMessage(){
|
|||||||
} else {
|
} else {
|
||||||
//show that the upload failed
|
//show that the upload failed
|
||||||
document.getElementById("submitButton").style.animation = "unset";
|
document.getElementById("submitButton").style.animation = "unset";
|
||||||
document.getElementById("submitImage").src = chrome.extension.getURL("icons/PlayerUploadFailedIconSponsorBlocker256px.png");
|
(<HTMLImageElement> document.getElementById("submitImage")).src = chrome.extension.getURL("icons/PlayerUploadFailedIconSponsorBlocker256px.png");
|
||||||
|
|
||||||
alert(getErrorMessage(response.statusCode));
|
alert(utils.getErrorMessage(response.statusCode));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -1037,36 +1095,19 @@ function getSponsorTimesMessage(sponsorTimes) {
|
|||||||
//converts time in seconds to minutes:seconds
|
//converts time in seconds to minutes:seconds
|
||||||
function getFormattedTime(seconds) {
|
function getFormattedTime(seconds) {
|
||||||
let minutes = Math.floor(seconds / 60);
|
let minutes = Math.floor(seconds / 60);
|
||||||
let secondsDisplay = Math.round(seconds - minutes * 60);
|
let secondsNum: number = Math.round(seconds - minutes * 60);
|
||||||
if (secondsDisplay < 10) {
|
let secondsDisplay: string = String(secondsNum);
|
||||||
|
|
||||||
|
if (secondsNum < 10) {
|
||||||
//add a zero
|
//add a zero
|
||||||
secondsDisplay = "0" + secondsDisplay;
|
secondsDisplay = "0" + secondsNum;
|
||||||
}
|
}
|
||||||
|
|
||||||
let formatted = minutes+ ":" + secondsDisplay;
|
let formatted = minutes + ":" + secondsDisplay;
|
||||||
|
|
||||||
return formatted;
|
return formatted;
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendRequestToServer(type, address, callback) {
|
|
||||||
let xmlhttp = new XMLHttpRequest();
|
|
||||||
|
|
||||||
xmlhttp.open(type, serverAddress + address, true);
|
|
||||||
|
|
||||||
if (callback != undefined) {
|
|
||||||
xmlhttp.onreadystatechange = function () {
|
|
||||||
callback(xmlhttp, false);
|
|
||||||
};
|
|
||||||
|
|
||||||
xmlhttp.onerror = function(ev) {
|
|
||||||
callback(xmlhttp, true);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
//submit this request
|
|
||||||
xmlhttp.send();
|
|
||||||
}
|
|
||||||
|
|
||||||
function sendRequestToCustomServer(type, fullAddress, callback) {
|
function sendRequestToCustomServer(type, fullAddress, callback) {
|
||||||
let xmlhttp = new XMLHttpRequest();
|
let xmlhttp = new XMLHttpRequest();
|
||||||
|
|
||||||
@@ -21,11 +21,13 @@ let barTypes = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
class PreviewBar {
|
class PreviewBar {
|
||||||
|
container: HTMLUListElement;
|
||||||
|
parent: any;
|
||||||
|
|
||||||
constructor(parent) {
|
constructor(parent) {
|
||||||
this.container = document.createElement('ul');
|
this.container = document.createElement('ul');
|
||||||
this.container.id = 'previewbar';
|
this.container.id = 'previewbar';
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
this.bars = []
|
|
||||||
|
|
||||||
this.updatePosition();
|
this.updatePosition();
|
||||||
}
|
}
|
||||||
@@ -39,7 +41,7 @@ class PreviewBar {
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateColor(segment, color, opacity) {
|
updateColor(segment, color, opacity) {
|
||||||
let bars = document.querySelectorAll('[data-vs-segment-type=' + segment + ']');
|
let bars = <NodeListOf<HTMLElement>> document.querySelectorAll('[data-vs-segment-type=' + segment + ']');
|
||||||
for (let bar of bars) {
|
for (let bar of bars) {
|
||||||
bar.style.backgroundColor = color;
|
bar.style.backgroundColor = color;
|
||||||
bar.style.opacity = opacity;
|
bar.style.opacity = opacity;
|
||||||
@@ -73,8 +75,7 @@ class PreviewBar {
|
|||||||
bar.style.left = (timestamps[i][0] / duration * 100) + "%";
|
bar.style.left = (timestamps[i][0] / duration * 100) + "%";
|
||||||
bar.style.position = "absolute"
|
bar.style.position = "absolute"
|
||||||
|
|
||||||
this.container.insertAdjacentElement('beforeEnd', bar);
|
this.container.insertAdjacentElement("beforeend", bar);
|
||||||
this.bars[i] = bar;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,3 +91,5 @@ class PreviewBar {
|
|||||||
this.container = undefined;
|
this.container = undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default PreviewBar;
|
||||||
@@ -4,16 +4,23 @@
|
|||||||
* The notice that tells the user that a sponsor was just skipped
|
* The notice that tells the user that a sponsor was just skipped
|
||||||
*/
|
*/
|
||||||
class SkipNotice {
|
class SkipNotice {
|
||||||
/**
|
parent: HTMLElement;
|
||||||
* @param {HTMLElement} parent
|
UUID: string;
|
||||||
* @param {String} UUID
|
manualSkip: boolean;
|
||||||
* @param {String} noticeTitle
|
// Contains functions and variables from the content script needed by the skip notice
|
||||||
* @param {boolean} manualSkip
|
contentContainer: () => any;
|
||||||
*/
|
|
||||||
constructor(parent, UUID, manualSkip = false) {
|
maxCountdownTime: () => number;
|
||||||
|
countdownTime: any;
|
||||||
|
countdownInterval: NodeJS.Timeout;
|
||||||
|
unskipCallback: any;
|
||||||
|
idSuffix: any;
|
||||||
|
|
||||||
|
constructor(parent: HTMLElement, UUID: string, manualSkip: boolean = false, contentContainer) {
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
this.UUID = UUID;
|
this.UUID = UUID;
|
||||||
this.manualSkip = manualSkip;
|
this.manualSkip = manualSkip;
|
||||||
|
this.contentContainer = contentContainer;
|
||||||
|
|
||||||
let noticeTitle = chrome.i18n.getMessage("noticeTitle");
|
let noticeTitle = chrome.i18n.getMessage("noticeTitle");
|
||||||
|
|
||||||
@@ -25,7 +32,7 @@ class SkipNotice {
|
|||||||
//the countdown until this notice closes
|
//the countdown until this notice closes
|
||||||
this.countdownTime = this.maxCountdownTime();
|
this.countdownTime = this.maxCountdownTime();
|
||||||
//the id for the setInterval running the countdown
|
//the id for the setInterval running the countdown
|
||||||
this.countdownInterval = -1;
|
this.countdownInterval = null;
|
||||||
|
|
||||||
//the unskip button's callback
|
//the unskip button's callback
|
||||||
this.unskipCallback = this.unskip.bind(this);
|
this.unskipCallback = this.unskip.bind(this);
|
||||||
@@ -48,7 +55,7 @@ class SkipNotice {
|
|||||||
noticeElement.id = "sponsorSkipNotice" + this.idSuffix;
|
noticeElement.id = "sponsorSkipNotice" + this.idSuffix;
|
||||||
noticeElement.classList.add("sponsorSkipObject");
|
noticeElement.classList.add("sponsorSkipObject");
|
||||||
noticeElement.classList.add("sponsorSkipNotice");
|
noticeElement.classList.add("sponsorSkipNotice");
|
||||||
noticeElement.style.zIndex = 50 + amountOfPreviousNotices;
|
noticeElement.style.zIndex = String(50 + amountOfPreviousNotices);
|
||||||
|
|
||||||
//add mouse enter and leave listeners
|
//add mouse enter and leave listeners
|
||||||
noticeElement.addEventListener("mouseenter", this.pauseCountdown.bind(this));
|
noticeElement.addEventListener("mouseenter", this.pauseCountdown.bind(this));
|
||||||
@@ -121,7 +128,7 @@ class SkipNotice {
|
|||||||
downvoteButton.id = "sponsorTimesDownvoteButtonsContainer" + this.idSuffix;
|
downvoteButton.id = "sponsorTimesDownvoteButtonsContainer" + this.idSuffix;
|
||||||
downvoteButton.className = "sponsorSkipObject voteButton";
|
downvoteButton.className = "sponsorSkipObject voteButton";
|
||||||
downvoteButton.src = chrome.extension.getURL("icons/report.png");
|
downvoteButton.src = chrome.extension.getURL("icons/report.png");
|
||||||
downvoteButton.addEventListener("click", () => vote(0, this.UUID, this));
|
downvoteButton.addEventListener("click", () => this.contentContainer().vote(0, this.UUID, this));
|
||||||
downvoteButton.setAttribute("title", chrome.i18n.getMessage("reportButtonInfo"));
|
downvoteButton.setAttribute("title", chrome.i18n.getMessage("reportButtonInfo"));
|
||||||
|
|
||||||
//add downvote and report text to container
|
//add downvote and report text to container
|
||||||
@@ -149,7 +156,7 @@ class SkipNotice {
|
|||||||
let dontShowAgainButton = document.createElement("button");
|
let dontShowAgainButton = document.createElement("button");
|
||||||
dontShowAgainButton.innerText = chrome.i18n.getMessage("Hide");
|
dontShowAgainButton.innerText = chrome.i18n.getMessage("Hide");
|
||||||
dontShowAgainButton.className = "sponsorSkipObject sponsorSkipNoticeButton sponsorSkipNoticeRightButton";
|
dontShowAgainButton.className = "sponsorSkipObject sponsorSkipNoticeButton sponsorSkipNoticeRightButton";
|
||||||
dontShowAgainButton.addEventListener("click", dontShowNoticeAgain);
|
dontShowAgainButton.addEventListener("click", this.contentContainer().dontShowNoticeAgain);
|
||||||
|
|
||||||
// Don't let them hide it if manually skipping
|
// Don't let them hide it if manually skipping
|
||||||
if (!this.manualSkip) {
|
if (!this.manualSkip) {
|
||||||
@@ -170,12 +177,12 @@ class SkipNotice {
|
|||||||
if (referenceNode == null) {
|
if (referenceNode == null) {
|
||||||
//for embeds
|
//for embeds
|
||||||
let player = document.getElementById("player");
|
let player = document.getElementById("player");
|
||||||
referenceNode = player.firstChild;
|
referenceNode = <HTMLElement> player.firstChild;
|
||||||
let index = 1;
|
let index = 1;
|
||||||
|
|
||||||
//find the child that is the video player (sometimes it is not the first)
|
//find the child that is the video player (sometimes it is not the first)
|
||||||
while (!referenceNode.classList.contains("html5-video-player") || !referenceNode.classList.contains("ytp-embed")) {
|
while (!referenceNode.classList.contains("html5-video-player") || !referenceNode.classList.contains("ytp-embed")) {
|
||||||
referenceNode = player.children[index];
|
referenceNode = <HTMLElement> player.children[index];
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
@@ -217,7 +224,7 @@ class SkipNotice {
|
|||||||
pauseCountdown() {
|
pauseCountdown() {
|
||||||
//remove setInterval
|
//remove setInterval
|
||||||
clearInterval(this.countdownInterval);
|
clearInterval(this.countdownInterval);
|
||||||
this.countdownInterval = -1;
|
this.countdownInterval = null;
|
||||||
|
|
||||||
//reset countdown
|
//reset countdown
|
||||||
this.countdownTime = this.maxCountdownTime();
|
this.countdownTime = this.maxCountdownTime();
|
||||||
@@ -234,7 +241,7 @@ class SkipNotice {
|
|||||||
|
|
||||||
startCountdown() {
|
startCountdown() {
|
||||||
//if it has already started, don't start it again
|
//if it has already started, don't start it again
|
||||||
if (this.countdownInterval != -1) return;
|
if (this.countdownInterval !== null) return;
|
||||||
|
|
||||||
this.countdownInterval = setInterval(this.countdown.bind(this), 1000);
|
this.countdownInterval = setInterval(this.countdown.bind(this), 1000);
|
||||||
|
|
||||||
@@ -248,7 +255,7 @@ class SkipNotice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unskip() {
|
unskip() {
|
||||||
unskipSponsorTime(this.UUID);
|
this.contentContainer().unskipSponsorTime(this.UUID);
|
||||||
|
|
||||||
this.unskippedMode(chrome.i18n.getMessage("reskip"));
|
this.unskippedMode(chrome.i18n.getMessage("reskip"));
|
||||||
}
|
}
|
||||||
@@ -264,8 +271,8 @@ class SkipNotice {
|
|||||||
|
|
||||||
//change max duration to however much of the sponsor is left
|
//change max duration to however much of the sponsor is left
|
||||||
this.maxCountdownTime = function() {
|
this.maxCountdownTime = function() {
|
||||||
let sponsorTime = sponsorTimes[UUIDs.indexOf(this.UUID)];
|
let sponsorTime = this.contentContainer().sponsorTimes[this.contentContainer().UUIDs.indexOf(this.UUID)];
|
||||||
let duration = Math.round(sponsorTime[1] - v.currentTime);
|
let duration = Math.round(sponsorTime[1] - this.contentContainer().v.currentTime);
|
||||||
|
|
||||||
return Math.max(duration, 4);
|
return Math.max(duration, 4);
|
||||||
};
|
};
|
||||||
@@ -275,7 +282,7 @@ class SkipNotice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
reskip() {
|
reskip() {
|
||||||
reskipSponsorTime(this.UUID);
|
this.contentContainer().reskipSponsorTime(this.UUID);
|
||||||
|
|
||||||
//change reskip button to a unskip button
|
//change reskip button to a unskip button
|
||||||
let unskipButton = this.changeUnskipButton(chrome.i18n.getMessage("unskip"));
|
let unskipButton = this.changeUnskipButton(chrome.i18n.getMessage("unskip"));
|
||||||
@@ -293,7 +300,7 @@ class SkipNotice {
|
|||||||
if (this.manualSkip) {
|
if (this.manualSkip) {
|
||||||
this.changeNoticeTitle(chrome.i18n.getMessage("noticeTitle"));
|
this.changeNoticeTitle(chrome.i18n.getMessage("noticeTitle"));
|
||||||
|
|
||||||
vote(1, this.UUID, this);
|
this.contentContainer().vote(1, this.UUID, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -317,14 +324,14 @@ class SkipNotice {
|
|||||||
|
|
||||||
//remove this sponsor from the sponsors looked up
|
//remove this sponsor from the sponsors looked up
|
||||||
//find which one it is
|
//find which one it is
|
||||||
for (let i = 0; i < sponsorTimes.length; i++) {
|
for (let i = 0; i < this.contentContainer().sponsorTimes.length; i++) {
|
||||||
if (UUIDs[i] == this.UUID) {
|
if (this.contentContainer().UUIDs[i] == this.UUID) {
|
||||||
//this one is the one to hide
|
//this one is the one to hide
|
||||||
|
|
||||||
//add this as a hidden sponsorTime
|
//add this as a hidden sponsorTime
|
||||||
hiddenSponsorTimes.push(i);
|
this.contentContainer().hiddenSponsorTimes.push(i);
|
||||||
|
|
||||||
updatePreviewBar();
|
this.contentContainer().updatePreviewBar();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -336,7 +343,7 @@ class SkipNotice {
|
|||||||
noticeElement.innerText = title;
|
noticeElement.innerText = title;
|
||||||
}
|
}
|
||||||
|
|
||||||
addNoticeInfoMessage(message, message2) {
|
addNoticeInfoMessage(message: string, message2: string = "") {
|
||||||
let previousInfoMessage = document.getElementById("sponsorTimesInfoMessage" + this.idSuffix);
|
let previousInfoMessage = document.getElementById("sponsorTimesInfoMessage" + this.idSuffix);
|
||||||
if (previousInfoMessage != null) {
|
if (previousInfoMessage != null) {
|
||||||
//remove it
|
//remove it
|
||||||
@@ -422,7 +429,9 @@ class SkipNotice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//remove setInterval
|
//remove setInterval
|
||||||
if (this.countdownInterval != -1) clearInterval(this.countdownInterval);
|
if (this.countdownInterval !== null) clearInterval(this.countdownInterval);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default SkipNotice;
|
||||||
@@ -1,13 +1,18 @@
|
|||||||
|
import SB from "./SB";
|
||||||
|
|
||||||
|
import Utils from "./utils";
|
||||||
|
var utils = new Utils();
|
||||||
|
|
||||||
window.addEventListener('DOMContentLoaded', init);
|
window.addEventListener('DOMContentLoaded', init);
|
||||||
|
|
||||||
async function init() {
|
async function init() {
|
||||||
localizeHtmlPage();
|
utils.localizeHtmlPage();
|
||||||
|
|
||||||
if (!SB.configListeners.includes(optionsConfigUpdateListener)) {
|
if (!SB.configListeners.includes(optionsConfigUpdateListener)) {
|
||||||
SB.configListeners.push(optionsConfigUpdateListener);
|
SB.configListeners.push(optionsConfigUpdateListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
await wait(() => SB.config !== undefined);
|
await utils.wait(() => SB.config !== null);
|
||||||
|
|
||||||
// Set all of the toggle options to the correct option
|
// Set all of the toggle options to the correct option
|
||||||
let optionsContainer = document.getElementById("options");
|
let optionsContainer = document.getElementById("options");
|
||||||
@@ -51,23 +56,23 @@ async function init() {
|
|||||||
break;
|
break;
|
||||||
case "text-change":
|
case "text-change":
|
||||||
let button = optionsElements[i].querySelector(".trigger-button");
|
let button = optionsElements[i].querySelector(".trigger-button");
|
||||||
button.addEventListener("click", () => activateTextChange(optionsElements[i]));
|
button.addEventListener("click", () => activateTextChange(<HTMLElement> optionsElements[i]));
|
||||||
|
|
||||||
let textChangeOption = optionsElements[i].getAttribute("sync-option");
|
let textChangeOption = optionsElements[i].getAttribute("sync-option");
|
||||||
// See if anything extra must be done
|
// See if anything extra must be done
|
||||||
switch (textChangeOption) {
|
switch (textChangeOption) {
|
||||||
case "invidiousInstances":
|
case "invidiousInstances":
|
||||||
invidiousInstanceAddInit(optionsElements[i], textChangeOption);
|
invidiousInstanceAddInit(<HTMLElement> optionsElements[i], textChangeOption);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case "keybind-change":
|
case "keybind-change":
|
||||||
let keybindButton = optionsElements[i].querySelector(".trigger-button");
|
let keybindButton = optionsElements[i].querySelector(".trigger-button");
|
||||||
keybindButton.addEventListener("click", () => activateKeybindChange(optionsElements[i]));
|
keybindButton.addEventListener("click", () => activateKeybindChange(<HTMLElement> optionsElements[i]));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case "display":
|
case "display":
|
||||||
updateDisplayElement(optionsElements[i])
|
updateDisplayElement(<HTMLElement> optionsElements[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,7 +92,7 @@ function optionsConfigUpdateListener(changes) {
|
|||||||
for (let i = 0; i < optionsElements.length; i++) {
|
for (let i = 0; i < optionsElements.length; i++) {
|
||||||
switch (optionsElements[i].getAttribute("option-type")) {
|
switch (optionsElements[i].getAttribute("option-type")) {
|
||||||
case "display":
|
case "display":
|
||||||
updateDisplayElement(optionsElements[i])
|
updateDisplayElement(<HTMLElement> optionsElements[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -95,9 +100,9 @@ function optionsConfigUpdateListener(changes) {
|
|||||||
/**
|
/**
|
||||||
* Will set display elements to the proper text
|
* Will set display elements to the proper text
|
||||||
*
|
*
|
||||||
* @param {HTMLElement} element
|
* @param element
|
||||||
*/
|
*/
|
||||||
function updateDisplayElement(element) {
|
function updateDisplayElement(element: HTMLElement) {
|
||||||
let displayOption = element.getAttribute("sync-option")
|
let displayOption = element.getAttribute("sync-option")
|
||||||
let displayText = SB.config[displayOption];
|
let displayText = SB.config[displayOption];
|
||||||
element.innerText = displayText;
|
element.innerText = displayText;
|
||||||
@@ -113,11 +118,11 @@ function updateDisplayElement(element) {
|
|||||||
/**
|
/**
|
||||||
* Initializes the option to add Invidious instances
|
* Initializes the option to add Invidious instances
|
||||||
*
|
*
|
||||||
* @param {HTMLElement} element
|
* @param element
|
||||||
* @param {String} option
|
* @param option
|
||||||
*/
|
*/
|
||||||
function invidiousInstanceAddInit(element, option) {
|
function invidiousInstanceAddInit(element: HTMLElement, option: string) {
|
||||||
let textBox = element.querySelector(".option-text-box");
|
let textBox = <HTMLInputElement> element.querySelector(".option-text-box");
|
||||||
let button = element.querySelector(".trigger-button");
|
let button = element.querySelector(".trigger-button");
|
||||||
|
|
||||||
let setButton = element.querySelector(".text-change-set");
|
let setButton = element.querySelector(".text-change-set");
|
||||||
@@ -133,7 +138,7 @@ function invidiousInstanceAddInit(element, option) {
|
|||||||
|
|
||||||
SB.config[option] = instanceList;
|
SB.config[option] = instanceList;
|
||||||
|
|
||||||
let checkbox = document.querySelector("#support-invidious input");
|
let checkbox = <HTMLInputElement> document.querySelector("#support-invidious input");
|
||||||
checkbox.checked = true;
|
checkbox.checked = true;
|
||||||
|
|
||||||
invidiousOnClick(checkbox, "supportInvidious");
|
invidiousOnClick(checkbox, "supportInvidious");
|
||||||
@@ -158,15 +163,15 @@ function invidiousInstanceAddInit(element, option) {
|
|||||||
/**
|
/**
|
||||||
* Run when the invidious button is being initialized
|
* Run when the invidious button is being initialized
|
||||||
*
|
*
|
||||||
* @param {HTMLElement} checkbox
|
* @param checkbox
|
||||||
* @param {string} option
|
* @param option
|
||||||
*/
|
*/
|
||||||
function invidiousInit(checkbox, option) {
|
function invidiousInit(checkbox: HTMLInputElement, option: string) {
|
||||||
let permissions = ["declarativeContent"];
|
let permissions = ["declarativeContent"];
|
||||||
if (isFirefox()) permissions = [];
|
if (utils.isFirefox()) permissions = [];
|
||||||
|
|
||||||
chrome.permissions.contains({
|
chrome.permissions.contains({
|
||||||
origins: getInvidiousInstancesRegex(),
|
origins: utils.getInvidiousInstancesRegex(),
|
||||||
permissions: permissions
|
permissions: permissions
|
||||||
}, function (result) {
|
}, function (result) {
|
||||||
if (result != checkbox.checked) {
|
if (result != checkbox.checked) {
|
||||||
@@ -180,28 +185,28 @@ function invidiousInit(checkbox, option) {
|
|||||||
/**
|
/**
|
||||||
* Run whenever the invidious checkbox is clicked
|
* Run whenever the invidious checkbox is clicked
|
||||||
*
|
*
|
||||||
* @param {HTMLElement} checkbox
|
* @param checkbox
|
||||||
* @param {string} option
|
* @param option
|
||||||
*/
|
*/
|
||||||
function invidiousOnClick(checkbox, option) {
|
function invidiousOnClick(checkbox: HTMLInputElement, option: string) {
|
||||||
if (checkbox.checked) {
|
if (checkbox.checked) {
|
||||||
setupExtraSitePermissions(function (granted) {
|
utils.setupExtraSitePermissions(function (granted) {
|
||||||
if (!granted) {
|
if (!granted) {
|
||||||
SB.config[option] = false;
|
SB.config[option] = false;
|
||||||
checkbox.checked = false;
|
checkbox.checked = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
removeExtraSiteRegistration();
|
utils.removeExtraSiteRegistration();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Will trigger the container to ask the user for a keybind.
|
* Will trigger the container to ask the user for a keybind.
|
||||||
*
|
*
|
||||||
* @param {HTMLElement} element
|
* @param element
|
||||||
*/
|
*/
|
||||||
function activateKeybindChange(element) {
|
function activateKeybindChange(element: HTMLElement) {
|
||||||
let button = element.querySelector(".trigger-button");
|
let button = element.querySelector(".trigger-button");
|
||||||
if (button.classList.contains("disabled")) return;
|
if (button.classList.contains("disabled")) return;
|
||||||
|
|
||||||
@@ -211,11 +216,11 @@ function activateKeybindChange(element) {
|
|||||||
|
|
||||||
let currentlySet = SB.config[option] !== null ? chrome.i18n.getMessage("keybindCurrentlySet") : "";
|
let currentlySet = SB.config[option] !== null ? chrome.i18n.getMessage("keybindCurrentlySet") : "";
|
||||||
|
|
||||||
let status = element.querySelector(".option-hidden-section > .keybind-status");
|
let status = <HTMLElement> element.querySelector(".option-hidden-section > .keybind-status");
|
||||||
status.innerText = chrome.i18n.getMessage("keybindDescription") + currentlySet;
|
status.innerText = chrome.i18n.getMessage("keybindDescription") + currentlySet;
|
||||||
|
|
||||||
if (SB.config[option] !== null) {
|
if (SB.config[option] !== null) {
|
||||||
let statusKey = element.querySelector(".option-hidden-section > .keybind-status-key");
|
let statusKey = <HTMLElement> element.querySelector(".option-hidden-section > .keybind-status-key");
|
||||||
statusKey.innerText = SB.config[option];
|
statusKey.innerText = SB.config[option];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -227,11 +232,10 @@ function activateKeybindChange(element) {
|
|||||||
/**
|
/**
|
||||||
* Called when a key is pressed in an activiated keybind change option.
|
* Called when a key is pressed in an activiated keybind change option.
|
||||||
*
|
*
|
||||||
* @param {HTMLElement} element
|
* @param element
|
||||||
* @param {KeyboardEvent} e
|
* @param e
|
||||||
*/
|
*/
|
||||||
function keybindKeyPressed(element, e) {
|
function keybindKeyPressed(element: HTMLElement, e: KeyboardEvent) {
|
||||||
e = e || window.event;
|
|
||||||
var key = e.key;
|
var key = e.key;
|
||||||
|
|
||||||
let button = element.querySelector(".trigger-button");
|
let button = element.querySelector(".trigger-button");
|
||||||
@@ -247,10 +251,10 @@ function keybindKeyPressed(element, e) {
|
|||||||
|
|
||||||
SB.config[option] = key;
|
SB.config[option] = key;
|
||||||
|
|
||||||
let status = element.querySelector(".option-hidden-section > .keybind-status");
|
let status = <HTMLElement> element.querySelector(".option-hidden-section > .keybind-status");
|
||||||
status.innerText = chrome.i18n.getMessage("keybindDescriptionComplete");
|
status.innerText = chrome.i18n.getMessage("keybindDescriptionComplete");
|
||||||
|
|
||||||
let statusKey = element.querySelector(".option-hidden-section > .keybind-status-key");
|
let statusKey = <HTMLElement> element.querySelector(".option-hidden-section > .keybind-status-key");
|
||||||
statusKey.innerText = key;
|
statusKey.innerText = key;
|
||||||
|
|
||||||
button.classList.remove("disabled");
|
button.classList.remove("disabled");
|
||||||
@@ -259,15 +263,15 @@ function keybindKeyPressed(element, e) {
|
|||||||
/**
|
/**
|
||||||
* Will trigger the textbox to appear to be able to change an option's text.
|
* Will trigger the textbox to appear to be able to change an option's text.
|
||||||
*
|
*
|
||||||
* @param {HTMLElement} element
|
* @param element
|
||||||
*/
|
*/
|
||||||
function activateTextChange(element) {
|
function activateTextChange(element: HTMLElement) {
|
||||||
let button = element.querySelector(".trigger-button");
|
let button = element.querySelector(".trigger-button");
|
||||||
if (button.classList.contains("disabled")) return;
|
if (button.classList.contains("disabled")) return;
|
||||||
|
|
||||||
button.classList.add("disabled");
|
button.classList.add("disabled");
|
||||||
|
|
||||||
let textBox = element.querySelector(".option-text-box");
|
let textBox = <HTMLInputElement> element.querySelector(".option-text-box");
|
||||||
let option = element.getAttribute("sync-option");
|
let option = element.getAttribute("sync-option");
|
||||||
|
|
||||||
// See if anything extra must be done
|
// See if anything extra must be done
|
||||||
@@ -1,27 +1,50 @@
|
|||||||
//make this a function to allow this to run on the content page
|
import SB from "./SB";
|
||||||
async function runThePopup() {
|
|
||||||
localizeHtmlPage();
|
|
||||||
//is it in the popup or content script
|
|
||||||
var inPopup = true;
|
|
||||||
if (chrome.tabs == undefined) {
|
|
||||||
//this is on the content script, use direct communication
|
|
||||||
chrome.tabs = {};
|
|
||||||
chrome.tabs.sendMessage = function(id, request, callback) {
|
|
||||||
messageListener(request, null, callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
//add a dummy query method
|
import Utils from "./utils";
|
||||||
chrome.tabs.query = function(config, callback) {
|
var utils = new Utils();
|
||||||
callback([{
|
|
||||||
url: document.URL,
|
|
||||||
id: -1
|
|
||||||
}]);
|
|
||||||
}
|
|
||||||
|
|
||||||
inPopup = false;
|
interface MessageListener {
|
||||||
|
(request: any, sender: any, callback: (response: any) => void): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
class MessageHandler {
|
||||||
|
messageListener: MessageListener;
|
||||||
|
|
||||||
|
constructor (messageListener?: MessageListener) {
|
||||||
|
this.messageListener = messageListener;
|
||||||
}
|
}
|
||||||
|
|
||||||
await wait(() => SB.config !== undefined);
|
sendMessage(id: number, request, callback?) {
|
||||||
|
if (this.messageListener) {
|
||||||
|
this.messageListener(request, null, callback);
|
||||||
|
} else {
|
||||||
|
chrome.tabs.sendMessage(id, request, callback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
query(config, callback) {
|
||||||
|
if (this.messageListener) {
|
||||||
|
// Send back dummy info
|
||||||
|
callback([{
|
||||||
|
url: document.URL,
|
||||||
|
id: -1
|
||||||
|
}]);
|
||||||
|
} else {
|
||||||
|
chrome.tabs.query(config, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//make this a function to allow this to run on the content page
|
||||||
|
async function runThePopup(messageListener?: MessageListener) {
|
||||||
|
var messageHandler = new MessageHandler();
|
||||||
|
|
||||||
|
utils.localizeHtmlPage();
|
||||||
|
|
||||||
|
await utils.wait(() => SB.config !== null);
|
||||||
|
|
||||||
|
var PageElements: any = {};
|
||||||
|
|
||||||
["sponsorStart",
|
["sponsorStart",
|
||||||
// Top toggles
|
// Top toggles
|
||||||
@@ -77,22 +100,22 @@ async function runThePopup() {
|
|||||||
"videoFound",
|
"videoFound",
|
||||||
"sponsorMessageTimes",
|
"sponsorMessageTimes",
|
||||||
"downloadedSponsorMessageTimes",
|
"downloadedSponsorMessageTimes",
|
||||||
].forEach(id => SB[id] = document.getElementById(id));
|
].forEach(id => PageElements[id] = document.getElementById(id));
|
||||||
|
|
||||||
//setup click listeners
|
//setup click listeners
|
||||||
SB.sponsorStart.addEventListener("click", sendSponsorStartMessage);
|
PageElements.sponsorStart.addEventListener("click", sendSponsorStartMessage);
|
||||||
SB.whitelistChannel.addEventListener("click", whitelistChannel);
|
PageElements.whitelistChannel.addEventListener("click", whitelistChannel);
|
||||||
SB.unwhitelistChannel.addEventListener("click", unwhitelistChannel);
|
PageElements.unwhitelistChannel.addEventListener("click", unwhitelistChannel);
|
||||||
SB.disableSkipping.addEventListener("click", () => toggleSkipping(true));
|
PageElements.disableSkipping.addEventListener("click", () => toggleSkipping(true));
|
||||||
SB.enableSkipping.addEventListener("click", () => toggleSkipping(false));
|
PageElements.enableSkipping.addEventListener("click", () => toggleSkipping(false));
|
||||||
SB.clearTimes.addEventListener("click", clearTimes);
|
PageElements.clearTimes.addEventListener("click", clearTimes);
|
||||||
SB.submitTimes.addEventListener("click", submitTimes);
|
PageElements.submitTimes.addEventListener("click", submitTimes);
|
||||||
SB.showNoticeAgain.addEventListener("click", showNoticeAgain);
|
PageElements.showNoticeAgain.addEventListener("click", showNoticeAgain);
|
||||||
SB.setUsernameButton.addEventListener("click", setUsernameButton);
|
PageElements.setUsernameButton.addEventListener("click", setUsernameButton);
|
||||||
SB.submitUsername.addEventListener("click", submitUsername);
|
PageElements.submitUsername.addEventListener("click", submitUsername);
|
||||||
SB.optionsButton.addEventListener("click", openOptions);
|
PageElements.optionsButton.addEventListener("click", openOptions);
|
||||||
SB.reportAnIssue.addEventListener("click", reportAnIssue);
|
PageElements.reportAnIssue.addEventListener("click", reportAnIssue);
|
||||||
SB.hideDiscordButton.addEventListener("click", hideDiscordButton);
|
PageElements.hideDiscordButton.addEventListener("click", hideDiscordButton);
|
||||||
|
|
||||||
//if true, the button now selects the end time
|
//if true, the button now selects the end time
|
||||||
let startTimeChosen = false;
|
let startTimeChosen = false;
|
||||||
@@ -109,7 +132,7 @@ async function runThePopup() {
|
|||||||
let hideDiscordLaunches = SB.config.hideDiscordLaunches;
|
let hideDiscordLaunches = SB.config.hideDiscordLaunches;
|
||||||
//only if less than 10 launches
|
//only if less than 10 launches
|
||||||
if (hideDiscordLaunches == undefined || hideDiscordLaunches < 10) {
|
if (hideDiscordLaunches == undefined || hideDiscordLaunches < 10) {
|
||||||
SB.discordButtonContainer.style.display = null;
|
PageElements.discordButtonContainer.style.display = null;
|
||||||
|
|
||||||
if (hideDiscordLaunches == undefined) {
|
if (hideDiscordLaunches == undefined) {
|
||||||
hideDiscordLaunches = 1;
|
hideDiscordLaunches = 1;
|
||||||
@@ -121,98 +144,98 @@ async function runThePopup() {
|
|||||||
//show proper disable skipping button
|
//show proper disable skipping button
|
||||||
let disableSkipping = SB.config.disableSkipping;
|
let disableSkipping = SB.config.disableSkipping;
|
||||||
if (disableSkipping != undefined && disableSkipping) {
|
if (disableSkipping != undefined && disableSkipping) {
|
||||||
SB.disableSkipping.style.display = "none";
|
PageElements.disableSkipping.style.display = "none";
|
||||||
SB.enableSkipping.style.display = "unset";
|
PageElements.enableSkipping.style.display = "unset";
|
||||||
}
|
}
|
||||||
|
|
||||||
//if the don't show notice again variable is true, an option to
|
//if the don't show notice again variable is true, an option to
|
||||||
// disable should be available
|
// disable should be available
|
||||||
let dontShowNotice = SB.config.dontShowNotice;
|
let dontShowNotice = SB.config.dontShowNotice;
|
||||||
if (dontShowNotice != undefined && dontShowNotice) {
|
if (dontShowNotice != undefined && dontShowNotice) {
|
||||||
SB.showNoticeAgain.style.display = "unset";
|
PageElements.showNoticeAgain.style.display = "unset";
|
||||||
}
|
}
|
||||||
|
|
||||||
//get the amount of times this user has contributed and display it to thank them
|
//get the amount of times this user has contributed and display it to thank them
|
||||||
if (SB.config.sponsorTimesContributed != undefined) {
|
if (SB.config.sponsorTimesContributed != undefined) {
|
||||||
if (SB.config.sponsorTimesContributed > 1) {
|
if (SB.config.sponsorTimesContributed > 1) {
|
||||||
SB.sponsorTimesContributionsDisplayEndWord.innerText = chrome.i18n.getMessage("Sponsors");
|
PageElements.sponsorTimesContributionsDisplayEndWord.innerText = chrome.i18n.getMessage("Sponsors");
|
||||||
} else {
|
} else {
|
||||||
SB.sponsorTimesContributionsDisplayEndWord.innerText = chrome.i18n.getMessage("Sponsor");
|
PageElements.sponsorTimesContributionsDisplayEndWord.innerText = chrome.i18n.getMessage("Sponsor");
|
||||||
}
|
}
|
||||||
SB.sponsorTimesContributionsDisplay.innerText = SB.config.sponsorTimesContributed;
|
PageElements.sponsorTimesContributionsDisplay.innerText = SB.config.sponsorTimesContributed;
|
||||||
SB.sponsorTimesContributionsContainer.style.display = "unset";
|
PageElements.sponsorTimesContributionsContainer.style.display = "unset";
|
||||||
|
|
||||||
//get the userID
|
//get the userID
|
||||||
let userID = SB.config.userID;
|
let userID = SB.config.userID;
|
||||||
if (userID != undefined) {
|
if (userID != undefined) {
|
||||||
//there are probably some views on these submissions then
|
//there are probably some views on these submissions then
|
||||||
//get the amount of views from the sponsors submitted
|
//get the amount of views from the sponsors submitted
|
||||||
sendRequestToServer("GET", "/api/getViewsForUser?userID=" + userID, function(xmlhttp) {
|
utils.sendRequestToServer("GET", "/api/getViewsForUser?userID=" + userID, function(xmlhttp) {
|
||||||
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
|
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
|
||||||
let viewCount = JSON.parse(xmlhttp.responseText).viewCount;
|
let viewCount = JSON.parse(xmlhttp.responseText).viewCount;
|
||||||
if (viewCount != 0) {
|
if (viewCount != 0) {
|
||||||
if (viewCount > 1) {
|
if (viewCount > 1) {
|
||||||
SB.sponsorTimesViewsDisplayEndWord.innerText = chrome.i18n.getMessage("Segments");
|
PageElements.sponsorTimesViewsDisplayEndWord.innerText = chrome.i18n.getMessage("Segments");
|
||||||
} else {
|
} else {
|
||||||
SB.sponsorTimesViewsDisplayEndWord.innerText = chrome.i18n.getMessage("Segment");
|
PageElements.sponsorTimesViewsDisplayEndWord.innerText = chrome.i18n.getMessage("Segment");
|
||||||
}
|
|
||||||
|
|
||||||
SB.sponsorTimesViewsDisplay.innerText = viewCount;
|
|
||||||
SB.sponsorTimesViewsContainer.style.display = "unset";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PageElements.sponsorTimesViewsDisplay.innerText = viewCount;
|
||||||
|
PageElements.sponsorTimesViewsContainer.style.display = "unset";
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
});
|
||||||
|
|
||||||
//get this time in minutes
|
//get this time in minutes
|
||||||
sendRequestToServer("GET", "/api/getSavedTimeForUser?userID=" + userID, function(xmlhttp) {
|
utils.sendRequestToServer("GET", "/api/getSavedTimeForUser?userID=" + userID, function(xmlhttp) {
|
||||||
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
|
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
|
||||||
let minutesSaved = JSON.parse(xmlhttp.responseText).timeSaved;
|
let minutesSaved = JSON.parse(xmlhttp.responseText).timeSaved;
|
||||||
if (minutesSaved != 0) {
|
if (minutesSaved != 0) {
|
||||||
if (minutesSaved != 1) {
|
if (minutesSaved != 1) {
|
||||||
SB.sponsorTimesOthersTimeSavedEndWord.innerText = chrome.i18n.getMessage("minsLower");
|
PageElements.sponsorTimesOthersTimeSavedEndWord.innerText = chrome.i18n.getMessage("minsLower");
|
||||||
} else {
|
} else {
|
||||||
SB.sponsorTimesOthersTimeSavedEndWord.innerText = chrome.i18n.getMessage("minLower");
|
PageElements.sponsorTimesOthersTimeSavedEndWord.innerText = chrome.i18n.getMessage("minLower");
|
||||||
}
|
|
||||||
|
|
||||||
SB.sponsorTimesOthersTimeSavedDisplay.innerText = getFormattedHours(minutesSaved);
|
|
||||||
SB.sponsorTimesOthersTimeSavedContainer.style.display = "unset";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PageElements.sponsorTimesOthersTimeSavedDisplay.innerText = getFormattedHours(minutesSaved);
|
||||||
|
PageElements.sponsorTimesOthersTimeSavedContainer.style.display = "unset";
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//get the amount of times this user has skipped a sponsor
|
//get the amount of times this user has skipped a sponsor
|
||||||
if (SB.config.skipCount != undefined) {
|
if (SB.config.skipCount != undefined) {
|
||||||
if (SB.config.skipCount != 1) {
|
if (SB.config.skipCount != 1) {
|
||||||
SB.sponsorTimesSkipsDoneEndWord.innerText = chrome.i18n.getMessage("Sponsors");
|
PageElements.sponsorTimesSkipsDoneEndWord.innerText = chrome.i18n.getMessage("Sponsors");
|
||||||
} else {
|
} else {
|
||||||
SB.sponsorTimesSkipsDoneEndWord.innerText = chrome.i18n.getMessage("Sponsor");
|
PageElements.sponsorTimesSkipsDoneEndWord.innerText = chrome.i18n.getMessage("Sponsor");
|
||||||
}
|
}
|
||||||
|
|
||||||
SB.sponsorTimesSkipsDoneDisplay.innerText = SB.config.skipCount;
|
PageElements.sponsorTimesSkipsDoneDisplay.innerText = SB.config.skipCount;
|
||||||
SB.sponsorTimesSkipsDoneContainer.style.display = "unset";
|
PageElements.sponsorTimesSkipsDoneContainer.style.display = "unset";
|
||||||
}
|
}
|
||||||
|
|
||||||
//get the amount of time this user has saved.
|
//get the amount of time this user has saved.
|
||||||
if (SB.config.minutesSaved != undefined) {
|
if (SB.config.minutesSaved != undefined) {
|
||||||
if (SB.config.minutesSaved != 1) {
|
if (SB.config.minutesSaved != 1) {
|
||||||
SB.sponsorTimeSavedEndWord.innerText = chrome.i18n.getMessage("minsLower");
|
PageElements.sponsorTimeSavedEndWord.innerText = chrome.i18n.getMessage("minsLower");
|
||||||
} else {
|
} else {
|
||||||
SB.sponsorTimeSavedEndWord.innerText = chrome.i18n.getMessage("minLower");
|
PageElements.sponsorTimeSavedEndWord.innerText = chrome.i18n.getMessage("minLower");
|
||||||
}
|
}
|
||||||
|
|
||||||
SB.sponsorTimeSavedDisplay.innerText = getFormattedHours(SB.config.minutesSaved);
|
PageElements.sponsorTimeSavedDisplay.innerText = getFormattedHours(SB.config.minutesSaved);
|
||||||
SB.sponsorTimeSavedContainer.style.display = "unset";
|
PageElements.sponsorTimeSavedContainer.style.display = "unset";
|
||||||
}
|
}
|
||||||
|
|
||||||
chrome.tabs.query({
|
messageHandler.query({
|
||||||
active: true,
|
active: true,
|
||||||
currentWindow: true
|
currentWindow: true
|
||||||
}, onTabs);
|
}, onTabs);
|
||||||
|
|
||||||
function onTabs(tabs) {
|
function onTabs(tabs) {
|
||||||
chrome.tabs.sendMessage(tabs[0].id, {message: 'getVideoID'}, function(result) {
|
messageHandler.sendMessage(tabs[0].id, {message: 'getVideoID'}, function(result) {
|
||||||
if (result != undefined && result.videoID) {
|
if (result != undefined && result.videoID) {
|
||||||
currentVideoID = result.videoID;
|
currentVideoID = result.videoID;
|
||||||
loadTabData(tabs);
|
loadTabData(tabs);
|
||||||
@@ -235,7 +258,7 @@ async function runThePopup() {
|
|||||||
if (sponsorTimesStorage != undefined && sponsorTimesStorage.length > 0) {
|
if (sponsorTimesStorage != undefined && sponsorTimesStorage.length > 0) {
|
||||||
if (sponsorTimesStorage[sponsorTimesStorage.length - 1] != undefined && sponsorTimesStorage[sponsorTimesStorage.length - 1].length < 2) {
|
if (sponsorTimesStorage[sponsorTimesStorage.length - 1] != undefined && sponsorTimesStorage[sponsorTimesStorage.length - 1].length < 2) {
|
||||||
startTimeChosen = true;
|
startTimeChosen = true;
|
||||||
SB.sponsorStart.innerHTML = chrome.i18n.getMessage("sponsorEnd");
|
PageElements.sponsorStart.innerHTML = chrome.i18n.getMessage("sponsorEnd");
|
||||||
}
|
}
|
||||||
|
|
||||||
sponsorTimes = sponsorTimesStorage;
|
sponsorTimes = sponsorTimesStorage;
|
||||||
@@ -243,13 +266,13 @@ async function runThePopup() {
|
|||||||
displaySponsorTimes();
|
displaySponsorTimes();
|
||||||
|
|
||||||
//show submission section
|
//show submission section
|
||||||
SB.submissionSection.style.display = "unset";
|
PageElements.submissionSection.style.display = "unset";
|
||||||
|
|
||||||
showSubmitTimesIfNecessary();
|
showSubmitTimesIfNecessary();
|
||||||
}
|
}
|
||||||
|
|
||||||
//check if this video's sponsors are known
|
//check if this video's sponsors are known
|
||||||
chrome.tabs.sendMessage(
|
messageHandler.sendMessage(
|
||||||
tabs[0].id,
|
tabs[0].id,
|
||||||
{message: 'isInfoFound'},
|
{message: 'isInfoFound'},
|
||||||
infoFound
|
infoFound
|
||||||
@@ -265,38 +288,34 @@ async function runThePopup() {
|
|||||||
|
|
||||||
//if request is undefined, then the page currently being browsed is not YouTube
|
//if request is undefined, then the page currently being browsed is not YouTube
|
||||||
if (request != undefined) {
|
if (request != undefined) {
|
||||||
//this must be a YouTube video
|
|
||||||
//set letiable
|
|
||||||
isYouTubeTab = true;
|
|
||||||
|
|
||||||
//remove loading text
|
//remove loading text
|
||||||
SB.mainControls.style.display = "unset"
|
PageElements.mainControls.style.display = "unset"
|
||||||
SB.loadingIndicator.style.display = "none";
|
PageElements.loadingIndicator.style.display = "none";
|
||||||
|
|
||||||
if (request.found) {
|
if (request.found) {
|
||||||
SB.videoFound.innerHTML = chrome.i18n.getMessage("sponsorFound");
|
PageElements.videoFound.innerHTML = chrome.i18n.getMessage("sponsorFound");
|
||||||
|
|
||||||
displayDownloadedSponsorTimes(request);
|
displayDownloadedSponsorTimes(request);
|
||||||
} else {
|
} else {
|
||||||
SB.videoFound.innerHTML = chrome.i18n.getMessage("sponsor404");
|
PageElements.videoFound.innerHTML = chrome.i18n.getMessage("sponsor404");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//see if whitelist button should be swapped
|
//see if whitelist button should be swapped
|
||||||
chrome.tabs.query({
|
messageHandler.query({
|
||||||
active: true,
|
active: true,
|
||||||
currentWindow: true
|
currentWindow: true
|
||||||
}, tabs => {
|
}, tabs => {
|
||||||
chrome.tabs.sendMessage(
|
messageHandler.sendMessage(
|
||||||
tabs[0].id,
|
tabs[0].id,
|
||||||
{message: 'isChannelWhitelisted'},
|
{message: 'isChannelWhitelisted'},
|
||||||
function(response) {
|
function(response) {
|
||||||
if (response.value) {
|
if (response.value) {
|
||||||
SB.whitelistChannel.style.display = "none";
|
PageElements.whitelistChannel.style.display = "none";
|
||||||
SB.unwhitelistChannel.style.display = "unset";
|
PageElements.unwhitelistChannel.style.display = "unset";
|
||||||
|
|
||||||
SB.downloadedSponsorMessageTimes.innerText = chrome.i18n.getMessage("channelWhitelisted");
|
PageElements.downloadedSponsorMessageTimes.innerText = chrome.i18n.getMessage("channelWhitelisted");
|
||||||
SB.downloadedSponsorMessageTimes.style.fontWeight = "bold";
|
PageElements.downloadedSponsorMessageTimes.style.fontWeight = "bold";
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -304,17 +323,17 @@ async function runThePopup() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function sendSponsorStartMessage() {
|
function sendSponsorStartMessage() {
|
||||||
//the content script will get the message if a YouTube page is open
|
//the content script will get the message if a YouTube page is open
|
||||||
chrome.tabs.query({
|
messageHandler.query({
|
||||||
active: true,
|
active: true,
|
||||||
currentWindow: true
|
currentWindow: true
|
||||||
}, tabs => {
|
}, tabs => {
|
||||||
chrome.tabs.sendMessage(
|
messageHandler.sendMessage(
|
||||||
tabs[0].id,
|
tabs[0].id,
|
||||||
{from: 'popup', message: 'sponsorStart'},
|
{from: 'popup', message: 'sponsorStart'},
|
||||||
startSponsorCallback
|
startSponsorCallback
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function startSponsorCallback(response) {
|
function startSponsorCallback(response) {
|
||||||
@@ -328,18 +347,19 @@ async function runThePopup() {
|
|||||||
|
|
||||||
let localStartTimeChosen = startTimeChosen;
|
let localStartTimeChosen = startTimeChosen;
|
||||||
SB.config.sponsorTimes.set(currentVideoID, sponsorTimes);
|
SB.config.sponsorTimes.set(currentVideoID, sponsorTimes);
|
||||||
//send a message to the client script
|
|
||||||
if (localStartTimeChosen) {
|
//send a message to the client script
|
||||||
chrome.tabs.query({
|
if (localStartTimeChosen) {
|
||||||
active: true,
|
messageHandler.query({
|
||||||
currentWindow: true
|
active: true,
|
||||||
}, tabs => {
|
currentWindow: true
|
||||||
chrome.tabs.sendMessage(
|
}, tabs => {
|
||||||
tabs[0].id,
|
messageHandler.sendMessage(
|
||||||
{message: "sponsorDataChanged"}
|
tabs[0].id,
|
||||||
);
|
{message: "sponsorDataChanged"}
|
||||||
});
|
);
|
||||||
}
|
});
|
||||||
|
}
|
||||||
|
|
||||||
updateStartTimeChosen();
|
updateStartTimeChosen();
|
||||||
|
|
||||||
@@ -347,7 +367,7 @@ async function runThePopup() {
|
|||||||
displaySponsorTimes();
|
displaySponsorTimes();
|
||||||
|
|
||||||
//show submission section
|
//show submission section
|
||||||
SB.submissionSection.style.display = "unset";
|
PageElements.submissionSection.style.display = "unset";
|
||||||
|
|
||||||
showSubmitTimesIfNecessary();
|
showSubmitTimesIfNecessary();
|
||||||
}
|
}
|
||||||
@@ -355,20 +375,20 @@ async function runThePopup() {
|
|||||||
//display the video times from the array
|
//display the video times from the array
|
||||||
function displaySponsorTimes() {
|
function displaySponsorTimes() {
|
||||||
//remove all children
|
//remove all children
|
||||||
while (SB.sponsorMessageTimes.firstChild) {
|
while (PageElements.sponsorMessageTimes.firstChild) {
|
||||||
SB.sponsorMessageTimes.removeChild(SB.sponsorMessageTimes.firstChild);
|
PageElements.sponsorMessageTimes.removeChild(PageElements.sponsorMessageTimes.firstChild);
|
||||||
}
|
}
|
||||||
|
|
||||||
//add sponsor times
|
//add sponsor times
|
||||||
SB.sponsorMessageTimes.appendChild(getSponsorTimesMessageDiv(sponsorTimes));
|
PageElements.sponsorMessageTimes.appendChild(getSponsorTimesMessageDiv(sponsorTimes));
|
||||||
}
|
}
|
||||||
|
|
||||||
//display the video times from the array at the top, in a different section
|
//display the video times from the array at the top, in a different section
|
||||||
function displayDownloadedSponsorTimes(request) {
|
function displayDownloadedSponsorTimes(request) {
|
||||||
if (request.sponsorTimes != undefined) {
|
if (request.sponsorTimes != undefined) {
|
||||||
//set it to the message
|
//set it to the message
|
||||||
if (SB.downloadedSponsorMessageTimes.innerText != chrome.i18n.getMessage("channelWhitelisted")) {
|
if (PageElements.downloadedSponsorMessageTimes.innerText != chrome.i18n.getMessage("channelWhitelisted")) {
|
||||||
SB.downloadedSponsorMessageTimes.innerText = getSponsorTimesMessage(request.sponsorTimes);
|
PageElements.downloadedSponsorMessageTimes.innerText = getSponsorTimesMessage(request.sponsorTimes);
|
||||||
}
|
}
|
||||||
|
|
||||||
//add them as buttons to the issue reporting container
|
//add them as buttons to the issue reporting container
|
||||||
@@ -526,11 +546,11 @@ async function runThePopup() {
|
|||||||
saveSponsorTimeEdit(index, false);
|
saveSponsorTimeEdit(index, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
chrome.tabs.query({
|
messageHandler.query({
|
||||||
active: true,
|
active: true,
|
||||||
currentWindow: true
|
currentWindow: true
|
||||||
}, tabs => {
|
}, tabs => {
|
||||||
chrome.tabs.sendMessage(
|
messageHandler.sendMessage(
|
||||||
tabs[0].id, {
|
tabs[0].id, {
|
||||||
message: "skipToTime",
|
message: "skipToTime",
|
||||||
time: skipTime - 2
|
time: skipTime - 2
|
||||||
@@ -562,7 +582,7 @@ async function runThePopup() {
|
|||||||
startTimeMinutes.id = "startTimeMinutes" + index;
|
startTimeMinutes.id = "startTimeMinutes" + index;
|
||||||
startTimeMinutes.className = "sponsorTime popupElement";
|
startTimeMinutes.className = "sponsorTime popupElement";
|
||||||
startTimeMinutes.type = "text";
|
startTimeMinutes.type = "text";
|
||||||
startTimeMinutes.value = getTimeInMinutes(sponsorTimes[index][0]);
|
startTimeMinutes.value = String(getTimeInMinutes(sponsorTimes[index][0]));
|
||||||
startTimeMinutes.style.width = "45px";
|
startTimeMinutes.style.width = "45px";
|
||||||
|
|
||||||
let startTimeSeconds = document.createElement("input");
|
let startTimeSeconds = document.createElement("input");
|
||||||
@@ -576,7 +596,7 @@ async function runThePopup() {
|
|||||||
endTimeMinutes.id = "endTimeMinutes" + index;
|
endTimeMinutes.id = "endTimeMinutes" + index;
|
||||||
endTimeMinutes.className = "sponsorTime popupElement";
|
endTimeMinutes.className = "sponsorTime popupElement";
|
||||||
endTimeMinutes.type = "text";
|
endTimeMinutes.type = "text";
|
||||||
endTimeMinutes.value = getTimeInMinutes(sponsorTimes[index][1]);
|
endTimeMinutes.value = String(getTimeInMinutes(sponsorTimes[index][1]));
|
||||||
endTimeMinutes.style.width = "45px";
|
endTimeMinutes.style.width = "45px";
|
||||||
|
|
||||||
let endTimeSeconds = document.createElement("input");
|
let endTimeSeconds = document.createElement("input");
|
||||||
@@ -628,18 +648,18 @@ async function runThePopup() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function setEditTimeToCurrentTime(idStartName, index) {
|
function setEditTimeToCurrentTime(idStartName, index) {
|
||||||
chrome.tabs.query({
|
messageHandler.query({
|
||||||
active: true,
|
active: true,
|
||||||
currentWindow: true
|
currentWindow: true
|
||||||
}, tabs => {
|
}, tabs => {
|
||||||
chrome.tabs.sendMessage(
|
messageHandler.sendMessage(
|
||||||
tabs[0].id,
|
tabs[0].id,
|
||||||
{message: "getCurrentTime"},
|
{message: "getCurrentTime"},
|
||||||
function (response) {
|
function (response) {
|
||||||
let minutes = document.getElementById(idStartName + "Minutes" + index);
|
let minutes = <HTMLInputElement> <unknown> document.getElementById(idStartName + "Minutes" + index);
|
||||||
let seconds = document.getElementById(idStartName + "Seconds" + index);
|
let seconds = <HTMLInputElement> <unknown> document.getElementById(idStartName + "Seconds" + index);
|
||||||
|
|
||||||
minutes.value = getTimeInMinutes(response.currentTime);
|
minutes.value = String(getTimeInMinutes(response.currentTime));
|
||||||
seconds.value = getTimeInFormattedSeconds(response.currentTime);
|
seconds.value = getTimeInFormattedSeconds(response.currentTime);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -648,10 +668,10 @@ async function runThePopup() {
|
|||||||
//id start name is whether it is the startTime or endTime
|
//id start name is whether it is the startTime or endTime
|
||||||
//gives back the time in seconds
|
//gives back the time in seconds
|
||||||
function getSponsorTimeEditTimes(idStartName, index) {
|
function getSponsorTimeEditTimes(idStartName, index) {
|
||||||
let minutes = document.getElementById(idStartName + "Minutes" + index);
|
let minutes = <HTMLInputElement> <unknown> document.getElementById(idStartName + "Minutes" + index);
|
||||||
let seconds = document.getElementById(idStartName + "Seconds" + index);
|
let seconds = <HTMLInputElement> <unknown> document.getElementById(idStartName + "Seconds" + index);
|
||||||
|
|
||||||
return parseInt(minutes.value) * 60 + parseFloat(seconds.value);
|
return parseInt(minutes.value) * 60 + seconds.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
function saveSponsorTimeEdit(index, closeEditMode = true) {
|
function saveSponsorTimeEdit(index, closeEditMode = true) {
|
||||||
@@ -660,11 +680,11 @@ async function runThePopup() {
|
|||||||
|
|
||||||
//save this
|
//save this
|
||||||
SB.config.sponsorTimes.set(currentVideoID, sponsorTimes);
|
SB.config.sponsorTimes.set(currentVideoID, sponsorTimes);
|
||||||
chrome.tabs.query({
|
messageHandler.query({
|
||||||
active: true,
|
active: true,
|
||||||
currentWindow: true
|
currentWindow: true
|
||||||
}, tabs => {
|
}, tabs => {
|
||||||
chrome.tabs.sendMessage(
|
messageHandler.sendMessage(
|
||||||
tabs[0].id,
|
tabs[0].id,
|
||||||
{message: "sponsorDataChanged"}
|
{message: "sponsorDataChanged"}
|
||||||
);
|
);
|
||||||
@@ -681,11 +701,11 @@ async function runThePopup() {
|
|||||||
function deleteSponsorTime(index) {
|
function deleteSponsorTime(index) {
|
||||||
//if it is not a complete sponsor time
|
//if it is not a complete sponsor time
|
||||||
if (sponsorTimes[index].length < 2) {
|
if (sponsorTimes[index].length < 2) {
|
||||||
chrome.tabs.query({
|
messageHandler.query({
|
||||||
active: true,
|
active: true,
|
||||||
currentWindow: true
|
currentWindow: true
|
||||||
}, function(tabs) {
|
}, function(tabs) {
|
||||||
chrome.tabs.sendMessage(tabs[0].id, {
|
messageHandler.sendMessage(tabs[0].id, {
|
||||||
message: "changeStartSponsorButton",
|
message: "changeStartSponsorButton",
|
||||||
showStartSponsor: true,
|
showStartSponsor: true,
|
||||||
uploadButtonVisible: false
|
uploadButtonVisible: false
|
||||||
@@ -699,11 +719,11 @@ async function runThePopup() {
|
|||||||
|
|
||||||
//save this
|
//save this
|
||||||
SB.config.sponsorTimes.set(currentVideoID, sponsorTimes);
|
SB.config.sponsorTimes.set(currentVideoID, sponsorTimes);
|
||||||
chrome.tabs.query({
|
messageHandler.query({
|
||||||
active: true,
|
active: true,
|
||||||
currentWindow: true
|
currentWindow: true
|
||||||
}, tabs => {
|
}, tabs => {
|
||||||
chrome.tabs.sendMessage(
|
messageHandler.sendMessage(
|
||||||
tabs[0].id,
|
tabs[0].id,
|
||||||
{message: "sponsorDataChanged"}
|
{message: "sponsorDataChanged"}
|
||||||
);
|
);
|
||||||
@@ -715,11 +735,11 @@ async function runThePopup() {
|
|||||||
//if they are all removed
|
//if they are all removed
|
||||||
if (sponsorTimes.length == 0) {
|
if (sponsorTimes.length == 0) {
|
||||||
//update chrome tab
|
//update chrome tab
|
||||||
chrome.tabs.query({
|
messageHandler.query({
|
||||||
active: true,
|
active: true,
|
||||||
currentWindow: true
|
currentWindow: true
|
||||||
}, function(tabs) {
|
}, function(tabs) {
|
||||||
chrome.tabs.sendMessage(tabs[0].id, {
|
messageHandler.sendMessage(tabs[0].id, {
|
||||||
message: "changeStartSponsorButton",
|
message: "changeStartSponsorButton",
|
||||||
showStartSponsor: true,
|
showStartSponsor: true,
|
||||||
uploadButtonVisible: false
|
uploadButtonVisible: false
|
||||||
@@ -734,11 +754,11 @@ async function runThePopup() {
|
|||||||
function clearTimes() {
|
function clearTimes() {
|
||||||
//send new sponsor time state to tab
|
//send new sponsor time state to tab
|
||||||
if (sponsorTimes.length > 0) {
|
if (sponsorTimes.length > 0) {
|
||||||
chrome.tabs.query({
|
messageHandler.query({
|
||||||
active: true,
|
active: true,
|
||||||
currentWindow: true
|
currentWindow: true
|
||||||
}, function(tabs) {
|
}, function(tabs) {
|
||||||
chrome.tabs.sendMessage(tabs[0].id, {
|
messageHandler.sendMessage(tabs[0].id, {
|
||||||
message: "changeStartSponsorButton",
|
message: "changeStartSponsorButton",
|
||||||
showStartSponsor: true,
|
showStartSponsor: true,
|
||||||
uploadButtonVisible: false
|
uploadButtonVisible: false
|
||||||
@@ -750,11 +770,11 @@ async function runThePopup() {
|
|||||||
sponsorTimes = [];
|
sponsorTimes = [];
|
||||||
|
|
||||||
SB.config.sponsorTimes.set(currentVideoID, sponsorTimes);
|
SB.config.sponsorTimes.set(currentVideoID, sponsorTimes);
|
||||||
chrome.tabs.query({
|
messageHandler.query({
|
||||||
active: true,
|
active: true,
|
||||||
currentWindow: true
|
currentWindow: true
|
||||||
}, tabs => {
|
}, tabs => {
|
||||||
chrome.tabs.sendMessage(
|
messageHandler.sendMessage(
|
||||||
tabs[0].id,
|
tabs[0].id,
|
||||||
{message: "sponsorDataChanged"}
|
{message: "sponsorDataChanged"}
|
||||||
);
|
);
|
||||||
@@ -770,8 +790,8 @@ async function runThePopup() {
|
|||||||
|
|
||||||
function submitTimes() {
|
function submitTimes() {
|
||||||
//make info message say loading
|
//make info message say loading
|
||||||
SB.submitTimesInfoMessage.innerText = chrome.i18n.getMessage("Loading");
|
PageElements.submitTimesInfoMessage.innerText = chrome.i18n.getMessage("Loading");
|
||||||
SB.submitTimesInfoMessageContainer.style.display = "unset";
|
PageElements.submitTimesInfoMessageContainer.style.display = "unset";
|
||||||
|
|
||||||
if (sponsorTimes.length > 0) {
|
if (sponsorTimes.length > 0) {
|
||||||
chrome.runtime.sendMessage({
|
chrome.runtime.sendMessage({
|
||||||
@@ -781,14 +801,14 @@ async function runThePopup() {
|
|||||||
if (response != undefined) {
|
if (response != undefined) {
|
||||||
if (response.statusCode == 200) {
|
if (response.statusCode == 200) {
|
||||||
//hide loading message
|
//hide loading message
|
||||||
SB.submitTimesInfoMessageContainer.style.display = "none";
|
PageElements.submitTimesInfoMessageContainer.style.display = "none";
|
||||||
|
|
||||||
clearTimes();
|
clearTimes();
|
||||||
} else {
|
} else {
|
||||||
document.getElementById("submitTimesInfoMessage").innerText = getErrorMessage(response.statusCode);
|
document.getElementById("submitTimesInfoMessage").innerText = utils.getErrorMessage(response.statusCode);
|
||||||
document.getElementById("submitTimesInfoMessageContainer").style.display = "unset";
|
document.getElementById("submitTimesInfoMessageContainer").style.display = "unset";
|
||||||
|
|
||||||
SB.submitTimesInfoMessageContainer.style.display = "unset";
|
PageElements.submitTimesInfoMessageContainer.style.display = "unset";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -798,14 +818,14 @@ async function runThePopup() {
|
|||||||
function showNoticeAgain() {
|
function showNoticeAgain() {
|
||||||
SB.config.dontShowNotice = false;
|
SB.config.dontShowNotice = false;
|
||||||
|
|
||||||
SB.showNoticeAgain.style.display = "none";
|
PageElements.showNoticeAgain.style.display = "none";
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateStartTimeChosen() {
|
function updateStartTimeChosen() {
|
||||||
//update startTimeChosen letiable
|
//update startTimeChosen letiable
|
||||||
if (!startTimeChosen) {
|
if (!startTimeChosen) {
|
||||||
startTimeChosen = true;
|
startTimeChosen = true;
|
||||||
SB.sponsorStart.innerHTML = chrome.i18n.getMessage("sponsorEnd");
|
PageElements.sponsorStart.innerHTML = chrome.i18n.getMessage("sponsorEnd");
|
||||||
} else {
|
} else {
|
||||||
resetStartTimeChosen();
|
resetStartTimeChosen();
|
||||||
}
|
}
|
||||||
@@ -814,7 +834,7 @@ async function runThePopup() {
|
|||||||
//set it to false
|
//set it to false
|
||||||
function resetStartTimeChosen() {
|
function resetStartTimeChosen() {
|
||||||
startTimeChosen = false;
|
startTimeChosen = false;
|
||||||
SB.sponsorStart.innerHTML = chrome.i18n.getMessage("sponsorStart");
|
PageElements.sponsorStart.innerHTML = chrome.i18n.getMessage("sponsorStart");
|
||||||
}
|
}
|
||||||
|
|
||||||
//hides and shows the submit times button when needed
|
//hides and shows the submit times button when needed
|
||||||
@@ -836,51 +856,51 @@ async function runThePopup() {
|
|||||||
|
|
||||||
//make the options username setting option visible
|
//make the options username setting option visible
|
||||||
function setUsernameButton() {
|
function setUsernameButton() {
|
||||||
//get username from the server
|
//get username from the server
|
||||||
sendRequestToServer("GET", "/api/getUsername?userID=" + SB.config.userID, function (xmlhttp, error) {
|
utils.sendRequestToServer("GET", "/api/getUsername?userID=" + SB.config.userID, function (xmlhttp, error) {
|
||||||
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
|
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
|
||||||
SB.usernameInput.value = JSON.parse(xmlhttp.responseText).userName;
|
PageElements.usernameInput.value = JSON.parse(xmlhttp.responseText).userName;
|
||||||
|
|
||||||
SB.submitUsername.style.display = "unset";
|
PageElements.submitUsername.style.display = "unset";
|
||||||
SB.usernameInput.style.display = "unset";
|
PageElements.usernameInput.style.display = "unset";
|
||||||
|
|
||||||
SB.setUsernameContainer.style.display = "none";
|
PageElements.setUsernameContainer.style.display = "none";
|
||||||
SB.setUsername.style.display = "unset";
|
PageElements.setUsername.style.display = "unset";
|
||||||
|
PageElements
|
||||||
|
PageElements.setUsernameStatusContainer.style.display = "none";
|
||||||
|
} else if (xmlhttp.readyState == 4) {
|
||||||
|
PageElements.setUsername.style.display = "unset";
|
||||||
|
PageElements.submitUsername.style.display = "none";
|
||||||
|
PageElements.usernameInput.style.display = "none";
|
||||||
|
|
||||||
SB.setUsernameStatusContainer.style.display = "none";
|
PageElements.setUsernameStatusContainer.style.display = "unset";
|
||||||
} else if (xmlhttp.readyState == 4) {
|
PageElements.setUsernameStatus.innerText = utils.getErrorMessage(xmlhttp.status);
|
||||||
SB.setUsername.style.display = "unset";
|
}
|
||||||
SB.submitUsername.style.display = "none";
|
});
|
||||||
SB.usernameInput.style.display = "none";
|
|
||||||
|
|
||||||
SB.setUsernameStatusContainer.style.display = "unset";
|
|
||||||
SB.setUsernameStatus.innerText = getErrorMessage(xmlhttp.status);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//submit the new username
|
//submit the new username
|
||||||
function submitUsername() {
|
function submitUsername() {
|
||||||
//add loading indicator
|
//add loading indicator
|
||||||
SB.setUsernameStatusContainer.style.display = "unset";
|
PageElements.setUsernameStatusContainer.style.display = "unset";
|
||||||
SB.setUsernameStatus.innerText = "Loading...";
|
PageElements.setUsernameStatus.innerText = "Loading...";
|
||||||
|
|
||||||
//get the userID
|
//get the userID
|
||||||
sendRequestToServer("POST", "/api/setUsername?userID=" + SB.config.userID + "&username=" + SB.usernameInput.value, function (xmlhttp, error) {
|
utils.sendRequestToServer("POST", "/api/setUsername?userID=" + SB.config.userID + "&username=" + PageElements.usernameInput.value, function (xmlhttp, error) {
|
||||||
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
|
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
|
||||||
//submitted
|
//submitted
|
||||||
SB.submitUsername.style.display = "none";
|
PageElements.submitUsername.style.display = "none";
|
||||||
SB.usernameInput.style.display = "none";
|
PageElements.usernameInput.style.display = "none";
|
||||||
|
|
||||||
SB.setUsernameStatus.innerText = chrome.i18n.getMessage("success");
|
PageElements.setUsernameStatus.innerText = chrome.i18n.getMessage("success");
|
||||||
} else if (xmlhttp.readyState == 4) {
|
} else if (xmlhttp.readyState == 4) {
|
||||||
SB.setUsernameStatus.innerText = getErrorMessageI(xmlhttp.status);
|
PageElements.setUsernameStatus.innerText = utils.getErrorMessage(xmlhttp.status);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
SB.setUsernameContainer.style.display = "none";
|
PageElements.setUsernameContainer.style.display = "none";
|
||||||
SB.setUsername.style.display = "unset";
|
PageElements.setUsername.style.display = "unset";
|
||||||
}
|
}
|
||||||
|
|
||||||
//this is not a YouTube video page
|
//this is not a YouTube video page
|
||||||
@@ -890,7 +910,7 @@ async function runThePopup() {
|
|||||||
|
|
||||||
function reportAnIssue() {
|
function reportAnIssue() {
|
||||||
document.getElementById("issueReporterContainer").style.display = "unset";
|
document.getElementById("issueReporterContainer").style.display = "unset";
|
||||||
SB.reportAnIssue.style.display = "none";
|
PageElements.reportAnIssue.style.display = "none";
|
||||||
}
|
}
|
||||||
|
|
||||||
function addVoteMessage(message, UUID) {
|
function addVoteMessage(message, UUID) {
|
||||||
@@ -927,7 +947,7 @@ async function runThePopup() {
|
|||||||
//failure: duplicate vote
|
//failure: duplicate vote
|
||||||
addVoteMessage(chrome.i18n.getMessage("voteFail"), UUID)
|
addVoteMessage(chrome.i18n.getMessage("voteFail"), UUID)
|
||||||
} else if (response.successType == -1) {
|
} else if (response.successType == -1) {
|
||||||
addVoteMessage(getErrorMessage(response.statusCode), UUID)
|
addVoteMessage(utils.getErrorMessage(response.statusCode), UUID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -935,14 +955,15 @@ async function runThePopup() {
|
|||||||
|
|
||||||
function hideDiscordButton() {
|
function hideDiscordButton() {
|
||||||
SB.config.hideDiscordLink = true;
|
SB.config.hideDiscordLink = true;
|
||||||
SB.discordButtonContainer.style.display = "none";
|
PageElements.discordButtonContainer.style.display = "none";
|
||||||
}
|
}
|
||||||
|
|
||||||
//converts time in seconds to minutes:seconds
|
//converts time in seconds to minutes:seconds
|
||||||
function getFormattedTime(seconds) {
|
function getFormattedTime(seconds) {
|
||||||
let minutes = Math.floor(seconds / 60);
|
let minutes = Math.floor(seconds / 60);
|
||||||
let secondsDisplay = Math.round(seconds - minutes * 60);
|
let secondsDisplayNumber = Math.round(seconds - minutes * 60);
|
||||||
if (secondsDisplay < 10) {
|
let secondsDisplay = String(secondsDisplayNumber);
|
||||||
|
if (secondsDisplayNumber < 10) {
|
||||||
//add a zero
|
//add a zero
|
||||||
secondsDisplay = "0" + secondsDisplay;
|
secondsDisplay = "0" + secondsDisplay;
|
||||||
}
|
}
|
||||||
@@ -954,11 +975,11 @@ async function runThePopup() {
|
|||||||
|
|
||||||
function whitelistChannel() {
|
function whitelistChannel() {
|
||||||
//get the channel url
|
//get the channel url
|
||||||
chrome.tabs.query({
|
messageHandler.query({
|
||||||
active: true,
|
active: true,
|
||||||
currentWindow: true
|
currentWindow: true
|
||||||
}, tabs => {
|
}, tabs => {
|
||||||
chrome.tabs.sendMessage(
|
messageHandler.sendMessage(
|
||||||
tabs[0].id,
|
tabs[0].id,
|
||||||
{message: 'getChannelURL'},
|
{message: 'getChannelURL'},
|
||||||
function(response) {
|
function(response) {
|
||||||
@@ -972,21 +993,21 @@ async function runThePopup() {
|
|||||||
whitelistedChannels.push(response.channelURL);
|
whitelistedChannels.push(response.channelURL);
|
||||||
|
|
||||||
//change button
|
//change button
|
||||||
SB.whitelistChannel.style.display = "none";
|
PageElements.whitelistChannel.style.display = "none";
|
||||||
SB.unwhitelistChannel.style.display = "unset";
|
PageElements.unwhitelistChannel.style.display = "unset";
|
||||||
|
|
||||||
SB.downloadedSponsorMessageTimes.innerText = chrome.i18n.getMessage("channelWhitelisted");
|
PageElements.downloadedSponsorMessageTimes.innerText = chrome.i18n.getMessage("channelWhitelisted");
|
||||||
SB.downloadedSponsorMessageTimes.style.fontWeight = "bold";
|
PageElements.downloadedSponsorMessageTimes.style.fontWeight = "bold";
|
||||||
|
|
||||||
//save this
|
//save this
|
||||||
SB.config.whitelistedChannels = whitelistedChannels;
|
SB.config.whitelistedChannels = whitelistedChannels;
|
||||||
|
|
||||||
//send a message to the client
|
//send a message to the client
|
||||||
chrome.tabs.query({
|
messageHandler.query({
|
||||||
active: true,
|
active: true,
|
||||||
currentWindow: true
|
currentWindow: true
|
||||||
}, tabs => {
|
}, tabs => {
|
||||||
chrome.tabs.sendMessage(
|
messageHandler.sendMessage(
|
||||||
tabs[0].id, {
|
tabs[0].id, {
|
||||||
message: 'whitelistChange',
|
message: 'whitelistChange',
|
||||||
value: true
|
value: true
|
||||||
@@ -1000,11 +1021,11 @@ async function runThePopup() {
|
|||||||
|
|
||||||
function unwhitelistChannel() {
|
function unwhitelistChannel() {
|
||||||
//get the channel url
|
//get the channel url
|
||||||
chrome.tabs.query({
|
messageHandler.query({
|
||||||
active: true,
|
active: true,
|
||||||
currentWindow: true
|
currentWindow: true
|
||||||
}, tabs => {
|
}, tabs => {
|
||||||
chrome.tabs.sendMessage(
|
messageHandler.sendMessage(
|
||||||
tabs[0].id,
|
tabs[0].id,
|
||||||
{message: 'getChannelURL'},
|
{message: 'getChannelURL'},
|
||||||
function(response) {
|
function(response) {
|
||||||
@@ -1019,21 +1040,21 @@ async function runThePopup() {
|
|||||||
whitelistedChannels.splice(index, 1);
|
whitelistedChannels.splice(index, 1);
|
||||||
|
|
||||||
//change button
|
//change button
|
||||||
SB.whitelistChannel.style.display = "unset";
|
PageElements.whitelistChannel.style.display = "unset";
|
||||||
SB.unwhitelistChannel.style.display = "none";
|
PageElements.unwhitelistChannel.style.display = "none";
|
||||||
|
|
||||||
SB.downloadedSponsorMessageTimes.innerText = "";
|
PageElements.downloadedSponsorMessageTimes.innerText = "";
|
||||||
SB.downloadedSponsorMessageTimes.style.fontWeight = "unset";
|
PageElements.downloadedSponsorMessageTimes.style.fontWeight = "unset";
|
||||||
|
|
||||||
//save this
|
//save this
|
||||||
SB.config.whitelistedChannels = whitelistedChannels;
|
SB.config.whitelistedChannels = whitelistedChannels;
|
||||||
|
|
||||||
//send a message to the client
|
//send a message to the client
|
||||||
chrome.tabs.query({
|
messageHandler.query({
|
||||||
active: true,
|
active: true,
|
||||||
currentWindow: true
|
currentWindow: true
|
||||||
}, tabs => {
|
}, tabs => {
|
||||||
chrome.tabs.sendMessage(
|
messageHandler.sendMessage(
|
||||||
tabs[0].id, {
|
tabs[0].id, {
|
||||||
message: 'whitelistChange',
|
message: 'whitelistChange',
|
||||||
value: false
|
value: false
|
||||||
@@ -1051,12 +1072,12 @@ async function runThePopup() {
|
|||||||
function toggleSkipping(disabled) {
|
function toggleSkipping(disabled) {
|
||||||
SB.config.disableSkipping = disabled;
|
SB.config.disableSkipping = disabled;
|
||||||
|
|
||||||
let hiddenButton = SB.disableSkipping;
|
let hiddenButton = PageElements.disableSkipping;
|
||||||
let shownButton = SB.enableSkipping;
|
let shownButton = PageElements.enableSkipping;
|
||||||
|
|
||||||
if (!disabled) {
|
if (!disabled) {
|
||||||
hiddenButton = SB.enableSkipping;
|
hiddenButton = PageElements.enableSkipping;
|
||||||
shownButton = SB.disableSkipping;
|
shownButton = PageElements.disableSkipping;
|
||||||
}
|
}
|
||||||
|
|
||||||
shownButton.style.display = "unset";
|
shownButton.style.display = "unset";
|
||||||
@@ -1072,34 +1093,16 @@ async function runThePopup() {
|
|||||||
|
|
||||||
//converts time in seconds to seconds past the last minute
|
//converts time in seconds to seconds past the last minute
|
||||||
function getTimeInFormattedSeconds(seconds) {
|
function getTimeInFormattedSeconds(seconds) {
|
||||||
let secondsFormatted = (seconds % 60).toFixed(3);
|
let minutes = seconds % 60;
|
||||||
|
let secondsFormatted = minutes.toFixed(3);
|
||||||
|
|
||||||
if (secondsFormatted < 10) {
|
if (minutes < 10) {
|
||||||
secondsFormatted = "0" + secondsFormatted;
|
secondsFormatted = "0" + secondsFormatted;
|
||||||
}
|
}
|
||||||
|
|
||||||
return secondsFormatted;
|
return secondsFormatted;
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendRequestToServer(type, address, callback) {
|
|
||||||
let xmlhttp = new XMLHttpRequest();
|
|
||||||
|
|
||||||
xmlhttp.open(type, serverAddress + address, true);
|
|
||||||
|
|
||||||
if (callback != undefined) {
|
|
||||||
xmlhttp.onreadystatechange = function () {
|
|
||||||
callback(xmlhttp, false);
|
|
||||||
};
|
|
||||||
|
|
||||||
xmlhttp.onerror = function(ev) {
|
|
||||||
callback(xmlhttp, true);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
//submit this request
|
|
||||||
xmlhttp.send();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts time in hours to 5h 25.1
|
* Converts time in hours to 5h 25.1
|
||||||
* If less than 1 hour, just returns minutes
|
* If less than 1 hour, just returns minutes
|
||||||
@@ -1117,7 +1120,11 @@ async function runThePopup() {
|
|||||||
|
|
||||||
if (chrome.tabs != undefined) {
|
if (chrome.tabs != undefined) {
|
||||||
//add the width restriction (because Firefox)
|
//add the width restriction (because Firefox)
|
||||||
document.getElementById("sponorBlockStyleSheet").sheet.insertRule('.popupBody { width: 325 }', 0);
|
let link = <HTMLLinkElement> document.getElementById("sponsorBlockStyleSheet");
|
||||||
|
(<CSSStyleSheet> link.sheet).insertRule('.popupBody { width: 325 }', 0);
|
||||||
|
|
||||||
//this means it is actually opened in the popup
|
//this means it is actually opened in the popup
|
||||||
runThePopup();
|
runThePopup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default runThePopup;
|
||||||
7
src/types.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
interface videoDurationResponse {
|
||||||
|
duration: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
videoDurationResponse
|
||||||
|
};
|
||||||
266
src/utils.ts
Normal file
@@ -0,0 +1,266 @@
|
|||||||
|
import * as CompileConfig from "../config.json";
|
||||||
|
import SB from "./SB";
|
||||||
|
|
||||||
|
class Utils {
|
||||||
|
|
||||||
|
// Contains functions needed from the background script
|
||||||
|
backgroundScriptContainer: any = null;
|
||||||
|
|
||||||
|
constructor(backgroundScriptContainer?: any) {
|
||||||
|
this.backgroundScriptContainer = backgroundScriptContainer;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function that can be used to wait for a condition before returning
|
||||||
|
async wait(condition, timeout = 5000, check = 100) {
|
||||||
|
return await new Promise((resolve, reject) => {
|
||||||
|
setTimeout(() => reject("TIMEOUT"), timeout);
|
||||||
|
|
||||||
|
let intervalCheck = () => {
|
||||||
|
let result = condition();
|
||||||
|
if (result !== false) {
|
||||||
|
resolve(result);
|
||||||
|
clearInterval(interval);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
let interval = setInterval(intervalCheck, check);
|
||||||
|
|
||||||
|
//run the check once first, this speeds it up a lot
|
||||||
|
intervalCheck();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asks for the optional permissions required for all extra sites.
|
||||||
|
* It also starts the content script registrations.
|
||||||
|
*
|
||||||
|
* For now, it is just SB.config.invidiousInstances.
|
||||||
|
*
|
||||||
|
* @param {CallableFunction} callback
|
||||||
|
*/
|
||||||
|
setupExtraSitePermissions(callback) {
|
||||||
|
// Request permission
|
||||||
|
let permissions = ["declarativeContent"];
|
||||||
|
if (this.isFirefox()) permissions = [];
|
||||||
|
|
||||||
|
let self = this;
|
||||||
|
|
||||||
|
chrome.permissions.request({
|
||||||
|
origins: this.getInvidiousInstancesRegex(),
|
||||||
|
permissions: permissions
|
||||||
|
}, async function (granted) {
|
||||||
|
if (granted) {
|
||||||
|
self.setupExtraSiteContentScripts();
|
||||||
|
} else {
|
||||||
|
self.removeExtraSiteRegistration();
|
||||||
|
}
|
||||||
|
|
||||||
|
callback(granted);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers the content scripts for the extra sites.
|
||||||
|
* Will use a different method depending on the browser.
|
||||||
|
* This is called by setupExtraSitePermissions().
|
||||||
|
*
|
||||||
|
* For now, it is just SB.config.invidiousInstances.
|
||||||
|
*/
|
||||||
|
setupExtraSiteContentScripts() {
|
||||||
|
let js = [
|
||||||
|
"./js/vendor.js",
|
||||||
|
"./js/content.js"
|
||||||
|
];
|
||||||
|
let css = [
|
||||||
|
"content.css",
|
||||||
|
"./libs/Source+Sans+Pro.css",
|
||||||
|
"popup.css"
|
||||||
|
];
|
||||||
|
|
||||||
|
let self = this;
|
||||||
|
|
||||||
|
if (this.isFirefox()) {
|
||||||
|
let firefoxJS = [];
|
||||||
|
for (const file of js) {
|
||||||
|
firefoxJS.push({file});
|
||||||
|
}
|
||||||
|
let firefoxCSS = [];
|
||||||
|
for (const file of css) {
|
||||||
|
firefoxCSS.push({file});
|
||||||
|
}
|
||||||
|
|
||||||
|
let registration = {
|
||||||
|
message: "registerContentScript",
|
||||||
|
id: "invidious",
|
||||||
|
allFrames: true,
|
||||||
|
js: firefoxJS,
|
||||||
|
css: firefoxCSS,
|
||||||
|
matches: this.getInvidiousInstancesRegex()
|
||||||
|
};
|
||||||
|
|
||||||
|
if (this.backgroundScriptContainer) {
|
||||||
|
this.backgroundScriptContainer.registerFirefoxContentScript(registration);
|
||||||
|
} else {
|
||||||
|
chrome.runtime.sendMessage(registration);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
chrome.declarativeContent.onPageChanged.removeRules(["invidious"], function() {
|
||||||
|
let conditions = [];
|
||||||
|
for (const regex of self.getInvidiousInstancesRegex()) {
|
||||||
|
conditions.push(new chrome.declarativeContent.PageStateMatcher({
|
||||||
|
pageUrl: { urlMatches: regex }
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add page rule
|
||||||
|
let rule = {
|
||||||
|
id: "invidious",
|
||||||
|
conditions,
|
||||||
|
// This API is experimental and not visible by the TypeScript compiler
|
||||||
|
actions: [new (<any> chrome.declarativeContent).RequestContentScript({
|
||||||
|
allFrames: true,
|
||||||
|
js,
|
||||||
|
css
|
||||||
|
})]
|
||||||
|
};
|
||||||
|
|
||||||
|
chrome.declarativeContent.onPageChanged.addRules([rule]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the permission and content script registration.
|
||||||
|
*/
|
||||||
|
removeExtraSiteRegistration() {
|
||||||
|
if (this.isFirefox()) {
|
||||||
|
let id = "invidious";
|
||||||
|
|
||||||
|
if (this.backgroundScriptContainer) {
|
||||||
|
this.backgroundScriptContainer.unregisterFirefoxContentScript(id);
|
||||||
|
} else {
|
||||||
|
chrome.runtime.sendMessage({
|
||||||
|
message: "unregisterContentScript",
|
||||||
|
id: id
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
chrome.declarativeContent.onPageChanged.removeRules(["invidious"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
chrome.permissions.remove({
|
||||||
|
origins: this.getInvidiousInstancesRegex()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
localizeHtmlPage() {
|
||||||
|
//Localize by replacing __MSG_***__ meta tags
|
||||||
|
var objects = document.getElementsByClassName("sponsorBlockPageBody")[0].children;
|
||||||
|
for (var j = 0; j < objects.length; j++) {
|
||||||
|
var obj = objects[j];
|
||||||
|
|
||||||
|
let localizedMessage = this.getLocalizedMessage(obj.innerHTML.toString());
|
||||||
|
if (localizedMessage) obj.innerHTML = localizedMessage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getLocalizedMessage(text) {
|
||||||
|
var valNewH = text.replace(/__MSG_(\w+)__/g, function(match, v1) {
|
||||||
|
return v1 ? chrome.i18n.getMessage(v1) : "";
|
||||||
|
});
|
||||||
|
|
||||||
|
if(valNewH != text) {
|
||||||
|
return valNewH;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {String[]} Invidious Instances in regex form
|
||||||
|
*/
|
||||||
|
getInvidiousInstancesRegex() {
|
||||||
|
var invidiousInstancesRegex = [];
|
||||||
|
for (const url of SB.config.invidiousInstances) {
|
||||||
|
invidiousInstancesRegex.push("https://*." + url + "/*");
|
||||||
|
invidiousInstancesRegex.push("http://*." + url + "/*");
|
||||||
|
}
|
||||||
|
|
||||||
|
return invidiousInstancesRegex;
|
||||||
|
}
|
||||||
|
|
||||||
|
generateUserID(length = 36) {
|
||||||
|
let charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||||
|
let result = "";
|
||||||
|
if (window.crypto && window.crypto.getRandomValues) {
|
||||||
|
let values = new Uint32Array(length);
|
||||||
|
window.crypto.getRandomValues(values);
|
||||||
|
for (let i = 0; i < length; i++) {
|
||||||
|
result += charset[values[i] % charset.length];
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
} else {
|
||||||
|
for (let i = 0; i < length; i++) {
|
||||||
|
result += charset[Math.floor(Math.random() * charset.length)];
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the error message in a nice string
|
||||||
|
*
|
||||||
|
* @param {int} statusCode
|
||||||
|
* @returns {string} errorMessage
|
||||||
|
*/
|
||||||
|
getErrorMessage(statusCode) {
|
||||||
|
let errorMessage = "";
|
||||||
|
|
||||||
|
if([400, 429, 409, 502, 0].includes(statusCode)) {
|
||||||
|
//treat them the same
|
||||||
|
if (statusCode == 503) statusCode = 502;
|
||||||
|
|
||||||
|
errorMessage = chrome.i18n.getMessage(statusCode + "") + " " + chrome.i18n.getMessage("errorCode") + statusCode
|
||||||
|
+ "\n\n" + chrome.i18n.getMessage("statusReminder");
|
||||||
|
} else {
|
||||||
|
errorMessage = chrome.i18n.getMessage("connectionError") + statusCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
return errorMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a request to the SponsorBlock server with address added as a query
|
||||||
|
*
|
||||||
|
* @param type The request type. "GET", "POST", etc.
|
||||||
|
* @param address The address to add to the SponsorBlock server address
|
||||||
|
* @param callback
|
||||||
|
*/
|
||||||
|
sendRequestToServer(type: string, address: string, callback?: (xmlhttp: XMLHttpRequest, err: boolean) => any) {
|
||||||
|
let xmlhttp = new XMLHttpRequest();
|
||||||
|
|
||||||
|
xmlhttp.open(type, CompileConfig.serverAddress + address, true);
|
||||||
|
|
||||||
|
if (callback != undefined) {
|
||||||
|
xmlhttp.onreadystatechange = function () {
|
||||||
|
callback(xmlhttp, false);
|
||||||
|
};
|
||||||
|
|
||||||
|
xmlhttp.onerror = function(ev) {
|
||||||
|
callback(xmlhttp, true);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
//submit this request
|
||||||
|
xmlhttp.send();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this Firefox (web-extensions)
|
||||||
|
*/
|
||||||
|
isFirefox() {
|
||||||
|
return typeof(browser) !== "undefined";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Utils;
|
||||||
12
tsconfig.json
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"module": "commonjs",
|
||||||
|
"target": "es6",
|
||||||
|
"noImplicitAny": false,
|
||||||
|
"sourceMap": false,
|
||||||
|
"outDir": "dist/js",
|
||||||
|
"noEmitOnError": true,
|
||||||
|
"typeRoots": [ "node_modules/@types" ],
|
||||||
|
"resolveJsonModule": true
|
||||||
|
}
|
||||||
|
}
|
||||||
271
utils.js
@@ -1,271 +0,0 @@
|
|||||||
var isBackgroundScript = false;
|
|
||||||
var onInvidious = false;
|
|
||||||
|
|
||||||
// Function that can be used to wait for a condition before returning
|
|
||||||
async function wait(condition, timeout = 5000, check = 100) {
|
|
||||||
return await new Promise((resolve, reject) => {
|
|
||||||
setTimeout(() => reject("TIMEOUT"), timeout);
|
|
||||||
|
|
||||||
let intervalCheck = () => {
|
|
||||||
let result = condition();
|
|
||||||
if (result !== false) {
|
|
||||||
resolve(result);
|
|
||||||
clearInterval(interval);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
let interval = setInterval(intervalCheck, check);
|
|
||||||
|
|
||||||
//run the check once first, this speeds it up a lot
|
|
||||||
intervalCheck();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function getYouTubeVideoID(url) {
|
|
||||||
// For YouTube TV support
|
|
||||||
if(url.startsWith("https://www.youtube.com/tv#/")) url = url.replace("#", "");
|
|
||||||
|
|
||||||
//Attempt to parse url
|
|
||||||
let urlObject = null;
|
|
||||||
try {
|
|
||||||
urlObject = new URL(url);
|
|
||||||
} catch (e) {
|
|
||||||
console.error("[SB] Unable to parse URL: " + url);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Check if valid hostname
|
|
||||||
if (SB.config && SB.config.invidiousInstances.includes(urlObject.host)) {
|
|
||||||
onInvidious = true;
|
|
||||||
} else if (!["www.youtube.com", "www.youtube-nocookie.com"].includes(urlObject.host)) {
|
|
||||||
if (!SB.config) {
|
|
||||||
// Call this later, in case this is an Invidious tab
|
|
||||||
wait(() => SB.config !== undefined).then(() => videoIDChange(getYouTubeVideoID(url)));
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
//Get ID from searchParam
|
|
||||||
if (urlObject.searchParams.has("v") && ["/watch", "/watch/"].includes(urlObject.pathname) || urlObject.pathname.startsWith("/tv/watch")) {
|
|
||||||
id = urlObject.searchParams.get("v");
|
|
||||||
return id.length == 11 ? id : false;
|
|
||||||
} else if (urlObject.pathname.startsWith("/embed/")) {
|
|
||||||
try {
|
|
||||||
return urlObject.pathname.substr(7, 11);
|
|
||||||
} catch (e) {
|
|
||||||
console.error("[SB] Video ID not valid for " + url);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Asks for the optional permissions required for all extra sites.
|
|
||||||
* It also starts the content script registrations.
|
|
||||||
*
|
|
||||||
* For now, it is just SB.config.invidiousInstances.
|
|
||||||
*
|
|
||||||
* @param {CallableFunction} callback
|
|
||||||
*/
|
|
||||||
function setupExtraSitePermissions(callback) {
|
|
||||||
// Request permission
|
|
||||||
let permissions = ["declarativeContent"];
|
|
||||||
if (isFirefox()) permissions = [];
|
|
||||||
|
|
||||||
chrome.permissions.request({
|
|
||||||
origins: getInvidiousInstancesRegex(),
|
|
||||||
permissions: permissions
|
|
||||||
}, async function (granted) {
|
|
||||||
if (granted) {
|
|
||||||
setupExtraSiteContentScripts();
|
|
||||||
} else {
|
|
||||||
removeExtraSiteRegistration();
|
|
||||||
}
|
|
||||||
|
|
||||||
callback(granted);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Registers the content scripts for the extra sites.
|
|
||||||
* Will use a different method depending on the browser.
|
|
||||||
* This is called by setupExtraSitePermissions().
|
|
||||||
*
|
|
||||||
* For now, it is just SB.config.invidiousInstances.
|
|
||||||
*/
|
|
||||||
function setupExtraSiteContentScripts() {
|
|
||||||
let js = [
|
|
||||||
"config.js",
|
|
||||||
"SB.js",
|
|
||||||
"utils/previewBar.js",
|
|
||||||
"utils/skipNotice.js",
|
|
||||||
"utils.js",
|
|
||||||
"content.js",
|
|
||||||
"popup.js"
|
|
||||||
];
|
|
||||||
let css = [
|
|
||||||
"content.css",
|
|
||||||
"./libs/Source+Sans+Pro.css",
|
|
||||||
"popup.css"
|
|
||||||
];
|
|
||||||
|
|
||||||
if (isFirefox()) {
|
|
||||||
let firefoxJS = [];
|
|
||||||
for (const file of js) {
|
|
||||||
firefoxJS.push({file});
|
|
||||||
}
|
|
||||||
let firefoxCSS = [];
|
|
||||||
for (const file of css) {
|
|
||||||
firefoxCSS.push({file});
|
|
||||||
}
|
|
||||||
|
|
||||||
let registration = {
|
|
||||||
message: "registerContentScript",
|
|
||||||
id: "invidious",
|
|
||||||
allFrames: true,
|
|
||||||
js: firefoxJS,
|
|
||||||
css: firefoxCSS,
|
|
||||||
matches: getInvidiousInstancesRegex()
|
|
||||||
};
|
|
||||||
|
|
||||||
if (isBackgroundScript) {
|
|
||||||
registerFirefoxContentScript(registration);
|
|
||||||
} else {
|
|
||||||
chrome.runtime.sendMessage(registration);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
chrome.declarativeContent.onPageChanged.removeRules(["invidious"], function() {
|
|
||||||
let conditions = [];
|
|
||||||
for (const regex of getInvidiousInstancesRegex()) {
|
|
||||||
conditions.push(new chrome.declarativeContent.PageStateMatcher({
|
|
||||||
pageUrl: { urlMatches: regex }
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add page rule
|
|
||||||
let rule = {
|
|
||||||
id: "invidious",
|
|
||||||
conditions,
|
|
||||||
actions: [new chrome.declarativeContent.RequestContentScript({
|
|
||||||
allFrames: true,
|
|
||||||
js,
|
|
||||||
css
|
|
||||||
})]
|
|
||||||
};
|
|
||||||
|
|
||||||
chrome.declarativeContent.onPageChanged.addRules([rule]);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes the permission and content script registration.
|
|
||||||
*/
|
|
||||||
function removeExtraSiteRegistration() {
|
|
||||||
if (isFirefox()) {
|
|
||||||
let id = "invidious";
|
|
||||||
|
|
||||||
if (isBackgroundScript) {
|
|
||||||
if (contentScriptRegistrations[id]) {
|
|
||||||
contentScriptRegistrations[id].unregister();
|
|
||||||
delete contentScriptRegistrations[id];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
chrome.runtime.sendMessage({
|
|
||||||
message: "unregisterContentScript",
|
|
||||||
id: id
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
chrome.declarativeContent.onPageChanged.removeRules(["invidious"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
chrome.permissions.remove({
|
|
||||||
origins: getInvidiousInstancesRegex()
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function localizeHtmlPage() {
|
|
||||||
//Localize by replacing __MSG_***__ meta tags
|
|
||||||
var objects = document.getElementsByClassName("sponsorBlockPageBody")[0].children;
|
|
||||||
for (var j = 0; j < objects.length; j++) {
|
|
||||||
var obj = objects[j];
|
|
||||||
|
|
||||||
let localizedMessage = getLocalizedMessage(obj.innerHTML.toString());
|
|
||||||
if (localizedMessage) obj.innerHTML = localizedMessage;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getLocalizedMessage(text) {
|
|
||||||
var valNewH = text.replace(/__MSG_(\w+)__/g, function(match, v1) {
|
|
||||||
return v1 ? chrome.i18n.getMessage(v1) : "";
|
|
||||||
});
|
|
||||||
|
|
||||||
if(valNewH != text) {
|
|
||||||
return valNewH;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @returns {String[]} Invidious Instances in regex form
|
|
||||||
*/
|
|
||||||
function getInvidiousInstancesRegex() {
|
|
||||||
var invidiousInstancesRegex = [];
|
|
||||||
for (const url of SB.config.invidiousInstances) {
|
|
||||||
invidiousInstancesRegex.push("https://*." + url + "/*");
|
|
||||||
invidiousInstancesRegex.push("http://*." + url + "/*");
|
|
||||||
}
|
|
||||||
|
|
||||||
return invidiousInstancesRegex;
|
|
||||||
}
|
|
||||||
|
|
||||||
function generateUserID(length = 36) {
|
|
||||||
let charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
||||||
let result = "";
|
|
||||||
if (window.crypto && window.crypto.getRandomValues) {
|
|
||||||
values = new Uint32Array(length);
|
|
||||||
window.crypto.getRandomValues(values);
|
|
||||||
for (i = 0; i < length; i++) {
|
|
||||||
result += charset[values[i] % charset.length];
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
} else {
|
|
||||||
for (let i = 0; i < length; i++) {
|
|
||||||
result += charset[Math.floor(Math.random() * charset.length)];
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the error message in a nice string
|
|
||||||
*
|
|
||||||
* @param {int} statusCode
|
|
||||||
* @returns {string} errorMessage
|
|
||||||
*/
|
|
||||||
function getErrorMessage(statusCode) {
|
|
||||||
let errorMessage = "";
|
|
||||||
|
|
||||||
if([400, 429, 409, 502, 0].includes(statusCode)) {
|
|
||||||
//treat them the same
|
|
||||||
if (statusCode == 503) statusCode = 502;
|
|
||||||
|
|
||||||
errorMessage = chrome.i18n.getMessage(statusCode + "") + " " + chrome.i18n.getMessage("errorCode") + statusCode
|
|
||||||
+ "\n\n" + chrome.i18n.getMessage("statusReminder");
|
|
||||||
} else {
|
|
||||||
errorMessage = chrome.i18n.getMessage("connectionError") + statusCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
return errorMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Is this Firefox (web-extensions)
|
|
||||||
*/
|
|
||||||
function isFirefox() {
|
|
||||||
return typeof(browser) !== "undefined";
|
|
||||||
}
|
|
||||||
44
webpack/webpack.common.js
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
const webpack = require("webpack");
|
||||||
|
const path = require('path');
|
||||||
|
const CopyPlugin = require('copy-webpack-plugin');
|
||||||
|
const srcDir = '../src/';
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
entry: {
|
||||||
|
popup: path.join(__dirname, srcDir + 'popup.ts'),
|
||||||
|
background: path.join(__dirname, srcDir + 'background.ts'),
|
||||||
|
content: path.join(__dirname, srcDir + 'content.ts'),
|
||||||
|
options: path.join(__dirname, srcDir + 'options.ts')
|
||||||
|
},
|
||||||
|
output: {
|
||||||
|
path: path.join(__dirname, '../dist/js'),
|
||||||
|
filename: '[name].js'
|
||||||
|
},
|
||||||
|
optimization: {
|
||||||
|
splitChunks: {
|
||||||
|
name: 'vendor',
|
||||||
|
chunks: "initial"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /\.tsx?$/,
|
||||||
|
use: 'ts-loader',
|
||||||
|
exclude: /node_modules/
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
resolve: {
|
||||||
|
extensions: ['.ts', '.tsx', '.js']
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
// exclude locale files in moment
|
||||||
|
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
|
||||||
|
new CopyPlugin([
|
||||||
|
{ from: '.', to: '../' }
|
||||||
|
],
|
||||||
|
{context: 'public' }
|
||||||
|
),
|
||||||
|
]
|
||||||
|
};
|
||||||
7
webpack/webpack.dev.js
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
const merge = require('webpack-merge');
|
||||||
|
const common = require('./webpack.common.js');
|
||||||
|
|
||||||
|
module.exports = merge(common, {
|
||||||
|
devtool: 'inline-source-map',
|
||||||
|
mode: 'development'
|
||||||
|
});
|
||||||
6
webpack/webpack.prod.js
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
const merge = require('webpack-merge');
|
||||||
|
const common = require('./webpack.common.js');
|
||||||
|
|
||||||
|
module.exports = merge(common, {
|
||||||
|
mode: 'production'
|
||||||
|
});
|
||||||