Merge pull request #1 from ajayyy/master

Update
This commit is contained in:
Official Noob
2020-02-09 22:15:27 +00:00
committed by GitHub
10 changed files with 404 additions and 69 deletions

View File

@@ -1,7 +1,7 @@
{
"name": "__MSG_fullName__",
"short_name": "__MSG_Name__",
"version": "1.2.5",
"version": "1.2.8",
"default_locale": "en",
"description": "__MSG_Description__",
"content_scripts": [
@@ -36,7 +36,8 @@
"icons/close.png",
"icons/PlayerInfoIconSponsorBlocker256px.png",
"icons/PlayerDeleteIconSponsorBlocker256px.png",
"popup.html"
"popup.html",
"content.css"
],
"permissions": [
"storage",

View File

@@ -386,5 +386,47 @@
},
"invidiousInfo2": {
"message": "You MUST enable it in the options for it to work."
},
"minDuration": {
"message": "Minimum duration (seconds):"
},
"minDurationDescription": {
"message": "Sponsor segments shorter than the set value will not be skipeed or show in the player."
},
"shortCheck": {
"message": "The following submission is shorter than your minimum duration option. This could mean that this is already submitted, and just being ignored due to this option. Are you sure you would like to submit?"
},
"showUploadButton": {
"message": "Show Upload Button"
},
"whatUploadButton": {
"message": "This button appears on the YouTube player after you have selected a timestamp and are ready to submit."
},
"customServerAddress": {
"message": "SponsorBlock Server Address"
},
"customServerAddressDescription": {
"message": "The address SponsorBlock uses to make calls to the server.\nUnless you have your own server instance, this should not be changed."
},
"save": {
"message": "Save"
},
"reset": {
"message": "Reset"
},
"customAddressError": {
"message": "This address is not in the right form. Make sure you have http:// or https:// at the begining and no trailing slashes."
},
"areYouSureReset": {
"message": "Are you sure you would like to reset this?"
},
"confirmPrivacy": {
"message": "The video has been detected as unlisted. Click cancel if you do not want to check for sponsors."
},
"unlistedCheck": {
"message": "Ignore Unlisted Videos"
},
"whatUnlistedCheck": {
"message": "This setting will significantly slow down SponsorBlock. Sponsor lookups require sending the video ID to the server. If you are concerned about unlisted video IDs being sent over the internet, enable this option."
}
}

View File

@@ -19,7 +19,7 @@
<p class="createdBy">Created By <a href="https://ajay.app">Ajay Ramachandran</a> <img src="https://ajay.app/newprofilepic.jpg" height="30" class="profilepiccircle"/></p>
<p>
Thanks for installing SponsorBlock. Here are some quick tips for getting started. Please join the Discord if you have any questions or suggestions.
Thanks for installing SponsorBlock. Here are some quick tips for getting started. Feel free to contact me if you have any questions.
</p>
<p class="projectPreview">
@@ -30,10 +30,13 @@
Come contribute, make some suggestions and help out in the Discord: <a href="https://discord.gg/QnmVMpU">https://discord.gg/QnmVMpU</a>
</p>
<a class="bigText" href="/options/options.html">Enable Invidious Support</a>
<div class="center">
<a class="bigText" href="/options/options.html">Enable optional features</a>
</div>
<p>
Invidious is a third-party YouTube viewer. SponsorBlock now supports invidious along with YouTube. Please visit the options page to make sure everything is how you want it to be.
Some features, such as support for non third-party YouTube sites, are disabled by default and can be enabled in the options. These can be enabled or disabled at any time.
You can also hide/show all UI elements added to the YouTube page.
</p>
<h1>How skipping works</h1>
@@ -83,6 +86,7 @@
<p>
There are hotkeys if you want to use them. You must be focused on the YouTube player to use them. Press the semicolon key to indicate the start/end of a sponsor segment and click the appostrophe to submit.
These can be changed in the options. If you don't use QWERTY, you should probably change the keybinds.
</p>
<h1>I hate these buttons, they are so ugly</h1>

View File

