Compare commits
94 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
da20709512 | ||
|
|
6ff461fa86 | ||
|
|
e205447968 | ||
|
|
ff6234bffe | ||
|
|
d93d475c1f | ||
|
|
0d0b919106 | ||
|
|
366fd43752 | ||
|
|
1119adffb7 | ||
|
|
9d14f02bec | ||
|
|
9fada00028 | ||
|
|
e0d2436372 | ||
|
|
e4c94aa5c5 | ||
|
|
e3e4121a21 | ||
|
|
a75ea50098 | ||
|
|
6b6e74b5a0 | ||
|
|
d6c5dbaff1 | ||
|
|
a66804064a | ||
|
|
919f9f56bd | ||
|
|
bd614e250b | ||
|
|
6275c2d62c | ||
|
|
feea7aa51d | ||
|
|
16263d463f | ||
|
|
6673272e14 | ||
|
|
6358ba2e11 | ||
|
|
2415784eee | ||
|
|
acb3c67629 | ||
|
|
622b2ea158 | ||
|
|
7a9af6cbcf | ||
|
|
51a389284d | ||
|
|
2ff70f1511 | ||
|
|
ff9badf2e9 | ||
|
|
aefc880486 | ||
|
|
e749456719 | ||
|
|
a2312a10be | ||
|
|
b0090a3334 | ||
|
|
7100831956 | ||
|
|
30c1b2d919 | ||
|
|
3ec6caee9d | ||
|
|
7f505a52ca | ||
|
|
84b8e59b39 | ||
|
|
808dfe42ce | ||
|
|
600365d998 | ||
|
|
569699cbc1 | ||
|
|
08cb324125 | ||
|
|
504f0b0ede | ||
|
|
00877fb087 | ||
|
|
d654d8934b | ||
|
|
97e202dbd0 | ||
|
|
64be41b008 | ||
|
|
b3684a8730 | ||
|
|
45f0d65f69 | ||
|
|
5436a1651e | ||
|
|
33fe63084b | ||
|
|
8f47513c98 | ||
|
|
7a17cc2b0a | ||
|
|
c7cb845d8a | ||
|
|
250c75a78f | ||
|
|
a86e55ac67 | ||
|
|
30f2f638fe | ||
|
|
725ab783e3 | ||
|
|
30e3222177 | ||
|
|
d9789c20d6 | ||
|
|
c8114e2d7e | ||
|
|
c7da0f0c65 | ||
|
|
0f561d4a5a | ||
|
|
55c7529731 | ||
|
|
30c6437160 | ||
|
|
e8ff6171eb | ||
|
|
b7764fc634 | ||
|
|
9913e99a6a | ||
|
|
c91c08a17f | ||
|
|
86bffeb96c | ||
|
|
c580a7dc7c | ||
|
|
22df50e3fe | ||
|
|
6d32b88490 | ||
|
|
95dee05e92 | ||
|
|
21220bf2d3 | ||
|
|
180260088d | ||
|
|
4c380aa1bf | ||
|
|
1040868ebb | ||
|
|
b7a35f0823 | ||
|
|
baefc59954 | ||
|
|
14121af900 | ||
|
|
52ec50a132 | ||
|
|
f162d6b8dd | ||
|
|
2d00cfffdf | ||
|
|
a7a4642920 | ||
|
|
91f0b65d06 | ||
|
|
4cc44258e8 | ||
|
|
4bb6cd0dcf | ||
|
|
b319729da8 | ||
|
|
888a03a708 | ||
|
|
e452e02bda | ||
|
|
01b61f6192 |
2
.gitignore
vendored
@@ -1,2 +1,2 @@
|
||||
content-config.js
|
||||
config.js
|
||||
ignored
|
||||
2
LICENSE
@@ -652,7 +652,7 @@ Also add information on how to contact you by electronic and paper mail.
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
SponsorBlock Copyright (C) 2019 Ajay Ramachandran and other SponsorBlock contributors
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
24
README.md
@@ -1,9 +1,15 @@
|
||||