@@ -76,6 +76,11 @@ body {
color: white;
}
.text-label-container {
font-size: 14px;
color: white;
}
.switch {
position: relative;
display: inline-block;
@@ -309,4 +314,13 @@ h1,h2,h3,h4,h5,h6 {
svg {
text-decoration: none;
}
.number-container:before {
content: attr(label-name);
padding-right: 4px;
width: max-content;
font-size: 14px;
color: white;
}

View File

@@ -41,7 +41,7 @@
<br/>
<br/>
<div option-type="text-change" sync-option="invidiousInstances">
<div option-type="private-text-change" sync-option="invidiousInstances">
<div class="option-button trigger-button">
__MSG_addInvidiousInstance__
</div>
@@ -76,7 +76,7 @@
<br/>
<br/>
<div option-type="toggle" toggle-type="reverse" sync-option="disableAutoSkip">
<label class="switch-container" label-name="__MSG_autoSkip__">
<label class="switch">
@@ -94,6 +94,7 @@
<br/>
<br/>
<div option-type="keybind-change" sync-option="startSponsorKeybind">
<div class="option-button trigger-button">
__MSG_setStartSponsorShortcut__
@@ -132,6 +133,32 @@
</span>
</div>
</div>
<br/>
<br/>
<div option-type="number-change" sync-option="minDuration">
<label class="number-container" label-name="__MSG_minDuration__">
<input type="number" step="0.1" min="0">
</label>
<br/>
<br/>
<div class="small-description">__MSG_minDurationDescription__</div>
</div>
<br/>
<br/>
<div option-type="toggle" toggle-type="reverse" sync-option="dontShowNotice">
<label class="switch-container" label-name="__MSG_showSkipNotice__">
<label class="switch">
<input type="checkbox" checked>
<span class="slider round"></span>
</label>
</label>
</div>
<br/>
<br/>
@@ -187,6 +214,23 @@
<br/>
<br/>
<div option-type="toggle" toggle-type="reverse" sync-option="hideUploadButtonPlayerControls">
<label class="switch-container" label-name="__MSG_showUploadButton__">
<label class="switch">
<input type="checkbox" checked>
<span class="slider round"></span>
</label>
</label>
<br/>
<br/>
<div class="small-description">__MSG_whatUploadButton__</div>
</div>
<br/>
<br/>
<div option-type="toggle" sync-option="autoUpvote">
<label class="switch-container" label-name="__MSG_enableAutoUpvote__">
<label class="switch">
@@ -217,11 +261,28 @@
<div class="small-description">__MSG_whatViewTracking__</div>
</div>
<br/>
<br/>
<div option-type="toggle" sync-option="checkForUnlistedVideos">
<label class="switch-container" label-name="__MSG_unlistedCheck__">
<label class="switch">
<input type="checkbox">
<span class="slider round"></span>
</label>
</label>
<br/>
<br/>
<div class="small-description">__MSG_whatUnlistedCheck__</div>
</div>
<br/>
<br/>
<div option-type="text-change" sync-option="userID" confirm-message="userIDChangeWarning">
<div option-type="private-text-change" sync-option="userID" confirm-message="userIDChangeWarning">
<div class="option-button trigger-button">
__MSG_changeUserID__
</div>
@@ -243,19 +304,31 @@
</div>
</div>
</div>
<br/>
<br/>
<div option-type="toggle" toggle-type="reverse" sync-option="dontShowNotice">
<label class="switch-container" label-name="__MSG_showSkipNotice__">
<label class="switch">
<input type="checkbox" checked>
<span class="slider round"></span>
</label>
<div option-type="text-change" sync-option="serverAddress">
<label class="text-label-container">
<div>__MSG_customServerAddress__</div>
<input class="option-text-box" type="text">
</label>
<div class="option-button text-change-set inline">
__MSG_save__
</div>
<div class="option-button text-change-reset inline">
__MSG_reset__
</div>
<br/>
<br/>
<div class="small-description">__MSG_customServerAddressDescription__</div>
</div>
</div>
</div>

View File

@@ -145,7 +145,7 @@
<span id="sponsorTimesSkipsDoneDisplay" class="popupElement">
0
</span>
<span id="sponsorTimesSkipsDoneEndWord" class="popupElement">__MSG_Segments__</span> (since December).
<span id="sponsorTimesSkipsDoneEndWord" class="popupElement">__MSG_Segments__</span> (since February).
</div>
<div id="sponsorTimeSavedContainer" class="popupElement" style="display: none">
@@ -153,7 +153,7 @@
<span id="sponsorTimeSavedDisplay" class="popupElement">
0
</span>
<span id="sponsorTimeSavedEndWord" class="popupElement">__MSG_minsLower__</span> (since December).
<span id="sponsorTimeSavedEndWord" class="popupElement">__MSG_minsLower__</span>.
</br/>
</br/>

View File

@@ -1,3 +1,5 @@
import * as CompileConfig from "../config.json";
interface SBConfig {
userID: string,
sponsorTimes: SBMap<string, any>,
@@ -14,12 +16,16 @@ interface SBConfig {
hideVideoPlayerControls: boolean,
hideInfoButtonPlayerControls: boolean,
hideDeleteButtonPlayerControls: boolean,
hideUploadButtonPlayerControls: boolean,
hideDiscordLaunches: number,
hideDiscordLink: boolean,
invidiousInstances: string[],
invidiousUpdateInfoShowCount: number,
autoUpvote: boolean,
supportInvidious: false
supportInvidious: boolean,
serverAddress: string,
minDuration: number,
checkForUnlistedVideos: boolean
}
interface SBObject {
@@ -42,7 +48,7 @@ class SBMap<T, U> extends Map {
// Import all entries if they were given
if (entries !== undefined) {
for (const item of entries) {
this.set(item[0], item[1])
super.set(item[0], item[1])
}
}
}
@@ -105,12 +111,16 @@ var Config: SBObject = {
hideVideoPlayerControls: false,
hideInfoButtonPlayerControls: false,
hideDeleteButtonPlayerControls: false,
hideUploadButtonPlayerControls: false,
hideDiscordLaunches: 0,
hideDiscordLink: false,
invidiousInstances: ["invidio.us", "invidiou.sh", "invidious.snopyta.org"],
invidiousUpdateInfoShowCount: 0,
autoUpvote: true,
supportInvidious: false
supportInvidious: false,
serverAddress: CompileConfig.serverAddress,
minDuration: 0,
checkForUnlistedVideos: false
},
localConfig: null,
config: null
@@ -236,7 +246,7 @@ function resetConfig() {
};
function convertJSON() {
Object.keys(Config.defaults).forEach(key => {
Object.keys(Config.localConfig).forEach(key => {
Config.localConfig[key] = decodeStoredItem(key, Config.localConfig[key]);
});
}

View File

@@ -8,12 +8,15 @@ import runThePopup from "./popup";
import PreviewBar from "./js-components/previewBar";
import SkipNotice from "./js-components/skipNotice";
// Hack to get the CSS loaded on permission-based sites (Invidious)
utils.wait(() => Config.config !== null, 5000, 10).then(addCSS);
//was sponsor data found when doing SponsorsLookup
var sponsorDataFound = false;
var previousVideoID = null;
//the actual sponsorTimes if loaded and UUIDs associated with them
var sponsorTimes = null;
var UUIDs = null;
var UUIDs = [];
//what video id are these sponsors for
var sponsorVideoID = null;
@@ -215,7 +218,7 @@ function resetValues() {
//reset sponsor times
sponsorTimes = null;
UUIDs = null;
UUIDs = [];
sponsorLookupRetries = 0;
//empty the preview bar
@@ -227,7 +230,7 @@ function resetValues() {
sponsorDataFound = false;
}
function videoIDChange(id) {
async function videoIDChange(id) {
//if the id has not changed return
if (sponsorVideoID === id) return;
@@ -239,6 +242,19 @@ function videoIDChange(id) {
//id is not valid
if (!id) return;
// Wait for options to be ready
await utils.wait(() => Config.config !== null, 5000, 1);
// If enabled, it will check if this video is private or unlisted and double check with the user if the sponsors should be looked up
if (Config.config.checkForUnlistedVideos) {
await utils.wait(isPrivacyInfoAvailable);
if (isUnlisted()) {
let shouldContinue = confirm(chrome.i18n.getMessage("confirmPrivacy"));
if(!shouldContinue) return;
}
}
// TODO: Use a better method here than using type any
// This is done to be able to do channelIDPromise.isFulfilled and channelIDPromise.isRejected
let channelIDPromise: any = utils.wait(getChannelID);
@@ -363,8 +379,36 @@ function sponsorsLookup(id: string, channelIDPromise?) {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
sponsorDataFound = true;
sponsorTimes = JSON.parse(xmlhttp.responseText).sponsorTimes;
UUIDs = JSON.parse(xmlhttp.responseText).UUIDs;
let recievedSponsorTimes = JSON.parse(xmlhttp.responseText).sponsorTimes;
let recievedUUIDs = JSON.parse(xmlhttp.responseText).UUIDs;
// Check if any old submissions should be kept
for (let i = 0; i < UUIDs.length; i++) {
if (UUIDs[i] === null) {
// This is a user submission, keep it
recievedSponsorTimes.push(sponsorTimes[i]);
recievedUUIDs.push(UUIDs[i]);
}
}
sponsorTimes = recievedSponsorTimes;
UUIDs = recievedUUIDs;
// Remove all submissions smaller than the minimum duration
if (Config.config.minDuration !== 0) {
let smallSponsors = [];
let smallUUIDs = [];
for (let i = 0; i < sponsorTimes.length; i++) {
if (sponsorTimes[i][1] - sponsorTimes[i][0] >= Config.config.minDuration) {
smallSponsors.push(sponsorTimes[i]);
smallUUIDs.push(UUIDs[i]);
}
}
sponsorTimes = smallSponsors;
UUIDs = smallUUIDs;
}
// Reset skip save
sponsorSkipped = [];
@@ -613,7 +657,7 @@ function skipToTime(v, index, sponsorTimes, openNotice) {
}
lastSponsorTimeSkipped = sponsorTimes[index][0];
let currentUUID = UUIDs[index];
lastSponsorTimeSkippedUUID = currentUUID;
@@ -627,17 +671,18 @@ function skipToTime(v, index, sponsorTimes, openNotice) {
vote(1, currentUUID, null);
}
}
}
//send telemetry that a this sponsor was skipped
if (Config.config.trackViewCount && !sponsorSkipped[index]) {
utils.sendRequestToServer("POST", "/api/viewedVideoSponsorTime?UUID=" + currentUUID);
//send telemetry that a this sponsor was skipped
if (Config.config.trackViewCount && !sponsorSkipped[index]) {
utils.sendRequestToServer("POST", "/api/viewedVideoSponsorTime?UUID=" + currentUUID);
if (!Config.config.disableAutoSkip) {
// Count this as a skip
Config.config.minutesSaved = Config.config.minutesSaved + (sponsorTimes[index][1] - sponsorTimes[index][0]) / 60;
Config.config.skipCount = Config.config.skipCount + 1;
sponsorSkipped[index] = true;
if (!Config.config.disableAutoSkip) {
// Count this as a skip
Config.config.minutesSaved = Config.config.minutesSaved + (sponsorTimes[index][1] - sponsorTimes[index][0]) / 60;
Config.config.skipCount = Config.config.skipCount + 1;
sponsorSkipped[index] = true;
}
}
}
}
@@ -787,7 +832,7 @@ async function changeStartSponsorButton(showStartSponsor, uploadButtonVisible) {
(<HTMLImageElement> document.getElementById("startSponsorImage")).src = chrome.extension.getURL("icons/PlayerStartIconSponsorBlocker256px.png");
document.getElementById("startSponsorButton").setAttribute("title", chrome.i18n.getMessage("sponsorStart"));
if (document.getElementById("startSponsorImage").style.display != "none" && uploadButtonVisible && !Config.config.hideInfoButtonPlayerControls) {
if (document.getElementById("startSponsorImage").style.display != "none" && uploadButtonVisible && !Config.config.hideUploadButtonPlayerControls) {
document.getElementById("submitButton").style.display = "unset";
} else if (!uploadButtonVisible) {
//disable submit button
@@ -921,12 +966,10 @@ function vote(type, UUID, skipNotice) {
sponsorSkipped[sponsorIndex] = false;
}
// Count this as a skip
Config.config.minutesSaved = Config.config.minutesSaved + factor * (sponsorTimes[sponsorIndex][1] - sponsorTimes[sponsorIndex][0]) / 60;
Config.config.skipCount = 0;
Config.config.skipCount = Config.config.skipCount + factor * 1;
// Count this as a skip
Config.config.minutesSaved = Config.config.minutesSaved + factor * (sponsorTimes[sponsorIndex][1] - sponsorTimes[sponsorIndex][0]) / 60;
Config.config.skipCount = Config.config.skipCount + factor;
}
chrome.runtime.sendMessage({
@@ -1006,6 +1049,17 @@ function submitSponsorTimes() {
//update sponsorTimesSubmitting
sponsorTimesSubmitting = sponsorTimes;
// Check to see if any of the submissions are below the minimum duration set
if (Config.config.minDuration > 0) {
for (let i = 0; i < sponsorTimes.length; i++) {
if (sponsorTimes[i][1] - sponsorTimes[i][0] < Config.config.minDuration) {
let confirmShort = chrome.i18n.getMessage("shortCheck") + "\n\n" + getSponsorTimesMessage(sponsorTimes);
if(!confirm(confirmShort)) return;
}
}
}
let confirmMessage = chrome.i18n.getMessage("submitCheck") + "\n\n" + getSponsorTimesMessage(sponsorTimes)
+ "\n\n" + chrome.i18n.getMessage("confirmMSG") + "\n\n" + chrome.i18n.getMessage("guildlinesSummary");
if(!confirm(confirmMessage)) return;
@@ -1049,10 +1103,12 @@ function sendSubmitMessage(){
Config.config.sponsorTimes.delete(currentVideoID);
//add submissions to current sponsors list
if (sponsorTimes === null) sponsorTimes = [];
sponsorTimes = sponsorTimes.concat(sponsorTimesSubmitting);
for (let i = 0; i < sponsorTimesSubmitting.length; i++) {
// Add some random IDs
UUIDs.push(utils.generateUserID());
// Add placeholder IDs
UUIDs.push(null);
}
// Empty the submitting times
@@ -1092,6 +1148,53 @@ function getSponsorTimesMessage(sponsorTimes) {
return sponsorTimesMessage;
}
// Privacy utils
function isPrivacyInfoAvailable(): boolean {
if(document.location.pathname.startsWith("/embed/")) return true;
return document.getElementsByClassName("style-scope ytd-badge-supported-renderer").length >= 2;
}
/**
* What privacy level is this YouTube video?
*/
function getPrivacy(): string {
if(document.location.pathname.startsWith("/embed/")) return "Public";
let privacyElement = <HTMLElement> document.getElementsByClassName("style-scope ytd-badge-supported-renderer")[2];
return privacyElement.innerText;
}
/**
* Is this an unlisted YouTube video.
* Assumes that the the privacy info is available.
*/
function isUnlisted(): boolean {
let privacyElement = <HTMLElement> document.getElementsByClassName("style-scope ytd-badge-supported-renderer")[2];
return privacyElement.innerText.toLocaleLowerCase() === "unlisted";
}
/**
* Adds the CSS to the page if needed. Required on optional sites with Chrome.
*/
function addCSS() {
if (!utils.isFirefox() && Config.config.invidiousInstances.includes(new URL(document.URL).host)) {
window.addEventListener("DOMContentLoaded", () => {
let head = document.getElementsByTagName("head")[0];
for (const file of utils.css) {
let fileref = document.createElement("link");
fileref.rel = "stylesheet";
fileref.type = "text/css";
fileref.href = chrome.extension.getURL(file);
head.appendChild(fileref);
}
});
}
}
//converts time in seconds to minutes:seconds
function getFormattedTime(seconds) {
let minutes = Math.floor(seconds / 60);

View File

@@ -50,19 +50,66 @@ async function init() {
switch (option) {
case "supportInvidious":
invidiousOnClick(checkbox, option);
break;
case "disableAutoSkip":
if (!checkbox.checked) {
// Enable the notice
Config.config["dontShowNotice"] = false;
let showNoticeSwitch = <HTMLInputElement> document.querySelector("[sync-option='dontShowNotice'] > label > label > input");
showNoticeSwitch.checked = true;
}
break;
}
});
break;
case "text-change":
let button = optionsElements[i].querySelector(".trigger-button");
button.addEventListener("click", () => activateTextChange(<HTMLElement> optionsElements[i]));
let textChangeOption = optionsElements[i].getAttribute("sync-option");
let textChangeInput = <HTMLInputElement> optionsElements[i].querySelector(".option-text-box");
let textChangeSetButton = <HTMLElement> optionsElements[i].querySelector(".text-change-set");
textChangeInput.value = Config.config[textChangeOption];
textChangeSetButton.addEventListener("click", () => {
// See if anything extra must be done
switch (textChangeOption) {
case "serverAddress":
let result = validateServerAddress(textChangeInput.value);
if (result !== null) {
textChangeInput.value = result;
} else {
return;
}
break;
}
Config.config[textChangeOption] = textChangeInput.value;
});
// Reset to the default if needed
let textChangeResetButton = <HTMLElement> optionsElements[i].querySelector(".text-change-reset");
textChangeResetButton.addEventListener("click", () => {
if (!confirm(chrome.i18n.getMessage("areYouSureReset"))) return;
Config.config[textChangeOption] = Config.defaults[textChangeOption];
textChangeInput.value = Config.config[textChangeOption];
});
break;
case "private-text-change":
let button = optionsElements[i].querySelector(".trigger-button");
button.addEventListener("click", () => activatePrivateTextChange(<HTMLElement> optionsElements[i]));
let privateTextChangeOption = optionsElements[i].getAttribute("sync-option");
// See if anything extra must be done
switch (textChangeOption) {
switch (privateTextChangeOption) {
case "invidiousInstances":
invidiousInstanceAddInit(<HTMLElement> optionsElements[i], textChangeOption);
invidiousInstanceAddInit(<HTMLElement> optionsElements[i], privateTextChangeOption);
}
break;
@@ -73,6 +120,24 @@ async function init() {
break;
case "display":
updateDisplayElement(<HTMLElement> optionsElements[i])
break;
case "number-change":
let numberChangeOption = optionsElements[i].getAttribute("sync-option");
let configValue = Config.config[numberChangeOption];
let numberInput = optionsElements[i].querySelector("input");
if (isNaN(configValue) || configValue < 0) {
numberInput.value = Config.defaults[numberChangeOption];
} else {
numberInput.value = configValue;
}
numberInput.addEventListener("input", () => {
Config.config[numberChangeOption] = numberInput.value;
});
break;
}
}
@@ -265,7 +330,7 @@ function keybindKeyPressed(element: HTMLElement, e: KeyboardEvent) {
*
* @param element
*/
function activateTextChange(element: HTMLElement) {
function activatePrivateTextChange(element: HTMLElement) {
let button = element.querySelector(".trigger-button");
if (button.classList.contains("disabled")) return;
@@ -293,4 +358,27 @@ function activateTextChange(element: HTMLElement) {
});
element.querySelector(".option-hidden-section").classList.remove("hidden");
}
/**
* Validates the value used for the database server address.
* Returns null and alerts the user if there is an issue.
*
* @param input Input server address
*/
function validateServerAddress(input: string): string {
input = input.trim();
// Trim the trailing slashes
input = input.replace(/\/+$/, "");
// If it isn't HTTP protocol
if ((!input.startsWith("https://") && !input.startsWith("http://"))) {
alert(chrome.i18n.getMessage("customAddressError"));
return null;
}
return input;
}

View File

@@ -1,4 +1,3 @@
import * as CompileConfig from "../config.json";
import Config from "./config";
class Utils {
@@ -6,6 +5,17 @@ class Utils {
// Contains functions needed from the background script
backgroundScriptContainer: any = null;
// Used to add content scripts and CSS required
js = [
"./js/vendor.js",
"./js/content.js"
];
css = [
"content.css",
"./libs/Source+Sans+Pro.css",
"popup.css"
];
constructor(backgroundScriptContainer?: any) {
this.backgroundScriptContainer = backgroundScriptContainer;
}
@@ -67,25 +77,15 @@ class Utils {
* For now, it is just SB.config.invidiousInstances.
*/
setupExtraSiteContentScripts() {
let js = [
"./js/vendor.js",
"./js/content.js"
];
let css = [
"content.css",
"./libs/Source+Sans+Pro.css",
"popup.css"
];
let self = this;
if (this.isFirefox()) {
let firefoxJS = [];
for (const file of js) {
for (const file of this.js) {
firefoxJS.push({file});
}
let firefoxCSS = [];
for (const file of css) {
for (const file of this.css) {
firefoxCSS.push({file});
}
@@ -119,8 +119,8 @@ class Utils {
// This API is experimental and not visible by the TypeScript compiler
actions: [new (<any> chrome.declarativeContent).RequestContentScript({
allFrames: true,
js,
css
js: self.js,
css: self.css
})]
};
@@ -240,7 +240,7 @@ class Utils {
sendRequestToServer(type: string, address: string, callback?: (xmlhttp: XMLHttpRequest, err: boolean) => any) {
let xmlhttp = new XMLHttpRequest();
xmlhttp.open(type, CompileConfig.serverAddress + address, true);
xmlhttp.open(type, Config.config.serverAddress + address, true);
if (callback != undefined) {
xmlhttp.onreadystatechange = function () {