|
||||
<br/><sub>Logo by [@munadikieh](https://github.com/munadikieh)</sub>
|
||||
|
||||
# SponsorBlocker
|
||||
# SponsorBlock
|
||||
|
||||
SponsorBlocker is an extension that will skip over sponsored segments of YouTube videos. SponsorBlocker is a crowdsourced browser extension that let's anyone submit the start and end time's of sponsored segments of YouTube videos. Once one person submits this information, everyone else with this extension will skip right over the sponsored segment.
|
||||
SponsorBlock is an extension that will skip over sponsored segments of YouTube videos. SponsorBlock is a crowdsourced browser extension that let's anyone submit the start and end time's of sponsored segments of YouTube videos. Once one person submits this information, everyone else with this extension will skip right over the sponsored segment.
|
||||
|
||||
# Available for Chrome and Firefox
|
||||
|
||||
Chrome: https://chrome.google.com/webstore/detail/ajjollijmimolcncegpgkbilohbhjnhi
|
||||
|
||||
Firefox: https://addons.mozilla.org/addon/sponsorblock/
|
||||
|
||||
# Server
|
||||
|
||||
@@ -19,14 +25,14 @@ Hopefully this project can be combined with projects like [this](https://github.
|
||||
|
||||
This project is partially based off of [this experimental extension](https://github.com/OfficialNoob/YTSponsorSkip). That extension has the basic video skipping functionality.
|
||||
|
||||
# Chrome extension
|
||||
# Build Yourself
|
||||
|
||||
It will be on the chrome webstore soon once I get some more UI features in, such as an icon. For now, you can load this project as an unpacked extension. Make sure to rename the `config.js.example` file to `config.js` before installing.
|
||||
|
||||
# Firefox extension
|
||||
|
||||
None at the moment
|
||||
You can load this project as an unpacked extension. Make sure to rename the `config.js.example` file to `config.js` before installing.
|
||||
|
||||
# Credit
|
||||
|
||||
Some i made by <a href="https://www.flaticon.com/authors/gregor-cresnar" title="Gregor Cresnar">Gregor Cresnar</a> from <a href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a> and are licensed by <a href="http://creativecommons.org/licenses/by/3.0/" title="Creative Commons BY 3.0" target="_blank">CC 3.0 BY</a>
|
||||
The awesome [Invidious API](https://github.com/omarroth/invidious/wiki/API) is used to grab the time the video was published.
|
||||
|
||||
Some icons made by <a href="https://www.flaticon.com/authors/gregor-cresnar" title="Gregor Cresnar">Gregor Cresnar</a> from <a href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a> and are licensed by <a href="http://creativecommons.org/licenses/by/3.0/" title="Creative Commons BY 3.0" target="_blank">CC 3.0 BY</a>
|
||||
|
||||
Some icons made by <a href="https://www.flaticon.com/authors/freepik" title="Freepik">Freepik</a> from <a href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a> is licensed by <a href="http://creativecommons.org/licenses/by/3.0/" title="Creative Commons BY 3.0" target="_blank">CC 3.0 BY</a>
|
||||
|
||||
166
background.js
@@ -3,35 +3,40 @@ var previousVideoID = null
|
||||
//the id of this user, randomly generated once per install
|
||||
var userID = null;
|
||||
|
||||
chrome.tabs.onUpdated.addListener( // On tab update
|
||||
function(tabId, changeInfo, tab) {
|
||||
if (changeInfo != undefined && changeInfo.url != undefined) {
|
||||
let id = getYouTubeVideoID(changeInfo.url);
|
||||
if (changeInfo.url && id) { // If URL changed and is youtube video message contentScript the video id
|
||||
videoIDChange(id);
|
||||
//when a new tab is highlighted
|
||||
chrome.tabs.onActivated.addListener(
|
||||
function(activeInfo) {
|
||||
chrome.tabs.get(activeInfo.tabId, function(tab) {
|
||||
let id = getYouTubeVideoID(tab.url);
|
||||
|
||||
chrome.tabs.sendMessage( tabId, {
|
||||
message: 'ytvideoid',
|
||||
id: id
|
||||
});
|
||||
//if this even is a YouTube tab
|
||||
if (id) {
|
||||
videoIDChange(id, activeInfo.tabId);
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
);
|
||||
|
||||
//when a tab changes URLs
|
||||
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
|
||||
if (changeInfo != undefined && changeInfo.url != undefined) {
|
||||
let id = getYouTubeVideoID(changeInfo.url);
|
||||
|
||||
//if URL changed and is youtube video message contentScript the video id
|
||||
if (changeInfo.url && id) {
|
||||
videoIDChange(id, tabId);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
chrome.runtime.onMessage.addListener(function (request, sender, callback) {
|
||||
if (request.message == "submitTimes") {
|
||||
submitTimes(request.videoID);
|
||||
submitTimes(request.videoID, callback);
|
||||
|
||||
callback({
|
||||
success: true
|
||||
});
|
||||
} else if (request.message == "ytvideoid") {
|
||||
if (previousVideoID != request.videoID) {
|
||||
videoIDChange(request.videoID);
|
||||
}
|
||||
//this allows the callback to be called later by the submitTimes function
|
||||
return true;
|
||||
} else if (request.message == "addSponsorTime") {
|
||||
addSponsorTime(request.time);
|
||||
addSponsorTime(request.time, request.videoID);
|
||||
} else if (request.message == "getSponsorTimes") {
|
||||
getSponsorTimes(request.videoID, function(sponsorTimes) {
|
||||
callback({
|
||||
@@ -42,7 +47,10 @@ chrome.runtime.onMessage.addListener(function (request, sender, callback) {
|
||||
//this allows the callback to be called later
|
||||
return true;
|
||||
} else if (request.message == "submitVote") {
|
||||
submitVote(request.type, request.UUID)
|
||||
submitVote(request.type, request.UUID, callback);
|
||||
|
||||
//this allows the callback to be called later
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -51,7 +59,7 @@ chrome.runtime.onMessage.addListener(function (request, sender, callback) {
|
||||
function getSponsorTimes(videoID, callback) {
|
||||
let sponsorTimes = [];
|
||||
let sponsorTimeKey = "sponsorTimes" + videoID;
|
||||
chrome.storage.local.get([sponsorTimeKey], function(result) {
|
||||
chrome.storage.sync.get([sponsorTimeKey], function(result) {
|
||||
let sponsorTimesStorage = result[sponsorTimeKey];
|
||||
if (sponsorTimesStorage != undefined && sponsorTimesStorage.length > 0) {
|
||||
sponsorTimes = sponsorTimesStorage;
|
||||
@@ -61,67 +69,104 @@ function getSponsorTimes(videoID, callback) {
|
||||
});
|
||||
}
|
||||
|
||||
function addSponsorTime(time) {
|
||||
getSponsorTimes(previousVideoID, function(sponsorTimes) {
|
||||
function addSponsorTime(time, videoID) {
|
||||
getSponsorTimes(videoID, function(sponsorTimes) {
|
||||
//add to sponsorTimes
|
||||
if (sponsorTimes.length > 0 && sponsorTimes[sponsorTimes.length - 1].length < 2) {
|
||||
//it is an end time
|
||||
sponsorTimes[sponsorTimes.length - 1][1] = parseInt(time);
|
||||
sponsorTimes[sponsorTimes.length - 1][1] = time;
|
||||
} else {
|
||||
//it is a start time
|
||||
let sponsorTimesIndex = sponsorTimes.length;
|
||||
sponsorTimes[sponsorTimesIndex] = [];
|
||||
|
||||
sponsorTimes[sponsorTimesIndex][0] = parseInt(time);
|
||||
sponsorTimes[sponsorTimesIndex][0] = time;
|
||||
}
|
||||
|
||||
//save this info
|
||||
let sponsorTimeKey = "sponsorTimes" + previousVideoID;
|
||||
chrome.storage.local.set({[sponsorTimeKey]: sponsorTimes});
|
||||
let sponsorTimeKey = "sponsorTimes" + videoID;
|
||||
chrome.storage.sync.set({[sponsorTimeKey]: sponsorTimes});
|
||||
});
|
||||
}
|
||||
|
||||
function submitVote(type, UUID) {
|
||||
let xmlhttp = new XMLHttpRequest();
|
||||
|
||||
function submitVote(type, UUID, callback) {
|
||||
getUserID(function(userID) {
|
||||
//publish this vote
|
||||
console.log(serverAddress + "/api/voteOnSponsorTime?UUID=" + UUID + "&userID=" + userID + "&type=" + type);
|
||||
xmlhttp.open('GET', serverAddress + "/api/voteOnSponsorTime?UUID=" + UUID + "&userID=" + userID + "&type=" + type, true);
|
||||
|
||||
//submit this vote
|
||||
xmlhttp.send();
|
||||
sendRequestToServer('GET', "/api/voteOnSponsorTime?UUID=" + UUID + "&userID=" + userID + "&type=" + type, function(xmlhttp, error) {
|
||||
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
|
||||
callback({
|
||||
successType: 1
|
||||
});
|
||||
} else if (xmlhttp.readyState == 4 && xmlhttp.status == 405) {
|
||||
//duplicate vote
|
||||
callback({
|
||||
successType: 0,
|
||||
statusCode: xmlhttp.status
|
||||
});
|
||||
} else if (error) {
|
||||
//error while connect
|
||||
callback({
|
||||
successType: -1,
|
||||
statusCode: xmlhttp.status
|
||||
});
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function submitTimes(videoID) {
|
||||
function submitTimes(videoID, callback) {
|
||||
//get the video times from storage
|
||||
let sponsorTimeKey = 'sponsorTimes' + videoID;
|
||||
chrome.storage.local.get([sponsorTimeKey], function(result) {
|
||||
chrome.storage.sync.get([sponsorTimeKey], function(result) {
|
||||
let sponsorTimes = result[sponsorTimeKey];
|
||||
|
||||
if (sponsorTimes != undefined && sponsorTimes.length > 0) {
|
||||
//submit these times
|
||||
for (let i = 0; i < sponsorTimes.length; i++) {
|
||||
let xmlhttp = new XMLHttpRequest();
|
||||
|
||||
let userIDStorage = getUserID(function(userIDStorage) {
|
||||
getUserID(function(userIDStorage) {
|
||||
//submit the sponsorTime
|
||||
xmlhttp.open('GET', serverAddress + "/api/postVideoSponsorTimes?videoID=" + videoID + "&startTime=" + sponsorTimes[i][0] + "&endTime=" + sponsorTimes[i][1]
|
||||
+ "&userID=" + userIDStorage, true);
|
||||
xmlhttp.send();
|
||||
sendRequestToServer('GET', "/api/postVideoSponsorTimes?videoID=" + videoID + "&startTime=" + sponsorTimes[i][0] + "&endTime=" + sponsorTimes[i][1]
|
||||
+ "&userID=" + userIDStorage, function(xmlhttp, error) {
|
||||
if (xmlhttp.readyState == 4 && !error) {
|
||||
callback({
|
||||
statusCode: xmlhttp.status
|
||||
});
|
||||
} else if (error) {
|
||||
callback({
|
||||
statusCode: -1
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
//add these to the storage log
|
||||
chrome.storage.sync.get(["sponsorTimesContributed"], function(result) {
|
||||
let currentContributionAmount = 0;
|
||||
if (result.sponsorTimesContributed != undefined) {
|
||||
//current contribution amount is known
|
||||
currentContributionAmount = result.sponsorTimesContributed;
|
||||
}
|
||||
|
||||
//save the amount contributed
|
||||
chrome.storage.sync.set({"sponsorTimesContributed": currentContributionAmount + sponsorTimes.length});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function videoIDChange(currentVideoID) {
|
||||
function videoIDChange(currentVideoID, tabId) {
|
||||
//send a message to the content script
|
||||
chrome.tabs.sendMessage(tabId, {
|
||||
message: 'ytvideoid',
|
||||
id: currentVideoID
|
||||
});
|
||||
|
||||
//warn them if they had unsubmitted times
|
||||
if (previousVideoID != null) {
|
||||
//get the sponsor times from storage
|
||||
let sponsorTimeKey = 'sponsorTimes' + previousVideoID;
|
||||
chrome.storage.local.get([sponsorTimeKey], function(result) {
|
||||
chrome.storage.sync.get([sponsorTimeKey], function(result) {
|
||||
let sponsorTimes = result[sponsorTimeKey];
|
||||
|
||||
if (sponsorTimes != undefined && sponsorTimes.length > 0) {
|
||||
@@ -149,23 +194,48 @@ function getUserID(callback) {
|
||||
}
|
||||
|
||||
//if it is not cached yet, grab it from storage
|
||||
chrome.storage.local.get(["userID"], function(result) {
|
||||
chrome.storage.sync.get(["userID"], function(result) {
|
||||
let userIDStorage = result.userID;
|
||||
if (userIDStorage != undefined) {
|
||||
userID = userIDStorage;
|
||||
callback(userID);
|
||||
} else {
|
||||
//double check if a UUID hasn't been created since this was first called
|
||||
if (userID != null) {
|
||||
callback(userID);
|
||||
return;
|
||||
}
|
||||
|
||||
//generate a userID
|
||||
userID = generateUUID();
|
||||
|
||||
//save this UUID
|
||||
chrome.storage.local.set({"userID": userID});
|
||||
chrome.storage.sync.set({"userID": userID});
|
||||
|
||||
callback(userID);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
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 getYouTubeVideoID(url) { // Return video id or false
|
||||
var regExp = /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#\&\?]*).*/;
|
||||
var match = url.match(regExp);
|
||||
|
||||
@@ -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 = "http://localhost";
|
||||
92
content.css
@@ -1,8 +1,32 @@
|
||||
.popup {
|
||||
z-index: 10;
|
||||
width: 100%;
|
||||
height: 500px;
|
||||
}
|
||||
|
||||
.smallLink {
|
||||
font-size: 10px;
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.playerButtonImage {
|
||||
height: 60%;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
display: block;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.playerButton {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.sponsorSkipObject {
|
||||
font-family: 'Source Sans Pro', sans-serif;
|
||||
}
|
||||
|
||||
#sponsorSkipLogo {
|
||||
.sponsorSkipLogo {
|
||||
height: 64px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
@@ -11,7 +35,12 @@
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
#sponsorSkipNotice {
|
||||
@keyframes fadeIn {
|
||||
from { opacity: 0; }
|
||||
to { opacity: 1; }
|
||||
}
|
||||
|
||||
.sponsorSkipNotice {
|
||||
min-height: 165px;
|
||||
min-width: 400px;
|
||||
background-color: rgba(255, 217, 217, 0.8);
|
||||
@@ -19,9 +48,18 @@
|
||||
z-index: 1;
|
||||
border: 3px solid rgba(0, 0, 0, 0.8);
|
||||
margin-top: -50px;
|
||||
|
||||
animation: fadeIn 0.5s;
|
||||
}
|
||||
|
||||
#sponsorSkipMessage {
|
||||
/* if two are very close to eachother */
|
||||
.secondSkipNotice {
|
||||
margin-left: 500px;
|
||||
|
||||
transition: margin-left 0.2s;
|
||||
}
|
||||
|
||||
.sponsorSkipMessage {
|
||||
font-size: 18px;
|
||||
color: #000000;
|
||||
text-align: center;
|
||||
@@ -30,7 +68,7 @@
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
#sponsorSkipInfo {
|
||||
.sponsorSkipInfo {
|
||||
font-size: 10px;
|
||||
color: #000000;
|
||||
text-align: center;
|
||||
@@ -42,6 +80,8 @@
|
||||
font-weight: bold;
|
||||
color: #000000;
|
||||
text-align: center;
|
||||
margin-top: 0px;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
#sponsorTimesThanksForVotingInfoText {
|
||||
@@ -49,6 +89,14 @@
|
||||
font-weight: bold;
|
||||
color: #000000;
|
||||
text-align: center;
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
.sponsorTimesInfoMessage {
|
||||
font-size: 15px;
|
||||
font-weight: bold;
|
||||
color: #000000;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.voteButton {
|
||||
@@ -60,6 +108,42 @@
|
||||
filter: brightness(80%);
|
||||
}
|
||||
|
||||
.submitButton {
|
||||
background-color:#ec1c1c;
|
||||
-moz-border-radius:28px;
|
||||
-webkit-border-radius:28px;
|
||||
border-radius:28px;
|
||||
border:1px solid #d31919;
|
||||
display:inline-block;
|
||||
cursor:pointer;
|
||||
color:#ffffff;
|
||||
font-size:14px;
|
||||
padding:4px 15px;
|
||||
text-decoration:none;
|
||||
text-shadow:0px 0px 0px #662727;
|
||||
|
||||
margin-top: 5px;
|
||||
margin-right: 15px;
|
||||
}
|
||||
.submitButton:hover {
|
||||
background-color:#bf2a2a;
|
||||
}
|
||||
|
||||
.submitButton:focus {
|
||||
outline: none;
|
||||
background-color:#bf2a2a;
|
||||
}
|
||||
|
||||
.submitButton:active {
|
||||
position:relative;
|
||||
top:1px;
|
||||
}
|
||||
|
||||
@keyframes rotate {
|
||||
from { transform: rotate(0deg); }
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
.sponsorSkipButton {
|
||||
background-color:#ec1c1c;
|
||||
-moz-border-radius:28px;
|
||||
|
||||
790
content.js
@@ -1,25 +1,24 @@
|
||||
if(id = getYouTubeVideoID(document.URL)){ // Direct Links
|
||||
videoIDChange(id);
|
||||
|
||||
//tell background.js about this
|
||||
chrome.runtime.sendMessage({
|
||||
message: "ytvideoid",
|
||||
videoID: id
|
||||
});
|
||||
}
|
||||
|
||||
//was sponsor data found when doing SponsorsLookup
|
||||
var sponsorDataFound = false;
|
||||
|
||||
//the actual sponsorTimes if loaded and UUIDs associated with them
|
||||
var sponsorTimes = undefined;
|
||||
var UUIDs = undefined;
|
||||
var sponsorTimes = null;
|
||||
var UUIDs = null;
|
||||
//what video id are these sponsors for
|
||||
var sponsorVideoID = null;
|
||||
|
||||
if(id = getYouTubeVideoID(document.URL)){ // Direct Links
|
||||
videoIDChange(id);
|
||||
}
|
||||
|
||||
//the video
|
||||
var v;
|
||||
|
||||
//the last time looked at (used to see if this time is in the interval)
|
||||
var lastTime;
|
||||
var lastTime = -1;
|
||||
|
||||
//the actual time (not video time) that the last skip happened
|
||||
var lastUnixTimeSkipped = -1;
|
||||
|
||||
//the last time in the video a sponsor was skipped
|
||||
//used for the go back button
|
||||
@@ -32,11 +31,28 @@ var showingStartSponsor = true;
|
||||
|
||||
//should the video controls buttons be added
|
||||
var hideVideoPlayerControls = false;
|
||||
var hideInfoButtonPlayerControls = false;
|
||||
var hideDeleteButtonPlayerControls = false;
|
||||
|
||||
//becomes true when isInfoFound is called
|
||||
//this is used to close the popup on YouTube when the other popup opens
|
||||
var popupInitialised = false;
|
||||
|
||||
//should view counts be tracked
|
||||
var trackViewCount = false;
|
||||
chrome.storage.sync.get(["trackViewCount"], function(result) {
|
||||
let trackViewCountStorage = result.trackViewCount;
|
||||
if (trackViewCountStorage != undefined) {
|
||||
trackViewCount = trackViewCountStorage;
|
||||
} else {
|
||||
trackViewCount = true;
|
||||
}
|
||||
});
|
||||
|
||||
//if the notice should not be shown
|
||||
//happens when the user click's the "Don't show notice again" button
|
||||
var dontShowNotice = false;
|
||||
chrome.storage.local.get(["dontShowNoticeAgain"], function(result) {
|
||||
chrome.storage.sync.get(["dontShowNoticeAgain"], function(result) {
|
||||
let dontShowNoticeAgain = result.dontShowNoticeAgain;
|
||||
if (dontShowNoticeAgain != undefined) {
|
||||
dontShowNotice = dontShowNoticeAgain;
|
||||
@@ -52,15 +68,23 @@ chrome.runtime.onMessage.addListener( // Detect URL Changes
|
||||
|
||||
//messages from popup script
|
||||
if (request.message == "sponsorStart") {
|
||||
sponsorMessageStarted();
|
||||
sponsorMessageStarted(sendResponse);
|
||||
}
|
||||
|
||||
if (request.message == "isInfoFound") {
|
||||
//send the sponsor times along with if it's found
|
||||
sendResponse({
|
||||
found: sponsorDataFound,
|
||||
sponsorTimes: sponsorTimes
|
||||
})
|
||||
sponsorTimes: sponsorTimes,
|
||||
UUIDs: UUIDs
|
||||
});
|
||||
|
||||
if (popupInitialised && document.getElementById("sponsorBlockPopupContainer") != null) {
|
||||
//the popup should be closed now that another is opening
|
||||
closeInfoMenu();
|
||||
}
|
||||
|
||||
popupInitialised = true;
|
||||
}
|
||||
|
||||
if (request.message == "getVideoID") {
|
||||
@@ -73,18 +97,63 @@ chrome.runtime.onMessage.addListener( // Detect URL Changes
|
||||
dontShowNotice = false;
|
||||
}
|
||||
|
||||
if (request.message == "toggleStartSponsorButton") {
|
||||
toggleStartSponsorButton();
|
||||
if (request.message == "changeStartSponsorButton") {
|
||||
changeStartSponsorButton(request.showStartSponsor, request.uploadButtonVisible);
|
||||
}
|
||||
|
||||
if (request.message == "changeVideoPlayerControlsVisibility") {
|
||||
hideVideoPlayerControls = request.value;
|
||||
|
||||
updateVisibilityOfPlayerControlsButton();
|
||||
} else if (request.message == "changeInfoButtonPlayerControlsVisibility") {
|
||||
hideInfoButtonPlayerControls = request.value;
|
||||
|
||||
updateVisibilityOfPlayerControlsButton();
|
||||
} else if (request.message == "changeDeleteButtonPlayerControlsVisibility") {
|
||||
hideDeleteButtonPlayerControls = request.value;
|
||||
|
||||
updateVisibilityOfPlayerControlsButton();
|
||||
}
|
||||
|
||||
if (request.message == "trackViewCount") {
|
||||
trackViewCount = request.value;
|
||||
}
|
||||
});
|
||||
|
||||
//check for hotkey pressed
|
||||
document.onkeydown = function(e){
|
||||
e = e || window.event;
|
||||
var key = e.which || e.keyCode;
|
||||
|
||||
let video = document.getElementById("movie_player");
|
||||
|
||||
//is the video in focus, otherwise they could be typing a comment
|
||||
if (document.activeElement === video) {
|
||||
if(key == 186){
|
||||
//semicolon
|
||||
startSponsorClicked();
|
||||
} else if (key == 222) {
|
||||
//single quote
|
||||
submitSponsorTimes();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function videoIDChange(id) {
|
||||
//not a url change
|
||||
if (sponsorVideoID == id){
|
||||
return;
|
||||
}
|
||||
|
||||
//reset last sponsor times
|
||||
lastTime = -1;
|
||||
lastUnixTimeSkipped = -1;
|
||||
|
||||
//reset sponsor times
|
||||
sponsorTimes = null;
|
||||
UUIDs = null;
|
||||
sponsorVideoID = id;
|
||||
|
||||
//reset sponsor data found check
|
||||
sponsorDataFound = false;
|
||||
sponsorsLookup(id);
|
||||
@@ -96,76 +165,124 @@ function videoIDChange(id) {
|
||||
}, function(response) {
|
||||
if (response != undefined) {
|
||||
let sponsorTimes = response.sponsorTimes;
|
||||
if (sponsorTimes != undefined && sponsorTimes.length > 0 && sponsorTimes[sponsorTimes.length - 1].length < 2) {
|
||||
toggleStartSponsorButton();
|
||||
if (sponsorTimes != null && sponsorTimes.length > 0 && sponsorTimes[sponsorTimes.length - 1].length >= 2) {
|
||||
changeStartSponsorButton(true, true);
|
||||
} else if (sponsorTimes != null && sponsorTimes.length > 0 && sponsorTimes[sponsorTimes.length - 1].length < 2) {
|
||||
changeStartSponsorButton(false, true);
|
||||
} else {
|
||||
changeStartSponsorButton(true, false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
//see if video control buttons should be added
|
||||
chrome.storage.local.get(["hideVideoPlayerControls"], function(result) {
|
||||
//see if video controls buttons should be added
|
||||
chrome.storage.sync.get(["hideVideoPlayerControls"], function(result) {
|
||||
if (result.hideVideoPlayerControls != undefined) {
|
||||
hideVideoPlayerControls = result.hideVideoPlayerControls;
|
||||
}
|
||||
|
||||
updateVisibilityOfPlayerControlsButton();
|
||||
});
|
||||
chrome.storage.sync.get(["hideInfoButtonPlayerControls"], function(result) {
|
||||
if (result.hideInfoButtonPlayerControls != undefined) {
|
||||
hideInfoButtonPlayerControls = result.hideInfoButtonPlayerControls;
|
||||
}
|
||||
|
||||
updateVisibilityOfPlayerControlsButton();
|
||||
});
|
||||
chrome.storage.sync.get(["hideDeleteButtonPlayerControls"], function(result) {
|
||||
if (result.hideDeleteButtonPlayerControls != undefined) {
|
||||
hideDeleteButtonPlayerControls = result.hideDeleteButtonPlayerControls;
|
||||
}
|
||||
|
||||
updateVisibilityOfPlayerControlsButton();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function sponsorsLookup(id) {
|
||||
v = document.querySelector('video') // Youtube video player
|
||||
let xmlhttp = new XMLHttpRequest();
|
||||
|
||||
//check database for sponsor times
|
||||
xmlhttp.open('GET', serverAddress + "/api/getVideoSponsorTimes?videoID=" + id, true);
|
||||
sendRequestToServer('GET', "/api/getVideoSponsorTimes?videoID=" + id, function(xmlhttp) {
|
||||
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
|
||||
sponsorDataFound = true;
|
||||
|
||||
xmlhttp.onreadystatechange = function () {
|
||||
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
|
||||
sponsorDataFound = true;
|
||||
sponsorTimes = JSON.parse(xmlhttp.responseText).sponsorTimes;
|
||||
UUIDs = JSON.parse(xmlhttp.responseText).UUIDs;
|
||||
|
||||
sponsorTimes = JSON.parse(xmlhttp.responseText).sponsorTimes;
|
||||
UUIDs = JSON.parse(xmlhttp.responseText).UUIDs;
|
||||
// If the sponsor data exists, add the event to run on the videos "ontimeupdate"
|
||||
v.ontimeupdate = function () {
|
||||
sponsorCheck(sponsorTimes);
|
||||
};
|
||||
} else if (xmlhttp.readyState == 4) {
|
||||
sponsorDataFound = false;
|
||||
|
||||
// If the sponsor data exists, add the event to run on the videos "ontimeupdate"
|
||||
v.ontimeupdate = function () {
|
||||
sponsorCheck(sponsorTimes);
|
||||
};
|
||||
} else {
|
||||
sponsorDataFound = false;
|
||||
}
|
||||
};
|
||||
xmlhttp.send(null);
|
||||
//check if this video was uploaded recently
|
||||
//use the invidious api to get the time published
|
||||
sendRequestToCustomServer('GET', "https://invidio.us/api/v1/videos/" + id, function(xmlhttp, error) {
|
||||
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
|
||||
let unixTimePublished = JSON.parse(xmlhttp.responseText).published;
|
||||
|
||||
//if less than 3 days old
|
||||
if ((Date.now() / 1000) - unixTimePublished < 259200) {
|
||||
setTimeout(() => sponsorsLookup(id), 10000);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function sponsorCheck(sponsorTimes) { // Video skipping
|
||||
//see if any sponsor start time was just passed
|
||||
for (let i = 0; i < sponsorTimes.length; i++) {
|
||||
//the sponsor time is in between these times, skip it
|
||||
//if the time difference is more than 1 second, than the there was probably a skip in time,
|
||||
// and it's not due to playback
|
||||
if (Math.abs(v.currentTime - lastTime) < 1 && sponsorTimes[i][0] >= lastTime && sponsorTimes[i][0] <= v.currentTime) {
|
||||
//skip it
|
||||
v.currentTime = sponsorTimes[i][1];
|
||||
|
||||
lastSponsorTimeSkipped = sponsorTimes[i][0];
|
||||
lastSponsorTimeSkippedUUID = UUIDs[i];
|
||||
|
||||
//send out the message saying that a sponsor message was skipped
|
||||
openSkipNotice();
|
||||
|
||||
setTimeout(closeSkipNotice, 7000);
|
||||
}
|
||||
|
||||
lastTime = v.currentTime;
|
||||
//see if any sponsor start time was just passed
|
||||
for (let i = 0; i < sponsorTimes.length; i++) {
|
||||
//this means part of the video was just skipped
|
||||
if (Math.abs(v.currentTime - lastTime) > 1 && lastTime != -1) {
|
||||
//make lastTime as if the video was playing normally
|
||||
lastTime = v.currentTime - 0.0001;
|
||||
}
|
||||
|
||||
let currentTime = Date.now();
|
||||
|
||||
//If the sponsor time is in between these times, skip it
|
||||
//Checks if the last time skipped to is not too close to now, to make sure not to get too many
|
||||
// sponsor times in a row (from one troll)
|
||||
//the last term makes 0 second start times possible
|
||||
if ((Math.abs(v.currentTime - sponsorTimes[i][0]) < 0.3 && sponsorTimes[i][0] >= lastTime && sponsorTimes[i][0] <= v.currentTime
|
||||
&& (lastUnixTimeSkipped == -1 || currentTime - lastUnixTimeSkipped > 500)) || (lastTime == -1 && sponsorTimes[i][0] == 0)) {
|
||||
//skip it
|
||||
v.currentTime = sponsorTimes[i][1];
|
||||
|
||||
lastSponsorTimeSkipped = sponsorTimes[i][0];
|
||||
|
||||
let currentUUID = UUIDs[i];
|
||||
lastSponsorTimeSkippedUUID = currentUUID;
|
||||
|
||||
//send out the message saying that a sponsor message was skipped
|
||||
openSkipNotice(currentUUID);
|
||||
|
||||
setTimeout(() => closeSkipNotice(currentUUID), 7000);
|
||||
|
||||
//send telemetry that a this sponsor was skipped happened
|
||||
if (trackViewCount) {
|
||||
sendRequestToServer("GET", "/api/viewedVideoSponsorTime?UUID=" + currentUUID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//don't keep track until they are loaded in
|
||||
if (sponsorTimes.length > 0) {
|
||||
lastTime = v.currentTime;
|
||||
}
|
||||
}
|
||||
|
||||
function goBackToPreviousTime() {
|
||||
if (lastSponsorTimeSkipped != null) {
|
||||
function goBackToPreviousTime(UUID) {
|
||||
if (sponsorTimes != null) {
|
||||
//add a tiny bit of time to make sure it is not skipped again
|
||||
v.currentTime = lastSponsorTimeSkipped + 0.001;
|
||||
v.currentTime = sponsorTimes[UUIDs.indexOf(UUID)][0] + 0.001;
|
||||
|
||||
closeSkipNotice();
|
||||
closeSkipNotice(UUID);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,17 +295,13 @@ function addPlayerControlsButton() {
|
||||
|
||||
let startSponsorButton = document.createElement("button");
|
||||
startSponsorButton.id = "startSponsorButton";
|
||||
startSponsorButton.className = "ytp-button";
|
||||
startSponsorButton.className = "ytp-button playerButton";
|
||||
startSponsorButton.setAttribute("title", "Sponsor Starts Now");
|
||||
startSponsorButton.addEventListener("click", startSponsorClicked);
|
||||
|
||||
let startSponsorImage = document.createElement("img");
|
||||
startSponsorImage.id = "startSponsorImage";
|
||||
startSponsorImage.style.height = "60%";
|
||||
startSponsorImage.style.top = "0";
|
||||
startSponsorImage.style.bottom = "0";
|
||||
startSponsorImage.style.display = "block";
|
||||
startSponsorImage.style.margin = "auto";
|
||||
startSponsorImage.className = "playerButtonImage";
|
||||
startSponsorImage.src = chrome.extension.getURL("icons/PlayerStartIconSponsorBlocker256px.png");
|
||||
|
||||
//add the image to the button
|
||||
@@ -201,78 +314,307 @@ function addPlayerControlsButton() {
|
||||
|
||||
function removePlayerControlsButton() {
|
||||
document.getElementById("startSponsorButton").style.display = "none";
|
||||
document.getElementById("submitButton").style.display = "none";
|
||||
}
|
||||
|
||||
//adds or removes the player controls button to what it should be
|
||||
function updateVisibilityOfPlayerControlsButton() {
|
||||
addPlayerControlsButton();
|
||||
addInfoButton();
|
||||
addDeleteButton();
|
||||
addSubmitButton();
|
||||
if (hideVideoPlayerControls) {
|
||||
removePlayerControlsButton();
|
||||
} else {
|
||||
addPlayerControlsButton();
|
||||
}
|
||||
if (hideInfoButtonPlayerControls) {
|
||||
document.getElementById("infoButton").style.display = "none";
|
||||
}
|
||||
if (hideDeleteButtonPlayerControls) {
|
||||
document.getElementById("deleteButton").style.display = "none";
|
||||
}
|
||||
}
|
||||
|
||||
function startSponsorClicked() {
|
||||
//it can't update to this info yet
|
||||
closeInfoMenu();
|
||||
|
||||
toggleStartSponsorButton();
|
||||
|
||||
//send back current time with message
|
||||
chrome.runtime.sendMessage({
|
||||
message: "addSponsorTime",
|
||||
time: v.currentTime
|
||||
time: v.currentTime,
|
||||
videoID: getYouTubeVideoID(document.URL)
|
||||
});
|
||||
}
|
||||
|
||||
function toggleStartSponsorButton() {
|
||||
if (showingStartSponsor) {
|
||||
showingStartSponsor = false;
|
||||
document.getElementById("startSponsorImage").src = chrome.extension.getURL("icons/PlayerStopIconSponsorBlocker256px.png");
|
||||
function changeStartSponsorButton(showStartSponsor, uploadButtonVisible) {
|
||||
//if it isn't visible, there is no data
|
||||
if (uploadButtonVisible && !hideDeleteButtonPlayerControls) {
|
||||
document.getElementById("deleteButton").style.display = "unset";
|
||||
} else {
|
||||
document.getElementById("deleteButton").style.display = "none";
|
||||
}
|
||||
|
||||
if (showStartSponsor) {
|
||||
showingStartSponsor = true;
|
||||
document.getElementById("startSponsorImage").src = chrome.extension.getURL("icons/PlayerStartIconSponsorBlocker256px.png");
|
||||
document.getElementById("startSponsorButton").setAttribute("title", "Sponsor Starts Now");
|
||||
|
||||
if (document.getElementById("startSponsorImage").style.display != "none" && uploadButtonVisible && !hideInfoButtonPlayerControls) {
|
||||
document.getElementById("submitButton").style.display = "unset";
|
||||
} else if (!uploadButtonVisible) {
|
||||
//disable submit button
|
||||
document.getElementById("submitButton").style.display = "none";
|
||||
}
|
||||
} else {
|
||||
showingStartSponsor = false;
|
||||
document.getElementById("startSponsorImage").src = chrome.extension.getURL("icons/PlayerStopIconSponsorBlocker256px.png");
|
||||
document.getElementById("startSponsorButton").setAttribute("title", "Sponsor Ends Now");
|
||||
|
||||
//disable submit button
|
||||
document.getElementById("submitButton").style.display = "none";
|
||||
}
|
||||
}
|
||||
|
||||
function toggleStartSponsorButton() {
|
||||
changeStartSponsorButton(!showingStartSponsor, true);
|
||||
}
|
||||
|
||||
//shows the info button on the video player
|
||||
function addInfoButton() {
|
||||
if (document.getElementById("infoButton") != null) {
|
||||
//it's already added
|
||||
return;
|
||||
}
|
||||
|
||||
//make a submit button
|
||||
let infoButton = document.createElement("button");
|
||||
infoButton.id = "infoButton";
|
||||
infoButton.className = "ytp-button playerButton";
|
||||
infoButton.setAttribute("title", "Open SponsorBlock Popup");
|
||||
infoButton.addEventListener("click", openInfoMenu);
|
||||
|
||||
let infoImage = document.createElement("img");
|
||||
infoImage.id = "infoButtonImage";
|
||||
infoImage.className = "playerButtonImage";
|
||||
infoImage.src = chrome.extension.getURL("icons/PlayerInfoIconSponsorBlocker256px.png");
|
||||
|
||||
//add the image to the button
|
||||
infoButton.appendChild(infoImage);
|
||||
|
||||
let referenceNode = document.getElementsByClassName("ytp-right-controls")[0];
|
||||
referenceNode.prepend(infoButton);
|
||||
}
|
||||
|
||||
//shows the delete button on the video player
|
||||
function addDeleteButton() {
|
||||
if (document.getElementById("deleteButton") != null) {
|
||||
//it's already added
|
||||
return;
|
||||
}
|
||||
|
||||
//make a submit button
|
||||
let deleteButton = document.createElement("button");
|
||||
deleteButton.id = "deleteButton";
|
||||
deleteButton.className = "ytp-button playerButton";
|
||||
deleteButton.setAttribute("title", "Clear Sponsor Times");
|
||||
deleteButton.addEventListener("click", clearSponsorTimes);
|
||||
//hide it at the start
|
||||
deleteButton.style.display = "none";
|
||||
|
||||
let deleteImage = document.createElement("img");
|
||||
deleteImage.id = "deleteButtonImage";
|
||||
deleteImage.className = "playerButtonImage";
|
||||
deleteImage.src = chrome.extension.getURL("icons/PlayerDeleteIconSponsorBlocker256px.png");
|
||||
|
||||
//add the image to the button
|
||||
deleteButton.appendChild(deleteImage);
|
||||
|
||||
let referenceNode = document.getElementsByClassName("ytp-right-controls")[0];
|
||||
referenceNode.prepend(deleteButton);
|
||||
}
|
||||
|
||||
//shows the submit button on the video player
|
||||
function addSubmitButton() {
|
||||
if (document.getElementById("submitButton") != null) {
|
||||
//it's already added
|
||||
return;
|
||||
}
|
||||
|
||||
//make a submit button
|
||||
let submitButton = document.createElement("button");
|
||||
submitButton.id = "submitButton";
|
||||
submitButton.className = "ytp-button playerButton";
|
||||
submitButton.setAttribute("title", "Submit Sponsor Times");
|
||||
submitButton.addEventListener("click", submitSponsorTimes);
|
||||
//hide it at the start
|
||||
submitButton.style.display = "none";
|
||||
|
||||
let submitImage = document.createElement("img");
|
||||
submitImage.id = "submitButtonImage";
|
||||
submitImage.className = "playerButtonImage";
|
||||
submitImage.src = chrome.extension.getURL("icons/PlayerUploadIconSponsorBlocker256px.png");
|
||||
|
||||
//add the image to the button
|
||||
submitButton.appendChild(submitImage);
|
||||
|
||||
let referenceNode = document.getElementsByClassName("ytp-right-controls")[0];
|
||||
referenceNode.prepend(submitButton);
|
||||
}
|
||||
|
||||
function openInfoMenu() {
|
||||
if (document.getElementById("sponsorBlockPopupContainer") != null) {
|
||||
//it's already added
|
||||
return;
|
||||
}
|
||||
|
||||
popupInitialised = false;
|
||||
|
||||
//hide info button
|
||||
document.getElementById("infoButton").style.display = "none";
|
||||
|
||||
let popup = document.createElement("div");
|
||||
popup.id = "sponsorBlockPopupContainer";
|
||||
|
||||
let popupFrame = document.createElement("iframe");
|
||||
popupFrame.id = "sponsorBlockPopupFrame"
|
||||
popupFrame.src = chrome.extension.getURL("popup.html");
|
||||
popupFrame.className = "popup";
|
||||
|
||||
//close button
|
||||
let closeButton = document.createElement("div");
|
||||
closeButton.innerText = "Close Popup";
|
||||
closeButton.classList = "smallLink";
|
||||
closeButton.setAttribute("align", "center");
|
||||
closeButton.addEventListener("click", closeInfoMenu);
|
||||
|
||||
popup.appendChild(closeButton);
|
||||
popup.appendChild(popupFrame);
|
||||
|
||||
let parentNode = document.getElementById("secondary");
|
||||
if (parentNode == null) {
|
||||
//old youtube theme
|
||||
parentNode = document.getElementById("watch7-sidebar-contents");
|
||||
}
|
||||
|
||||
parentNode.prepend(popup);
|
||||
}
|
||||
|
||||
function closeInfoMenu() {
|
||||
let popup = document.getElementById("sponsorBlockPopupContainer");
|
||||
if (popup != null) {
|
||||
popup.remove();
|
||||
|
||||
//show info button
|
||||
document.getElementById("infoButton").style.display = "unset";
|
||||
}
|
||||
}
|
||||
|
||||
function clearSponsorTimes() {
|
||||
//it can't update to this info yet
|
||||
closeInfoMenu();
|
||||
|
||||
let currentVideoID = getYouTubeVideoID(document.URL);
|
||||
|
||||
let sponsorTimeKey = 'sponsorTimes' + currentVideoID;
|
||||
chrome.storage.sync.get([sponsorTimeKey], function(result) {
|
||||
let sponsorTimes = result[sponsorTimeKey];
|
||||
|
||||
if (sponsorTimes != undefined && sponsorTimes.length > 0) {
|
||||
let confirmMessage = "Are you sure you want to clear this?\n\n" + getSponsorTimesMessage(sponsorTimes);
|
||||
confirmMessage += "\n\nTo edit or delete individual values, click the info button or open the extension popup by clicking the extension icon in the top right corner."
|
||||
if(!confirm(confirmMessage)) return;
|
||||
|
||||
//clear the sponsor times
|
||||
let sponsorTimeKey = "sponsorTimes" + currentVideoID;
|
||||
chrome.storage.sync.set({[sponsorTimeKey]: []});
|
||||
|
||||
//set buttons to be correct
|
||||
changeStartSponsorButton(true, false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//Opens the notice that tells the user that a sponsor was just skipped
|
||||
function openSkipNotice(){
|
||||
function openSkipNotice(UUID){
|
||||
if (dontShowNotice) {
|
||||
//don't show, return
|
||||
return;
|
||||
}
|
||||
|
||||
//check if page is loaded yet (for 0 second sponsors, the page might not be loaded yet)
|
||||
//it looks for the view count div and sees if it is full yet
|
||||
//querySelectorAll is being used like findElementById for multiple objects, because for
|
||||
//some reason YouTube has put more than one object with one ID.
|
||||
let viewCountNode = document.querySelectorAll("#count");
|
||||
//check to see if the length is over zero, otherwise it's a different YouTube theme probably
|
||||
if (viewCountNode.length > 0) {
|
||||
//check if any of these have text
|
||||
let viewCountVisible = false;
|
||||
for (let i = 0; i < viewCountNode.length; i++) {
|
||||
if (viewCountNode[i].innerText != null) {
|
||||
viewCountVisible = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!viewCountVisible) {
|
||||
//this is the new YouTube layout and it is still loading
|
||||
//wait a bit for opening the notice
|
||||
setTimeout(() => openSkipNotice(UUID), 200);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
let amountOfPreviousNotices = document.getElementsByClassName("sponsorSkipNotice").length;
|
||||
|
||||
if (amountOfPreviousNotices > 0) {
|
||||
//already exists
|
||||
|
||||
let previousNotice = document.getElementsByClassName("sponsorSkipNotice")[0];
|
||||
previousNotice.classList.add("secondSkipNotice")
|
||||
}
|
||||
|
||||
let noticeElement = document.createElement("div");
|
||||
noticeElement.id = "sponsorSkipNotice";
|
||||
noticeElement.className = "sponsorSkipObject";
|
||||
//what sponsor time this is about
|
||||
noticeElement.id = "sponsorSkipNotice" + UUID;
|
||||
noticeElement.classList.add("sponsorSkipObject");
|
||||
noticeElement.classList.add("sponsorSkipNotice");
|
||||
noticeElement.style.zIndex = 5 + amountOfPreviousNotices;
|
||||
|
||||
let logoElement = document.createElement("img");
|
||||
logoElement.id = "sponsorSkipLogo";
|
||||
logoElement.id = "sponsorSkipLogo" + UUID;
|
||||
logoElement.className = "sponsorSkipLogo";
|
||||
logoElement.src = chrome.extension.getURL("icons/LogoSponsorBlocker256px.png");
|
||||
|
||||
let noticeMessage = document.createElement("div");
|
||||
noticeMessage.id = "sponsorSkipMessage";
|
||||
noticeMessage.className = "sponsorSkipObject";
|
||||
noticeMessage.id = "sponsorSkipMessage" + UUID;
|
||||
noticeMessage.classList.add("sponsorSkipMessage");
|
||||
noticeMessage.classList.add("sponsorSkipObject");
|
||||
noticeMessage.innerText = "Hey, you just skipped a sponsor!";
|
||||
|
||||
let noticeInfo = document.createElement("p");
|
||||
noticeInfo.id = "sponsorSkipInfo";
|
||||
noticeInfo.className = "sponsorSkipObject";
|
||||
noticeInfo.id = "sponsorSkipInfo" + UUID;
|
||||
noticeInfo.classList.add("sponsorSkipInfo");
|
||||
noticeInfo.classList.add("sponsorSkipObject");
|
||||
noticeInfo.innerText = "This message will disapear in 7 seconds";
|
||||
|
||||
//thumbs up and down buttons
|
||||
let voteButtonsContainer = document.createElement("div");
|
||||
voteButtonsContainer.id = "sponsorTimesVoteButtonsContainer";
|
||||
voteButtonsContainer.id = "sponsorTimesVoteButtonsContainer" + UUID;
|
||||
voteButtonsContainer.setAttribute("align", "center");
|
||||
|
||||
let upvoteButton = document.createElement("img");
|
||||
upvoteButton.id = "sponsorTimesUpvoteButtonsContainer"
|
||||
upvoteButton.id = "sponsorTimesUpvoteButtonsContainer" + UUID;
|
||||
upvoteButton.className = "sponsorSkipObject voteButton";
|
||||
upvoteButton.src = chrome.extension.getURL("icons/upvote.png");
|
||||
upvoteButton.addEventListener("click", upvote);
|
||||
upvoteButton.addEventListener("click", () => vote(1, UUID));
|
||||
|
||||
let downvoteButton = document.createElement("img");
|
||||
downvoteButton.id = "sponsorTimesDownvoteButtonsContainer"
|
||||
downvoteButton.id = "sponsorTimesDownvoteButtonsContainer" + UUID;
|
||||
downvoteButton.className = "sponsorSkipObject voteButton";
|
||||
downvoteButton.src = chrome.extension.getURL("icons/downvote.png");
|
||||
downvoteButton.addEventListener("click", downvote);
|
||||
downvoteButton.addEventListener("click", () => vote(0, UUID));
|
||||
|
||||
//add thumbs up and down buttons to the container
|
||||
voteButtonsContainer.appendChild(upvoteButton);
|
||||
@@ -284,12 +626,12 @@ function openSkipNotice(){
|
||||
let goBackButton = document.createElement("button");
|
||||
goBackButton.innerText = "Go back";
|
||||
goBackButton.className = "sponsorSkipButton";
|
||||
goBackButton.addEventListener("click", goBackToPreviousTime);
|
||||
goBackButton.addEventListener("click", () => goBackToPreviousTime(UUID));
|
||||
|
||||
let hideButton = document.createElement("button");
|
||||
hideButton.innerText = "Dismiss";
|
||||
hideButton.className = "sponsorSkipButton";
|
||||
hideButton.addEventListener("click", closeSkipNotice);
|
||||
hideButton.addEventListener("click", () => closeSkipNotice(UUID));
|
||||
|
||||
let dontShowAgainButton = document.createElement("button");
|
||||
dontShowAgainButton.innerText = "Don't Show This Again";
|
||||
@@ -316,19 +658,23 @@ function openSkipNotice(){
|
||||
referenceNode.prepend(noticeElement);
|
||||
}
|
||||
|
||||
function upvote() {
|
||||
vote(1);
|
||||
|
||||
closeSkipNotice();
|
||||
}
|
||||
|
||||
function downvote() {
|
||||
vote(0);
|
||||
|
||||
function afterDownvote(UUID) {
|
||||
//change text to say thanks for voting
|
||||
//remove buttons
|
||||
document.getElementById("sponsorTimesVoteButtonsContainer").removeChild(document.getElementById("sponsorTimesUpvoteButtonsContainer"));
|
||||
document.getElementById("sponsorTimesVoteButtonsContainer").removeChild(document.getElementById("sponsorTimesDownvoteButtonsContainer"));
|
||||
let upvoteButton = document.getElementById("sponsorTimesUpvoteButtonsContainer" + UUID);
|
||||
let downvoteButton = document.getElementById("sponsorTimesDownvoteButtonsContainer" + UUID);
|
||||
if (upvoteButton != null) {
|
||||
document.getElementById("sponsorTimesVoteButtonsContainer" + UUID).removeChild(upvoteButton);
|
||||
}
|
||||
if (downvoteButton != null) {
|
||||
document.getElementById("sponsorTimesVoteButtonsContainer" + UUID).removeChild(downvoteButton);
|
||||
}
|
||||
|
||||
let previousInfoMessage = document.getElementById("sponsorTimesInfoMessage" + UUID);
|
||||
if (previousInfoMessage != null) {
|
||||
//remove it
|
||||
document.getElementById("sponsorTimesVoteButtonsContainer" + UUID).removeChild(previousInfoMessage);
|
||||
}
|
||||
|
||||
//add thanks for voting text
|
||||
let thanksForVotingText = document.createElement("p");
|
||||
@@ -341,49 +687,261 @@ function downvote() {
|
||||
thanksForVotingInfoText.innerText = "Hit go back to get to where you came from."
|
||||
|
||||
//add element to div
|
||||
document.getElementById("sponsorTimesVoteButtonsContainer").appendChild(thanksForVotingText);
|
||||
document.getElementById("sponsorTimesVoteButtonsContainer").appendChild(thanksForVotingInfoText);
|
||||
document.getElementById("sponsorTimesVoteButtonsContainer" + UUID).appendChild(thanksForVotingText);
|
||||
document.getElementById("sponsorTimesVoteButtonsContainer" + UUID).appendChild(thanksForVotingInfoText);
|
||||
}
|
||||
|
||||
function vote(type) {
|
||||
function addLoadingInfo(message, UUID) {
|
||||
//change text to say thanks for message
|
||||
//remove buttons
|
||||
let upvoteButton = document.getElementById("sponsorTimesUpvoteButtonsContainer" + UUID);
|
||||
let downvoteButton = document.getElementById("sponsorTimesDownvoteButtonsContainer" + UUID);
|
||||
if (upvoteButton != null) {
|
||||
document.getElementById("sponsorTimesVoteButtonsContainer" + UUID).removeChild(upvoteButton);
|
||||
}
|
||||
if (downvoteButton != null) {
|
||||
document.getElementById("sponsorTimesVoteButtonsContainer" + UUID).removeChild(downvoteButton);
|
||||
}
|
||||
|
||||
let previousInfoMessage = document.getElementById("sponsorTimesInfoMessage" + UUID);
|
||||
if (previousInfoMessage != null) {
|
||||
//remove it
|
||||
document.getElementById("sponsorTimesVoteButtonsContainer" + UUID).removeChild(previousInfoMessage);
|
||||
}
|
||||
|
||||
//add thanks for voting text
|
||||
let thanksForVotingText = document.createElement("p");
|
||||
thanksForVotingText.id = "sponsorTimesInfoMessage" + UUID;
|
||||
thanksForVotingText.className = "sponsorTimesInfoMessage";
|
||||
thanksForVotingText.innerText = message;
|
||||
|
||||
//add element to div
|
||||
document.getElementById("sponsorTimesVoteButtonsContainer" + UUID).appendChild(thanksForVotingText);
|
||||
}
|
||||
|
||||
function vote(type, UUID) {
|
||||
//add loading info
|
||||
addLoadingInfo("Loading...", UUID)
|
||||
|
||||
chrome.runtime.sendMessage({
|
||||
message: "submitVote",
|
||||
type: type,
|
||||
UUID: lastSponsorTimeSkippedUUID
|
||||
UUID: UUID
|
||||
}, function(response) {
|
||||
if (response != undefined) {
|
||||
//see if it was a success or failure
|
||||
if (response.successType == 1) {
|
||||
//success
|
||||
if (type == 0) {
|
||||
afterDownvote(UUID);
|
||||
} else if (type == 1) {
|
||||
closeSkipNotice(UUID);
|
||||
}
|
||||
} else if (response.successType == 0) {
|
||||
//failure: duplicate vote
|
||||
addLoadingInfo("It seems you've already voted before", UUID)
|
||||
} else if (response.successType == -1) {
|
||||
if (response.statusCode == 502) {
|
||||
addLoadingInfo("It seems the sever is down. Contact the dev immediately.", UUID)
|
||||
} else {
|
||||
//failure: unknown error
|
||||
addLoadingInfo("A connection error has occured. Error code: " + response.statusCode, UUID)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//Closes the notice that tells the user that a sponsor was just skipped
|
||||
function closeSkipNotice(){
|
||||
let notice = document.getElementById("sponsorSkipNotice");
|
||||
//Closes the notice that tells the user that a sponsor was just skipped for this UUID
|
||||
function closeSkipNotice(UUID){
|
||||
let notice = document.getElementById("sponsorSkipNotice" + UUID);
|
||||
if (notice != null) {
|
||||
notice.remove();
|
||||
}
|
||||
}
|
||||
|
||||
//Closes all notices that tell the user that a sponsor was just skipped
|
||||
function closeAllSkipNotices(){
|
||||
let notices = document.getElementsByClassName("sponsorSkipNotice");
|
||||
for (let i = 0; i < notices.length; i++) {
|
||||
notices[i].remove();
|
||||
}
|
||||
}
|
||||
|
||||
function dontShowNoticeAgain() {
|
||||
chrome.storage.local.set({"dontShowNoticeAgain": true});
|
||||
chrome.storage.sync.set({"dontShowNoticeAgain": true});
|
||||
|
||||
dontShowNotice = true;
|
||||
|
||||
closeSkipNotice();
|
||||
closeAllSkipNotices();
|
||||
}
|
||||
|
||||
function sponsorMessageStarted() {
|
||||
function sponsorMessageStarted(callback) {
|
||||
let v = document.querySelector('video');
|
||||
|
||||
//send back current time
|
||||
chrome.runtime.sendMessage({
|
||||
message: "time",
|
||||
callback({
|
||||
time: v.currentTime
|
||||
});
|
||||
})
|
||||
|
||||
//update button
|
||||
toggleStartSponsorButton();
|
||||
}
|
||||
|
||||
function submitSponsorTimes() {
|
||||
if (document.getElementById("submitButton").style.display == "none") {
|
||||
//don't submit, not ready
|
||||
return;
|
||||
}
|
||||
|
||||
//it can't update to this info yet
|
||||
closeInfoMenu();
|
||||
|
||||
let currentVideoID = getYouTubeVideoID(document.URL);
|
||||
|
||||
let sponsorTimeKey = 'sponsorTimes' + currentVideoID;
|
||||
chrome.storage.sync.get([sponsorTimeKey], function(result) {
|
||||
let sponsorTimes = result[sponsorTimeKey];
|
||||
|
||||
if (sponsorTimes != undefined && sponsorTimes.length > 0) {
|
||||
let confirmMessage = "Are you sure you want to submit this?\n\n" + getSponsorTimesMessage(sponsorTimes);
|
||||
confirmMessage += "\n\nTo edit or delete values, click the info button or open the extension popup by clicking the extension icon in the top right corner."
|
||||
if(!confirm(confirmMessage)) return;
|
||||
|
||||
sendSubmitMessage();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
//send the message to the background js
|
||||
//called after all the checks have been made that it's okay to do so
|
||||
function sendSubmitMessage(){
|
||||
//add loading animation
|
||||
document.getElementById("submitButtonImage").src = chrome.extension.getURL("icons/PlayerUploadIconSponsorBlocker256px.png");
|
||||
document.getElementById("submitButton").style.animation = "rotate 1s 0s infinite";
|
||||
|
||||
let currentVideoID = getYouTubeVideoID(document.URL);
|
||||
|
||||
chrome.runtime.sendMessage({
|
||||
message: "submitTimes",
|
||||
videoID: currentVideoID
|
||||
}, function(response) {
|
||||
if (response != undefined) {
|
||||
if (response.statusCode == 200) {
|
||||
//hide loading message
|
||||
let submitButton = document.getElementById("submitButton");
|
||||
//finish this animation
|
||||
submitButton.style.animation = "rotate 1s";
|
||||
//when the animation is over, hide the button
|
||||
submitButton.addEventListener("animationend", function() {
|
||||
submitButton.style.animation = "unset";
|
||||
submitButton.style.display = "none";
|
||||
});
|
||||
|
||||
//clear the sponsor times
|
||||
let sponsorTimeKey = "sponsorTimes" + currentVideoID;
|
||||
chrome.storage.sync.set({[sponsorTimeKey]: []});
|
||||
} else {
|
||||
//for a more detailed error message, they should check the popup
|
||||
//show that the upload failed
|
||||
document.getElementById("submitButton").style.animation = "unset";
|
||||
document.getElementById("submitButtonImage").src = chrome.extension.getURL("icons/PlayerUploadFailedIconSponsorBlocker256px.png");
|
||||
|
||||
if(response.statusCode == 400) {
|
||||
alert("Server said this request was invalid");
|
||||
} else if(response.statusCode == 429) {
|
||||
alert("You have submitted too many sponsor times for this one video, are you sure there are this many?");
|
||||
} else if(response.statusCode == 409) {
|
||||
alert("This has already been submitted before");
|
||||
} else if(response.statusCode == 502) {
|
||||
alert("It seems the server is down. Contact the dev to inform them. Error code " + response.statusCode);
|
||||
} else {
|
||||
alert("There was an error submitting your sponsor times, please try again later. Error code " + response.statusCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//get the message that visually displays the video times
|
||||
function getSponsorTimesMessage(sponsorTimes) {
|
||||
let sponsorTimesMessage = "";
|
||||
|
||||
for (let i = 0; i < sponsorTimes.length; i++) {
|
||||
for (let s = 0; s < sponsorTimes[i].length; s++) {
|
||||
let timeMessage = getFormattedTime(sponsorTimes[i][s]);
|
||||
//if this is an end time
|
||||
if (s == 1) {
|
||||
timeMessage = " to " + timeMessage;
|
||||
} else if (i > 0) {
|
||||
//add commas if necessary
|
||||
timeMessage = ", " + timeMessage;
|
||||
}
|
||||
|
||||
sponsorTimesMessage += timeMessage;
|
||||
}
|
||||
}
|
||||
|
||||
return sponsorTimesMessage;
|
||||
}
|
||||
|
||||
//converts time in seconds to minutes:seconds
|
||||
function getFormattedTime(seconds) {
|
||||
let minutes = Math.floor(seconds / 60);
|
||||
let secondsDisplay = Math.round(seconds - minutes * 60);
|
||||
if (secondsDisplay < 10) {
|
||||
//add a zero
|
||||
secondsDisplay = "0" + secondsDisplay;
|
||||
}
|
||||
|
||||
let formatted = minutes+ ":" + secondsDisplay;
|
||||
|
||||
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) {
|
||||
let xmlhttp = new XMLHttpRequest();
|
||||
|
||||
xmlhttp.open(type, fullAddress, true);
|
||||
|
||||
if (callback != undefined) {
|
||||
xmlhttp.onreadystatechange = function () {
|
||||
callback(xmlhttp, false);
|
||||
};
|
||||
|
||||
xmlhttp.onerror = function(ev) {
|
||||
callback(xmlhttp, true);
|
||||
};
|
||||
}
|
||||
|
||||
//submit this request
|
||||
xmlhttp.send();
|
||||
}
|
||||
|
||||
function getYouTubeVideoID(url) { // Returns with video id else returns false
|
||||
var regExp = /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#\&\?]*).*/;
|
||||
var match = url.match(regExp);
|
||||
return (match && match[7].length == 11) ? match[7] : false;
|
||||
}
|
||||
var id = new URL(url).searchParams.get("v");
|
||||
return (match && match[7].length == 11) ? id : false;
|
||||
}
|
||||
|
||||
64
firefox_manifest.json
Normal file
@@ -0,0 +1,64 @@
|
||||
{
|
||||
"name": "SponsorBlock - YouTube Sponsorship Blocker",
|
||||
"short_name": "SponsorBlock",
|
||||
"version": "1.0.12",
|
||||
"description": "Skip over sponsorship on YouTube videos. Report sponsors on videos you watch to save the time of others.",
|
||||
"content_scripts": [
|
||||
{
|
||||
"matches": [
|
||||
"https://*.youtube.com/*"
|
||||
],
|
||||
"js": [
|
||||
"config.js",
|
||||
"content.js"
|
||||
],
|
||||
"css": [
|
||||
"content.css",
|
||||
"./libs/Source+Sans+Pro.css"
|
||||
]
|
||||
}
|
||||
],
|
||||
"web_accessible_resources": [
|
||||
"icons/LogoSponsorBlocker256px.png",
|
||||
"icons/IconSponsorBlocker256px.png",
|
||||
"icons/PlayerStartIconSponsorBlocker256px.png",
|
||||
"icons/PlayerStopIconSponsorBlocker256px.png",
|
||||
"icons/PlayerUploadIconSponsorBlocker256px.png",
|
||||
"icons/PlayerUploadFailedIconSponsorBlocker256px.png",
|
||||
"icons/upvote.png",
|
||||
"icons/downvote.png",
|
||||
"icons/PlayerInfoIconSponsorBlocker256px.png",
|
||||
"icons/PlayerDeleteIconSponsorBlocker256px.png",
|
||||
"popup.html"
|
||||
],
|
||||
"permissions": [
|
||||
"tabs",
|
||||
"storage",
|
||||
"notifications",
|
||||
"https://sponsor.ajay.app/*"
|
||||
],
|
||||
"browser_action": {
|
||||
"default_title": "SponsorBlock",
|
||||
"default_popup": "popup.html"
|
||||
},
|
||||
"background": {
|
||||
"scripts":[
|
||||
"config.js",
|
||||
"background.js"
|
||||
]
|
||||
},
|
||||
"icons": {
|
||||
"16": "icons/IconSponsorBlocker16px.png",
|
||||
"32": "icons/IconSponsorBlocker32px.png",
|
||||
"64": "icons/LogoSponsorBlocker64px.png",
|
||||
"128": "icons/LogoSponsorBlocker128px.png",
|
||||
"256": "icons/LogoSponsorBlocker256px.png"
|
||||
},
|
||||
"browser_specific_settings": {
|
||||
"gecko": {
|
||||
"id": "sponsorBlocker@ajay.app",
|
||||
"strict_min_version": "57.0"
|
||||
}
|
||||
},
|
||||
"manifest_version": 2
|
||||
}
|
||||
|
Before Width: | Height: | Size: 8.2 KiB After Width: | Height: | Size: 9.1 KiB |
|
Before Width: | Height: | Size: 9.8 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.3 KiB |
BIN
icons/PlayerDeleteIconSponsorBlocker256px.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
icons/PlayerInfoIconSponsorBlocker256px.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
icons/PlayerUploadFailedIconSponsorBlocker256px.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
icons/PlayerUploadIconSponsorBlocker256px.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
@@ -1,7 +1,8 @@
|
||||
{
|
||||
"name": "YTSponsorSkip",
|
||||
"version": "1.0",
|
||||
"description": "Skip youtube video sponsors.",
|
||||
"name": "SponsorBlock for YouTube - Skip Sponsorships",
|
||||
"short_name": "SponsorBlock",
|
||||
"version": "1.0.16",
|
||||
"description": "Skip over sponsorship on YouTube videos. Report sponsors on videos you watch to save the time of others.",
|
||||
"content_scripts": [
|
||||
{
|
||||
"matches": [
|
||||
@@ -22,13 +23,19 @@
|
||||
"icons/IconSponsorBlocker256px.png",
|
||||
"icons/PlayerStartIconSponsorBlocker256px.png",
|
||||
"icons/PlayerStopIconSponsorBlocker256px.png",
|
||||
"icons/PlayerUploadIconSponsorBlocker256px.png",
|
||||
"icons/PlayerUploadFailedIconSponsorBlocker256px.png",
|
||||
"icons/upvote.png",
|
||||
"icons/downvote.png"
|
||||
"icons/downvote.png",
|
||||
"icons/PlayerInfoIconSponsorBlocker256px.png",
|
||||
"icons/PlayerDeleteIconSponsorBlocker256px.png",
|
||||
"popup.html"
|
||||
],
|
||||
"permissions": [
|
||||
"tabs",
|
||||
"storage",
|
||||
"notifications"
|
||||
"notifications",
|
||||
"https://sponsor.ajay.app/*"
|
||||
],
|
||||
"browser_action": {
|
||||
"default_title": "SponsorBlock",
|
||||
|
||||
37
popup.css
@@ -8,10 +8,45 @@ h1 {
|
||||
|
||||
body {
|
||||
font-size: 14px;
|
||||
width: 300px;
|
||||
min-width: 300px;
|
||||
background-color: #ffd9d9;
|
||||
}
|
||||
|
||||
.recordingSubtitle {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.voteButton {
|
||||
height: 32px;
|
||||
margin-right: 15px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.voteButton:hover {
|
||||
filter: brightness(80%);
|
||||
}
|
||||
|
||||
#discordButtonContainer {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.sponsorTime {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.smallLink {
|
||||
font-size: 10px;
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mediumLink {
|
||||
font-size: 15px;
|
||||
padding-left: 15px;
|
||||
padding-right: 15px;
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.greenButton {
|
||||
background-color:#ec1c1c;
|
||||
-moz-border-radius:28px;
|
||||
|
||||
119
popup.html
@@ -24,8 +24,44 @@
|
||||
<div id="downloadedSponsorMessageTimes">
|
||||
|
||||
</div>
|
||||
|
||||
<h2>Record the times of a sponsorship</h2>
|
||||
|
||||
<br/>
|
||||
|
||||
<button id="reportAnIssue" class="dangerButton">Vote On A Sponsor Time</button>
|
||||
|
||||
<div id="issueReporterContainer" style="display: none">
|
||||
|
||||
<h3 style="margin-top: 0px">Vote On A Sponsor Time</h3>
|
||||
|
||||
<div id="issueReporterTimeButtons">
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<h2 class="recordingSubtitle">Record the times of a sponsorship</h2>
|
||||
|
||||
<p>
|
||||
<span id=sponsorTimesContributionsContainer style="display: none">
|
||||
So far, you've submitted
|
||||
<span id="sponsorTimesContributionsDisplay">
|
||||
0
|
||||
</span>
|
||||
<span id="sponsorTimesContributionsDisplayEndWord">
|
||||
sponsors.
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<span id=sponsorTimesViewsContainer style="display: none">
|
||||
You have saved people from
|
||||
<span id="sponsorTimesViewsDisplay">
|
||||
0
|
||||
</span>
|
||||
<span id="sponsorTimesViewsDisplayEndWord">
|
||||
sponsor segments.
|
||||
</span>
|
||||
</span>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Click the button below when the sponsorship starts and ends to record and
|
||||
@@ -35,7 +71,9 @@
|
||||
<div>
|
||||
<button id="sponsorStart" class="greenButton">Sponsorship Starts Now</button>
|
||||
</div>
|
||||
|
||||
|
||||
<sub>Hint: Press the semicolon key while focused on a video report the start/end of a sponsor and quote to submit.</sub>
|
||||
|
||||
<div id="submissionSection" style="display: none">
|
||||
<h3>Latest Sponsor Message Times Chosen</h3>
|
||||
<b>
|
||||
@@ -48,8 +86,32 @@
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
<div id="submitTimesContainer" style="display: none">
|
||||
<button id="submitTimes" class="smallButton">Submit Times</button>
|
||||
|
||||
<div id="submitTimesInfoMessageContainer" style="display: none">
|
||||
<h3 id="submitTimesInfoMessage">
|
||||
|
||||
</h3>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<button id="submitTimes" style="display: none" class="smallButton">Submit Times</button>
|
||||
</div>
|
||||
|
||||
<div id="discordButtonContainer" style="display: none">
|
||||
<br/>
|
||||
|
||||
<a href="https://discord.gg/QnmVMpU" target="_blank"><img src="https://www.logolynx.com/images/logolynx/1b/1bcc0f0aefe71b2c8ce66ffe8645d365.png" height="32px"/></a>
|
||||
|
||||
<br/>
|
||||
|
||||
Come join the official discord server to give suggestions and feedback!
|
||||
|
||||
<br/>
|
||||
|
||||
<span id="hideDiscordButton" class="smallLink">Hide this</span>
|
||||
</div>
|
||||
|
||||
<div id="optionsButtonContainer">
|
||||
@@ -64,16 +126,59 @@
|
||||
|
||||
<h3>Options</h3>
|
||||
|
||||
<button id="hideVideoPlayerControls" class="warningButton">Hide Button On YouTube Player</button>
|
||||
<button id="showVideoPlayerControls" style="display: none" class="warningButton">Show Button On YouTube Player</button>
|
||||
<button id="hideVideoPlayerControls" class="warningButton">Hide Buttons On YouTube Player</button>
|
||||
<button id="showVideoPlayerControls" style="display: none" class="warningButton">Show Buttons On YouTube Player</button>
|
||||
<br/>
|
||||
<sub>
|
||||
This hides the buttons that appear on the YouTube player to submit sponsors. I can see this being annoying for some
|
||||
people. Instead of using the button there, this popup can be used to submit sponsors. To hide the notice that appears,
|
||||
use the button that appears on the notice saying "Don't show this again". You can always enable these settings again
|
||||
later.
|
||||
</sub>
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
<button id="hideInfoButtonPlayerControls" class="warningButton">Hide Info Button On YouTube Player</button>
|
||||
<button id="showInfoButtonPlayerControls" style="display: none" class="warningButton">Show Info Button On YouTube Player</button>
|
||||
<br/>
|
||||
<sub>
|
||||
This is the button that opens up a popup in the YouTube page.
|
||||
</sub>
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
<button id="hideDeleteButtonPlayerControls" class="warningButton">Hide Delete Button On YouTube Player</button>
|
||||
<button id="showDeleteButtonPlayerControls" style="display: none" class="warningButton">Show Delete Button On YouTube Player</button>
|
||||
<br/>
|
||||
<sub>
|
||||
This is the button that allows you to clear all sponsors on the YouTube player.
|
||||
</sub>
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
<button id="disableSponsorViewTracking" class="warningButton">Disable Sponsor View Tracking</button>
|
||||
<button id="enableSponsorViewTracking" style="display: none" class="warningButton">Enable Sponsor View Tracking</button>
|
||||
<br/>
|
||||
<sub>
|
||||
This feature tracks which sponsors you have skipped to let users know how much their submission has helped others and
|
||||
used as a metric along with upvotes to ensure that spam doesn't get into the database. The extension sends a message
|
||||
to the server each time you skip a sponsor. Hopefully most people don't change this setting so that the view numbers
|
||||
are accurate. :)
|
||||
</sub>
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
|
||||
<button id="showNoticeAgain" style="display: none" class="dangerButton">Show Notice Again</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</center>
|
||||
|
||||
<!-- Scripts that need to load after the html -->
|
||||
<script src="config.js"></script>
|
||||
<script src="popup.js"></script>
|
||||
</html>
|
||||
721
popup.js
@@ -1,11 +1,50 @@
|
||||
|
||||
// References
|
||||
var SB = {};
|
||||
|
||||
SB.sponsorStart = document.getElementById("sponsorStart");
|
||||
SB.clearTimes = document.getElementById("clearTimes");
|
||||
SB.submitTimes = document.getElementById("submitTimes");
|
||||
SB.showNoticeAgain = document.getElementById("showNoticeAgain");
|
||||
SB.hideVideoPlayerControls = document.getElementById("hideVideoPlayerControls");
|
||||
SB.showVideoPlayerControls = document.getElementById("showVideoPlayerControls");
|
||||
SB.hideInfoButtonPlayerControls = document.getElementById("hideInfoButtonPlayerControls");
|
||||
SB.showInfoButtonPlayerControls = document.getElementById("showInfoButtonPlayerControls");
|
||||
SB.hideDeleteButtonPlayerControls = document.getElementById("hideDeleteButtonPlayerControls");
|
||||
SB.showDeleteButtonPlayerControls = document.getElementById("showDeleteButtonPlayerControls");
|
||||
SB.disableSponsorViewTracking = document.getElementById("disableSponsorViewTracking");
|
||||
SB.enableSponsorViewTracking = document.getElementById("enableSponsorViewTracking");
|
||||
SB.optionsButton = document.getElementById("optionsButton");
|
||||
SB.reportAnIssue = document.getElementById("reportAnIssue");
|
||||
// sponsorTimesContributions
|
||||
SB.sponsorTimesContributionsContainer = document.getElementById("sponsorTimesContributionsContainer");
|
||||
SB.sponsorTimesContributionsDisplay = document.getElementById("sponsorTimesContributionsDisplay");
|
||||
SB.sponsorTimesContributionsDisplayEndWord = document.getElementById("sponsorTimesContributionsDisplayEndWord");
|
||||
// sponsorTimesViewsDisplay
|
||||
SB.sponsorTimesViewsContainer = document.getElementById("sponsorTimesViewsDisplayContainer");
|
||||
SB.sponsorTimesViewsDisplay = document.getElementById("sponsorTimesViewsDisplayDisplay");
|
||||
SB.sponsorTimesViewsDisplayEndWord = document.getElementById("sponsorTimesViewsDisplayDisplayEndWord");
|
||||
// discordButtons
|
||||
SB.discordButtonContainer = document.getElementById("discordButtonContainer");
|
||||
SB.hideDiscordButton = document.getElementById("hideDiscordButton");
|
||||
|
||||
//setup click listeners
|
||||
document.getElementById("sponsorStart").addEventListener("click", sendSponsorStartMessage);
|
||||
document.getElementById("clearTimes").addEventListener("click", clearTimes);
|
||||
document.getElementById("submitTimes").addEventListener("click", submitTimes);
|
||||
document.getElementById("showNoticeAgain").addEventListener("click", showNoticeAgain);
|
||||
document.getElementById("hideVideoPlayerControls").addEventListener("click", hideVideoPlayerControls);
|
||||
document.getElementById("showVideoPlayerControls").addEventListener("click", showVideoPlayerControls);
|
||||
document.getElementById("optionsButton").addEventListener("click", openOptions);
|
||||
SB.sponsorStart.addEventListener("click", sendSponsorStartMessage);
|
||||
SB.clearTimes.addEventListener("click", clearTimes);
|
||||
SB.submitTimes.addEventListener("click", submitTimes);
|
||||
SB.showNoticeAgain.addEventListener("click", showNoticeAgain);
|
||||
SB.hideVideoPlayerControls.addEventListener("click", hideVideoPlayerControls);
|
||||
SB.showVideoPlayerControls.addEventListener("click", showVideoPlayerControls);
|
||||
SB.hideInfoButtonPlayerControls.addEventListener("click", hideInfoButtonPlayerControls);
|
||||
SB.showInfoButtonPlayerControls.addEventListener("click", showInfoButtonPlayerControls);
|
||||
SB.hideDeleteButtonPlayerControls.addEventListener("click", hideDeleteButtonPlayerControls);
|
||||
SB.showDeleteButtonPlayerControls.addEventListener("click", showDeleteButtonPlayerControls);
|
||||
SB.disableSponsorViewTracking.addEventListener("click", disableSponsorViewTracking);
|
||||
SB.enableSponsorViewTracking.addEventListener("click", enableSponsorViewTracking);
|
||||
SB.optionsButton.addEventListener("click", openOptions);
|
||||
SB.reportAnIssue.addEventListener("click", reportAnIssue);
|
||||
SB.hideDiscordButton.addEventListener("click", hideDiscordButton);
|
||||
|
||||
|
||||
//if true, the button now selects the end time
|
||||
var startTimeChosen = false;
|
||||
@@ -19,24 +58,104 @@ var currentVideoID = null;
|
||||
//is this a YouTube tab?
|
||||
var isYouTubeTab = false;
|
||||
|
||||
//if the don't show notice again variable is true, an option to
|
||||
// disable should be available
|
||||
chrome.storage.local.get(["dontShowNoticeAgain"], function(result) {
|
||||
let dontShowNoticeAgain = result.dontShowNoticeAgain;
|
||||
if (dontShowNoticeAgain != undefined && dontShowNoticeAgain) {
|
||||
document.getElementById("showNoticeAgain").style.display = "unset";
|
||||
//see if discord link can be shown
|
||||
chrome.storage.sync.get(["hideDiscordLink"], function(result) {
|
||||
let hideDiscordLink = result.hideDiscordLink;
|
||||
if (hideDiscordLink == undefined || !hideDiscordLink) {
|
||||
chrome.storage.sync.get(["hideDiscordLaunches"], function(result) {
|
||||
let hideDiscordLaunches = result.hideDiscordLaunches;
|
||||
//only if less than 5 launches
|
||||
if (hideDiscordLaunches == undefined || hideDiscordLaunches < 10) {
|
||||
SB.discordButtonContainer.style.display = null;
|
||||
|
||||
if (hideDiscordLaunches == undefined) {
|
||||
hideDiscordButton = 1;
|
||||
}
|
||||
|
||||
chrome.storage.sync.set({"hideDiscordLaunches": hideDiscordButton + 1});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
//show proper video player controls option
|
||||
chrome.storage.local.get(["hideVideoPlayerControls"], function(result) {
|
||||
let hideVideoPlayerControls = result.hideVideoPlayerControls;
|
||||
if (hideVideoPlayerControls != undefined && hideVideoPlayerControls) {
|
||||
document.getElementById("hideVideoPlayerControls").style.display = "none";
|
||||
document.getElementById("showVideoPlayerControls").style.display = "unset";
|
||||
//if the don't show notice again variable is true, an option to
|
||||
// disable should be available
|
||||
chrome.storage.sync.get(["dontShowNoticeAgain"], function(result) {
|
||||
let dontShowNoticeAgain = result.dontShowNoticeAgain;
|
||||
if (dontShowNoticeAgain != undefined && dontShowNoticeAgain) {
|
||||
SB.showNoticeAgain.style.display = "unset";
|
||||
}
|
||||
});
|
||||
|
||||
//show proper video player controls options
|
||||
chrome.storage.sync.get(["hideVideoPlayerControls"], function(result) {
|
||||
let hideVideoPlayerControls = result.hideVideoPlayerControls;
|
||||
if (hideVideoPlayerControls != undefined && hideVideoPlayerControls) {
|
||||
SB.hideVideoPlayerControls.style.display = "none";
|
||||
SB.showVideoPlayerControls.style.display = "unset";
|
||||
}
|
||||
});
|
||||
chrome.storage.sync.get(["hideInfoButtonPlayerControls"], function(result) {
|
||||
let hideInfoButtonPlayerControls = result.hideInfoButtonPlayerControls;
|
||||
if (hideInfoButtonPlayerControls != undefined && hideInfoButtonPlayerControls) {
|
||||
SB.hideInfoButtonPlayerControls.style.display = "none";
|
||||
SB.showInfoButtonPlayerControls.style.display = "unset";
|
||||
}
|
||||
});
|
||||
chrome.storage.sync.get(["hideDeleteButtonPlayerControls"], function(result) {
|
||||
let hideDeleteButtonPlayerControls = result.hideDeleteButtonPlayerControls;
|
||||
if (hideDeleteButtonPlayerControls != undefined && hideDeleteButtonPlayerControls) {
|
||||
SB.hideDeleteButtonPlayerControls.style.display = "none";
|
||||
SB.showDeleteButtonPlayerControls.style.display = "unset";
|
||||
}
|
||||
});
|
||||
|
||||
//show proper tracking option
|
||||
chrome.storage.sync.get(["trackViewCount"], function(result) {
|
||||
let trackViewCount = result.trackViewCount;
|
||||
if (trackViewCount != undefined && !trackViewCount) {
|
||||
SB.disableSponsorViewTracking.style.display = "none";
|
||||
SB.enableSponsorViewTracking.style.display = "unset";
|
||||
}
|
||||
});
|
||||
|
||||
//get the amount of times this user has contributed and display it to thank them
|
||||
chrome.storage.sync.get(["sponsorTimesContributed"], function(result) {
|
||||
if (result.sponsorTimesContributed != undefined) {
|
||||
if (result.sponsorTimesContributed > 1) {
|
||||
SB.sponsorTimesContributionsDisplayEndWord.innerText = "sponsors."
|
||||
} else {
|
||||
SB.sponsorTimesContributionsDisplayEndWord.innerText = "sponsor."
|
||||
}
|
||||
SB.sponsorTimesContributionsDisplay.innerText = result.sponsorTimesContributed;
|
||||
SB.sponsorTimesContributionsContainer.style.display = "unset";
|
||||
|
||||
//get the userID
|
||||
chrome.storage.sync.get(["userID"], function(result) {
|
||||
let userID = result.userID;
|
||||
if (userID != undefined) {
|
||||
//there are probably some views on these submissions then
|
||||
//get the amount of views from the sponsors submitted
|
||||
sendRequestToServer("GET", "/api/getViewsForUser?userID=" + userID, function(xmlhttp) {
|
||||
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
|
||||
let viewCount = JSON.parse(xmlhttp.responseText).viewCount;
|
||||
if (viewCount != 0) {
|
||||
if (viewCount > 1) {
|
||||
SB.sponsorTimesViewsDisplayEndWord.innerText = "sponsor segments."
|
||||
} else {
|
||||
SB.sponsorTimesViewsDisplayEndWord.innerText = "sponsor segment."
|
||||
}
|
||||
SB.sponsorTimesViewsDisplay.innerText = viewCount;
|
||||
SB.sponsorTimesViewsContainer.style.display = "unset";
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
chrome.tabs.query({
|
||||
active: true,
|
||||
currentWindow: true
|
||||
@@ -54,12 +173,12 @@ function loadTabData(tabs) {
|
||||
|
||||
//load video times for this video
|
||||
let sponsorTimeKey = "sponsorTimes" + currentVideoID;
|
||||
chrome.storage.local.get([sponsorTimeKey], function(result) {
|
||||
chrome.storage.sync.get([sponsorTimeKey], function(result) {
|
||||
let sponsorTimesStorage = result[sponsorTimeKey];
|
||||
if (sponsorTimesStorage != undefined && sponsorTimesStorage.length > 0) {
|
||||
if (sponsorTimesStorage[sponsorTimesStorage.length - 1] != undefined && sponsorTimesStorage[sponsorTimesStorage.length - 1].length < 2) {
|
||||
startTimeChosen = true;
|
||||
document.getElementById("sponsorStart").innerHTML = "Sponsorship Ends Now";
|
||||
SB.sponsorStart.innerHTML = "Sponsorship Ends Now";
|
||||
}
|
||||
|
||||
sponsorTimes = sponsorTimesStorage;
|
||||
@@ -123,40 +242,47 @@ function sendSponsorStartMessage() {
|
||||
}, tabs => {
|
||||
chrome.tabs.sendMessage(
|
||||
tabs[0].id,
|
||||
{from: 'popup', message: 'sponsorStart'}
|
||||
{from: 'popup', message: 'sponsorStart'},
|
||||
startSponsorCallback
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
chrome.runtime.onMessage.addListener(function (request, sender, callback) {
|
||||
if (request.message == "time") {
|
||||
let sponsorTimesIndex = sponsorTimes.length - (startTimeChosen ? 1 : 0);
|
||||
function startSponsorCallback(response) {
|
||||
let sponsorTimesIndex = sponsorTimes.length - (startTimeChosen ? 1 : 0);
|
||||
|
||||
if (sponsorTimes[sponsorTimesIndex] == undefined) {
|
||||
sponsorTimes[sponsorTimesIndex] = [];
|
||||
}
|
||||
|
||||
sponsorTimes[sponsorTimesIndex][startTimeChosen ? 1 : 0] = request.time;
|
||||
|
||||
let sponsorTimeKey = "sponsorTimes" + currentVideoID;
|
||||
chrome.storage.local.set({[sponsorTimeKey]: sponsorTimes});
|
||||
|
||||
updateStartTimeChosen();
|
||||
|
||||
//display video times on screen
|
||||
displaySponsorTimes();
|
||||
|
||||
//show submission section
|
||||
document.getElementById("submissionSection").style.display = "unset";
|
||||
|
||||
showSubmitTimesIfNecessary();
|
||||
if (sponsorTimes[sponsorTimesIndex] == undefined) {
|
||||
sponsorTimes[sponsorTimesIndex] = [];
|
||||
}
|
||||
});
|
||||
|
||||
sponsorTimes[sponsorTimesIndex][startTimeChosen ? 1 : 0] = response.time;
|
||||
|
||||
let sponsorTimeKey = "sponsorTimes" + currentVideoID;
|
||||
chrome.storage.sync.set({[sponsorTimeKey]: sponsorTimes});
|
||||
|
||||
updateStartTimeChosen();
|
||||
|
||||
//display video times on screen
|
||||
displaySponsorTimes();
|
||||
|
||||
//show submission section
|
||||
document.getElementById("submissionSection").style.display = "unset";
|
||||
|
||||
showSubmitTimesIfNecessary();
|
||||
}
|
||||
|
||||
//display the video times from the array
|
||||
function displaySponsorTimes() {
|
||||
//set it to the message
|
||||
document.getElementById("sponsorMessageTimes").innerHTML = getSponsorTimesMessage(sponsorTimes);
|
||||
let sponsorMessageTimes = document.getElementById("sponsorMessageTimes");
|
||||
|
||||
//remove all children
|
||||
while (sponsorMessageTimes.firstChild) {
|
||||
sponsorMessageTimes.removeChild(sponsorMessageTimes.firstChild);
|
||||
}
|
||||
|
||||
//add sponsor times
|
||||
sponsorMessageTimes.appendChild(getSponsorTimesMessageDiv(sponsorTimes));
|
||||
}
|
||||
|
||||
//display the video times from the array at the top, in a different section
|
||||
@@ -164,6 +290,56 @@ function displayDownloadedSponsorTimes(request) {
|
||||
if (request.sponsorTimes != undefined) {
|
||||
//set it to the message
|
||||
document.getElementById("downloadedSponsorMessageTimes").innerHTML = getSponsorTimesMessage(request.sponsorTimes);
|
||||
|
||||
//add them as buttons to the issue reporting container
|
||||
let container = document.getElementById("issueReporterTimeButtons");
|
||||
for (let i = 0; i < request.sponsorTimes.length; i++) {
|
||||
let sponsorTimeButton = document.createElement("button");
|
||||
sponsorTimeButton.className = "warningButton";
|
||||
sponsorTimeButton.innerText = getFormattedTime(request.sponsorTimes[i][0]) + " to " + getFormattedTime(request.sponsorTimes[i][1]);
|
||||
|
||||
let votingButtons = document.createElement("div");
|
||||
|
||||
let UUID = request.UUIDs[i];
|
||||
|
||||
//thumbs up and down buttons
|
||||
let voteButtonsContainer = document.createElement("div");
|
||||
voteButtonsContainer.id = "sponsorTimesVoteButtonsContainer" + UUID;
|
||||
voteButtonsContainer.setAttribute("align", "center");
|
||||
voteButtonsContainer.style.display = "none"
|
||||
|
||||
let upvoteButton = document.createElement("img");
|
||||
upvoteButton.id = "sponsorTimesUpvoteButtonsContainer" + UUID;
|
||||
upvoteButton.className = "voteButton";
|
||||
upvoteButton.src = chrome.extension.getURL("icons/upvote.png");
|
||||
upvoteButton.addEventListener("click", () => vote(1, UUID));
|
||||
|
||||
let downvoteButton = document.createElement("img");
|
||||
downvoteButton.id = "sponsorTimesDownvoteButtonsContainer" + UUID;
|
||||
downvoteButton.className = "voteButton";
|
||||
downvoteButton.src = chrome.extension.getURL("icons/downvote.png");
|
||||
downvoteButton.addEventListener("click", () => vote(0, UUID));
|
||||
|
||||
//add thumbs up and down buttons to the container
|
||||
voteButtonsContainer.appendChild(document.createElement("br"));
|
||||
voteButtonsContainer.appendChild(document.createElement("br"));
|
||||
voteButtonsContainer.appendChild(upvoteButton);
|
||||
voteButtonsContainer.appendChild(downvoteButton);
|
||||
|
||||
//add click listener to open up vote panel
|
||||
sponsorTimeButton.addEventListener("click", function() {
|
||||
voteButtonsContainer.style.display = "unset";
|
||||
});
|
||||
|
||||
container.appendChild(sponsorTimeButton);
|
||||
container.appendChild(voteButtonsContainer);
|
||||
|
||||
//if it is not the last iteration
|
||||
if (i != request.sponsorTimes.length - 1) {
|
||||
container.appendChild(document.createElement("br"));
|
||||
container.appendChild(document.createElement("br"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,15 +365,207 @@ function getSponsorTimesMessage(sponsorTimes) {
|
||||
return sponsorTimesMessage;
|
||||
}
|
||||
|
||||
function clearTimes() {
|
||||
//check if the player controls should be toggled
|
||||
if (sponsorTimes.length > 0 && sponsorTimes[sponsorTimes.length - 1].length < 2) {
|
||||
//get the message that visually displays the video times
|
||||
//this version is a div that contains each with delete buttons
|
||||
function getSponsorTimesMessageDiv(sponsorTimes) {
|
||||
// let sponsorTimesMessage = "";
|
||||
let sponsorTimesContainer = document.createElement("div");
|
||||
sponsorTimesContainer.id = "sponsorTimesContainer";
|
||||
|
||||
for (let i = 0; i < sponsorTimes.length; i++) {
|
||||
let currentSponsorTimeContainer = document.createElement("div");
|
||||
currentSponsorTimeContainer.id = "sponsorTimeContainer" + i;
|
||||
currentSponsorTimeContainer.className = "sponsorTime";
|
||||
let currentSponsorTimeMessage = "";
|
||||
|
||||
let deleteButton = document.createElement("span");
|
||||
deleteButton.id = "sponsorTimeDeleteButton" + i;
|
||||
deleteButton.innerText = "Delete";
|
||||
deleteButton.className = "mediumLink";
|
||||
let index = i;
|
||||
deleteButton.addEventListener("click", () => deleteSponsorTime(index));
|
||||
|
||||
let spacer = document.createElement("span");
|
||||
spacer.innerText = " ";
|
||||
|
||||
let editButton = document.createElement("span");
|
||||
editButton.id = "sponsorTimeEditButton" + i;
|
||||
editButton.innerText = "Edit";
|
||||
editButton.className = "mediumLink";
|
||||
editButton.addEventListener("click", () => editSponsorTime(index));
|
||||
|
||||
for (let s = 0; s < sponsorTimes[i].length; s++) {
|
||||
let timeMessage = getFormattedTime(sponsorTimes[i][s]);
|
||||
//if this is an end time
|
||||
if (s == 1) {
|
||||
timeMessage = " to " + timeMessage;
|
||||
} else if (i > 0) {
|
||||
//add commas if necessary
|
||||
timeMessage = timeMessage;
|
||||
}
|
||||
|
||||
currentSponsorTimeMessage += timeMessage;
|
||||
}
|
||||
|
||||
currentSponsorTimeContainer.innerText = currentSponsorTimeMessage;
|
||||
currentSponsorTimeContainer.addEventListener("click", () => editSponsorTime(index));
|
||||
|
||||
sponsorTimesContainer.appendChild(currentSponsorTimeContainer);
|
||||
sponsorTimesContainer.appendChild(deleteButton);
|
||||
|
||||
//only if it is a complete sponsor time
|
||||
if (sponsorTimes[i].length > 1) {
|
||||
sponsorTimesContainer.appendChild(editButton);
|
||||
}
|
||||
}
|
||||
|
||||
return sponsorTimesContainer;
|
||||
}
|
||||
|
||||
function editSponsorTime(index) {
|
||||
if (document.getElementById("startTimeMinutes" + index) != null) {
|
||||
//already open
|
||||
return;
|
||||
}
|
||||
|
||||
let sponsorTimeContainer = document.getElementById("sponsorTimeContainer" + index);
|
||||
|
||||
//get sponsor time minutes and seconds boxes
|
||||
let startTimeMinutes = document.createElement("input");
|
||||
startTimeMinutes.id = "startTimeMinutes" + index;
|
||||
startTimeMinutes.className = "sponsorTime";
|
||||
startTimeMinutes.type = "text";
|
||||
startTimeMinutes.value = getTimeInMinutes(sponsorTimes[index][0]);
|
||||
startTimeMinutes.style.width = "45";
|
||||
|
||||
let startTimeSeconds = document.createElement("input");
|
||||
startTimeSeconds.id = "startTimeSeconds" + index;
|
||||
startTimeSeconds.className = "sponsorTime";
|
||||
startTimeSeconds.type = "text";
|
||||
startTimeSeconds.value = getTimeInFormattedSeconds(sponsorTimes[index][0]);
|
||||
startTimeSeconds.style.width = "60";
|
||||
|
||||
let endTimeMinutes = document.createElement("input");
|
||||
endTimeMinutes.id = "endTimeMinutes" + index;
|
||||
endTimeMinutes.className = "sponsorTime";
|
||||
endTimeMinutes.type = "text";
|
||||
endTimeMinutes.value = getTimeInMinutes(sponsorTimes[index][1]);
|
||||
endTimeMinutes.style.width = "45";
|
||||
|
||||
let endTimeSeconds = document.createElement("input");
|
||||
endTimeSeconds.id = "endTimeSeconds" + index;
|
||||
endTimeSeconds.className = "sponsorTime";
|
||||
endTimeSeconds.type = "text";
|
||||
endTimeSeconds.value = getTimeInFormattedSeconds(sponsorTimes[index][1]);
|
||||
endTimeSeconds.style.width = "60";
|
||||
|
||||
let colonText = document.createElement("span");
|
||||
colonText.innerText = ":";
|
||||
|
||||
let toText = document.createElement("span");
|
||||
toText.innerText = " to ";
|
||||
|
||||
//remove all children to replace
|
||||
while (sponsorTimeContainer.firstChild) {
|
||||
sponsorTimeContainer.removeChild(sponsorTimeContainer.firstChild);
|
||||
}
|
||||
|
||||
sponsorTimeContainer.appendChild(startTimeMinutes);
|
||||
sponsorTimeContainer.appendChild(colonText);
|
||||
sponsorTimeContainer.appendChild(startTimeSeconds);
|
||||
sponsorTimeContainer.appendChild(toText);
|
||||
sponsorTimeContainer.appendChild(endTimeMinutes);
|
||||
sponsorTimeContainer.appendChild(colonText);
|
||||
sponsorTimeContainer.appendChild(endTimeSeconds);
|
||||
|
||||
//add save button and remove edit button
|
||||
let saveButton = document.createElement("span");
|
||||
saveButton.id = "sponsorTimeSaveButton" + index;
|
||||
saveButton.innerText = "Save";
|
||||
saveButton.className = "mediumLink";
|
||||
saveButton.addEventListener("click", () => saveSponsorTimeEdit(index));
|
||||
|
||||
let editButton = document.getElementById("sponsorTimeEditButton" + index);
|
||||
let sponsorTimesContainer = document.getElementById("sponsorTimesContainer");
|
||||
|
||||
sponsorTimesContainer.removeChild(editButton);
|
||||
sponsorTimesContainer.appendChild(saveButton);
|
||||
}
|
||||
|
||||
function saveSponsorTimeEdit(index) {
|
||||
let startTimeMinutes = document.getElementById("startTimeMinutes" + index);
|
||||
let startTimeSeconds = document.getElementById("startTimeSeconds" + index);
|
||||
|
||||
let endTimeMinutes = document.getElementById("endTimeMinutes" + index);
|
||||
let endTimeSeconds = document.getElementById("endTimeSeconds" + index);
|
||||
|
||||
sponsorTimes[index][0] = parseInt(startTimeMinutes.value) * 60 + parseFloat(startTimeSeconds.value);
|
||||
sponsorTimes[index][1] = parseInt(endTimeMinutes.value) * 60 + parseFloat(endTimeSeconds.value);
|
||||
|
||||
//save this
|
||||
let sponsorTimeKey = "sponsorTimes" + currentVideoID;
|
||||
chrome.storage.sync.set({[sponsorTimeKey]: sponsorTimes});
|
||||
|
||||
displaySponsorTimes();
|
||||
}
|
||||
|
||||
//deletes the sponsor time submitted at an index
|
||||
function deleteSponsorTime(index) {
|
||||
//if it is not a complete sponsor time
|
||||
if (sponsorTimes[index].length < 2) {
|
||||
chrome.tabs.query({
|
||||
active: true,
|
||||
currentWindow: true
|
||||
}, function(tabs) {
|
||||
chrome.tabs.sendMessage(tabs[0].id, {
|
||||
message: "toggleStartSponsorButton"
|
||||
message: "changeStartSponsorButton",
|
||||
showStartSponsor: true,
|
||||
uploadButtonVisible: false
|
||||
});
|
||||
});
|
||||
|
||||
resetStartTimeChosen();
|
||||
}
|
||||
|
||||
sponsorTimes.splice(index, 1);
|
||||
|
||||
//save this
|
||||
let sponsorTimeKey = "sponsorTimes" + currentVideoID;
|
||||
chrome.storage.sync.set({[sponsorTimeKey]: sponsorTimes});
|
||||
|
||||
//update display
|
||||
displaySponsorTimes();
|
||||
|
||||
//if they are all removed
|
||||
if (sponsorTimes.length == 0) {
|
||||
//update chrome tab
|
||||
chrome.tabs.query({
|
||||
active: true,
|
||||
currentWindow: true
|
||||
}, function(tabs) {
|
||||
chrome.tabs.sendMessage(tabs[0].id, {
|
||||
message: "changeStartSponsorButton",
|
||||
showStartSponsor: true,
|
||||
uploadButtonVisible: false
|
||||
});
|
||||
});
|
||||
|
||||
//hide submission section
|
||||
document.getElementById("submissionSection").style.display = "none";
|
||||
}
|
||||
}
|
||||
|
||||
function clearTimes() {
|
||||
//send new sponsor time state to tab
|
||||
if (sponsorTimes.length > 0) {
|
||||
chrome.tabs.query({
|
||||
active: true,
|
||||
currentWindow: true
|
||||
}, function(tabs) {
|
||||
chrome.tabs.sendMessage(tabs[0].id, {
|
||||
message: "changeStartSponsorButton",
|
||||
showStartSponsor: true,
|
||||
uploadButtonVisible: false
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -206,7 +574,7 @@ function clearTimes() {
|
||||
sponsorTimes = [];
|
||||
|
||||
let sponsorTimeKey = "sponsorTimes" + currentVideoID;
|
||||
chrome.storage.local.set({[sponsorTimeKey]: sponsorTimes});
|
||||
chrome.storage.sync.set({[sponsorTimeKey]: sponsorTimes});
|
||||
|
||||
displaySponsorTimes();
|
||||
|
||||
@@ -217,18 +585,44 @@ function clearTimes() {
|
||||
}
|
||||
|
||||
function submitTimes() {
|
||||
//make info message say loading
|
||||
document.getElementById("submitTimesInfoMessage").innerText = "Loading...";
|
||||
document.getElementById("submitTimesInfoMessageContainer").style.display = "unset";
|
||||
|
||||
if (sponsorTimes.length > 0) {
|
||||
chrome.runtime.sendMessage({
|
||||
message: "submitTimes",
|
||||
videoID: currentVideoID
|
||||
}, function(request) {
|
||||
clearTimes();
|
||||
}, function(response) {
|
||||
if (response != undefined) {
|
||||
if (response.statusCode == 200) {
|
||||
//hide loading message
|
||||
document.getElementById("submitTimesInfoMessageContainer").style.display = "none";
|
||||
|
||||
clearTimes();
|
||||
} else if(response.statusCode == 400) {
|
||||
document.getElementById("submitTimesInfoMessage").innerText = "Server said this request was invalid";
|
||||
document.getElementById("submitTimesInfoMessageContainer").style.display = "unset";
|
||||
} else if(response.statusCode == 429) {
|
||||
document.getElementById("submitTimesInfoMessage").innerText = "You have submitted too many sponsor times for this one video, are you sure there are this many?";
|
||||
document.getElementById("submitTimesInfoMessageContainer").style.display = "unset";
|
||||
} else if(response.statusCode == 409) {
|
||||
document.getElementById("submitTimesInfoMessage").innerText = "This has already been submitted before";
|
||||
document.getElementById("submitTimesInfoMessageContainer").style.display = "unset";
|
||||
} else if(response.statusCode == 502) {
|
||||
document.getElementById("submitTimesInfoMessage").innerText = "It seems the server is down. Contact the dev to inform them. Error code " + response.statusCode;
|
||||
document.getElementById("submitTimesInfoMessageContainer").style.display = "unset";
|
||||
} else {
|
||||
document.getElementById("submitTimesInfoMessage").innerText = "There was an error submitting your sponsor times, please try again later. Error code " + response.statusCode;
|
||||
document.getElementById("submitTimesInfoMessageContainer").style.display = "unset";
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function showNoticeAgain() {
|
||||
chrome.storage.local.set({"dontShowNoticeAgain": false});
|
||||
chrome.storage.sync.set({"dontShowNoticeAgain": false});
|
||||
|
||||
chrome.tabs.query({
|
||||
active: true,
|
||||
@@ -239,11 +633,11 @@ function showNoticeAgain() {
|
||||
});
|
||||
});
|
||||
|
||||
document.getElementById("showNoticeAgain").style.display = "none";
|
||||
SB.showNoticeAgain.style.display = "none";
|
||||
}
|
||||
|
||||
function hideVideoPlayerControls() {
|
||||
chrome.storage.local.set({"hideVideoPlayerControls": true});
|
||||
chrome.storage.sync.set({"hideVideoPlayerControls": true});
|
||||
|
||||
chrome.tabs.query({
|
||||
active: true,
|
||||
@@ -255,12 +649,12 @@ function hideVideoPlayerControls() {
|
||||
});
|
||||
});
|
||||
|
||||
document.getElementById("hideVideoPlayerControls").style.display = "none";
|
||||
document.getElementById("showVideoPlayerControls").style.display = "unset";
|
||||
SB.hideVideoPlayerControls.style.display = "none";
|
||||
SB.showVideoPlayerControls.style.display = "unset";
|
||||
}
|
||||
|
||||
function showVideoPlayerControls() {
|
||||
chrome.storage.local.set({"hideVideoPlayerControls": false});
|
||||
chrome.storage.sync.set({"hideVideoPlayerControls": false});
|
||||
|
||||
chrome.tabs.query({
|
||||
active: true,
|
||||
@@ -272,15 +666,117 @@ function showVideoPlayerControls() {
|
||||
});
|
||||
});
|
||||
|
||||
document.getElementById("hideVideoPlayerControls").style.display = "unset";
|
||||
document.getElementById("showVideoPlayerControls").style.display = "none";
|
||||
SB.hideVideoPlayerControls.style.display = "unset";
|
||||
SB.showVideoPlayerControls.style.display = "none";
|
||||
}
|
||||
|
||||
function hideInfoButtonPlayerControls() {
|
||||
chrome.storage.sync.set({"hideInfoButtonPlayerControls": true});
|
||||
|
||||
chrome.tabs.query({
|
||||
active: true,
|
||||
currentWindow: true
|
||||
}, function(tabs) {
|
||||
chrome.tabs.sendMessage(tabs[0].id, {
|
||||
message: "changeInfoButtonPlayerControlsVisibility",
|
||||
value: true
|
||||
});
|
||||
});
|
||||
|
||||
SB.hideInfoButtonPlayerControls.style.display = "none";
|
||||
SB.showInfoButtonPlayerControls.style.display = "unset";
|
||||
}
|
||||
|
||||
function showInfoButtonPlayerControls() {
|
||||
chrome.storage.sync.set({"hideInfoButtonPlayerControls": false});
|
||||
|
||||
chrome.tabs.query({
|
||||
active: true,
|
||||
currentWindow: true
|
||||
}, function(tabs) {
|
||||
chrome.tabs.sendMessage(tabs[0].id, {
|
||||
message: "changeVideoPlayerCochangeInfoButtonPlayerControlsVisibilityntrolsVisibility",
|
||||
value: false
|
||||
});
|
||||
});
|
||||
|
||||
SB.hideInfoButtonPlayerControls.style.display = "unset";
|
||||
SB.showInfoButtonPlayerControls.style.display = "none";
|
||||
}
|
||||
|
||||
function hideDeleteButtonPlayerControls() {
|
||||
chrome.storage.sync.set({"hideDeleteButtonPlayerControls": true});
|
||||
|
||||
chrome.tabs.query({
|
||||
active: true,
|
||||
currentWindow: true
|
||||
}, function(tabs) {
|
||||
chrome.tabs.sendMessage(tabs[0].id, {
|
||||
message: "changeDeleteButtonPlayerControlsVisibility",
|
||||
value: true
|
||||
});
|
||||
});
|
||||
|
||||
SB.hideDeleteButtonPlayerControls.style.display = "none";
|
||||
SB.showDeleteButtonPlayerControls.style.display = "unset";
|
||||
}
|
||||
|
||||
function showDeleteButtonPlayerControls() {
|
||||
chrome.storage.sync.set({"hideDeleteButtonPlayerControls": false});
|
||||
|
||||
chrome.tabs.query({
|
||||
active: true,
|
||||
currentWindow: true
|
||||
}, function(tabs) {
|
||||
chrome.tabs.sendMessage(tabs[0].id, {
|
||||
message: "changeVideoPlayerCochangeDeleteButtonPlayerControlsVisibilityntrolsVisibility",
|
||||
value: false
|
||||
});
|
||||
});
|
||||
|
||||
SB.hideDeleteButtonPlayerControls.style.display = "unset";
|
||||
SB.showDeleteButtonPlayerControls.style.display = "none";
|
||||
}
|
||||
|
||||
function disableSponsorViewTracking() {
|
||||
chrome.storage.sync.set({"trackViewCount": false});
|
||||
|
||||
chrome.tabs.query({
|
||||
active: true,
|
||||
currentWindow: true
|
||||
}, function(tabs) {
|
||||
chrome.tabs.sendMessage(tabs[0].id, {
|
||||
message: "trackViewCount",
|
||||
value: false
|
||||
});
|
||||
});
|
||||
|
||||
SB.disableSponsorViewTracking.style.display = "none";
|
||||
SB.enableSponsorViewTracking.style.display = "unset";
|
||||
}
|
||||
|
||||
function enableSponsorViewTracking() {
|
||||
chrome.storage.sync.set({"trackViewCount": true});
|
||||
|
||||
chrome.tabs.query({
|
||||
active: true,
|
||||
currentWindow: true
|
||||
}, function(tabs) {
|
||||
chrome.tabs.sendMessage(tabs[0].id, {
|
||||
message: "trackViewCount",
|
||||
value: true
|
||||
});
|
||||
});
|
||||
|
||||
SB.enableSponsorViewTracking.style.display = "none";
|
||||
SB.disableSponsorViewTracking.style.display = "unset";
|
||||
}
|
||||
|
||||
function updateStartTimeChosen() {
|
||||
//update startTimeChosen variable
|
||||
if (!startTimeChosen) {
|
||||
startTimeChosen = true;
|
||||
document.getElementById("sponsorStart").innerHTML = "Sponsorship Ends Now";
|
||||
SB.sponsorStart.innerHTML = "Sponsorship Ends Now";
|
||||
} else {
|
||||
resetStartTimeChosen();
|
||||
}
|
||||
@@ -289,16 +785,18 @@ function updateStartTimeChosen() {
|
||||
//set it to false
|
||||
function resetStartTimeChosen() {
|
||||
startTimeChosen = false;
|
||||
document.getElementById("sponsorStart").innerHTML = "Sponsorship Starts Now";
|
||||
SB.sponsorStart.innerHTML = "Sponsorship Starts Now";
|
||||
}
|
||||
|
||||
//hides and shows the submit times button when needed
|
||||
function showSubmitTimesIfNecessary() {
|
||||
//check if an end time has been specified for the latest sponsor time
|
||||
if (sponsorTimes.length > 0 && sponsorTimes[sponsorTimes.length - 1].length > 1) {
|
||||
//show submit times button
|
||||
document.getElementById("submitTimes").style.display = "unset";
|
||||
document.getElementById("submitTimesContainer").style.display = "unset";
|
||||
} else {
|
||||
document.getElementById("submitTimes").style.display = "none";
|
||||
//hide submit times button
|
||||
document.getElementById("submitTimesContainer").style.display = "none";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -314,6 +812,62 @@ function displayNoVideo() {
|
||||
"If you know this is a YouTube tab, close this popup and open it again.";
|
||||
}
|
||||
|
||||
function reportAnIssue() {
|
||||
document.getElementById("issueReporterContainer").style.display = "unset";
|
||||
SB.reportAnIssue.style.display = "none";
|
||||
}
|
||||
|
||||
function addVoteMessage(message, UUID) {
|
||||
let container = document.getElementById("sponsorTimesVoteButtonsContainer" + UUID);
|
||||
//remove all children
|
||||
while (container.firstChild) {
|
||||
container.removeChild(container.firstChild);
|
||||
}
|
||||
|
||||
let thanksForVotingText = document.createElement("h2");
|
||||
thanksForVotingText.innerText = message;
|
||||
//there are already breaks there
|
||||
thanksForVotingText.style.marginBottom = "0px";
|
||||
|
||||
container.appendChild(thanksForVotingText);
|
||||
}
|
||||
|
||||
function vote(type, UUID) {
|
||||
//add loading info
|
||||
addVoteMessage("Loading...", UUID)
|
||||
|
||||
//send the vote message to the tab
|
||||
chrome.runtime.sendMessage({
|
||||
message: "submitVote",
|
||||
type: type,
|
||||
UUID: UUID
|
||||
}, function(response) {
|
||||
if (response != undefined) {
|
||||
//see if it was a success or failure
|
||||
if (response.successType == 1) {
|
||||
//success
|
||||
addVoteMessage("Thanks for voting!", UUID)
|
||||
} else if (response.successType == 0) {
|
||||
//failure: duplicate vote
|
||||
addVoteMessage("You have already voted this way before.", UUID)
|
||||
} else if (response.successType == -1) {
|
||||
if (response.statusCode == 502) {
|
||||
addVoteMessage("It seems the sever is down. Contact the dev immediately.", UUID)
|
||||
} else {
|
||||
//failure: unknown error
|
||||
addVoteMessage("A connection error has occured. Error code: " + response.statusCode, UUID)
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function hideDiscordButton() {
|
||||
chrome.storage.sync.set({"hideDiscordLink": false});
|
||||
|
||||
SB.discordButtonContainer.style.display = "none";
|
||||
}
|
||||
|
||||
//converts time in seconds to minutes:seconds
|
||||
function getFormattedTime(seconds) {
|
||||
let minutes = Math.floor(seconds / 60);
|
||||
@@ -328,8 +882,45 @@ function getFormattedTime(seconds) {
|
||||
return formatted;
|
||||
}
|
||||
|
||||
//converts time in seconds to minutes
|
||||
function getTimeInMinutes(seconds) {
|
||||
let minutes = Math.floor(seconds / 60);
|
||||
|
||||
return minutes;
|
||||
}
|
||||
|
||||
//converts time in seconds to seconds past the last minute
|
||||
function getTimeInFormattedSeconds(seconds) {
|
||||
let secondsFormatted = (seconds % 60).toFixed(3);
|
||||
|
||||
if (secondsFormatted < 10) {
|
||||
secondsFormatted = "0" + 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();
|
||||
}
|
||||
|
||||
function getYouTubeVideoID(url) { // Return video id or false
|
||||
var regExp = /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#\&\?]*).*/;
|
||||
var match = url.match(regExp);
|
||||
return (match && match[7].length == 11) ? match[7] : false;
|
||||
}
|
||||
}
|
||||
|
||||