Added github contributors to options page
This commit is contained in:
81
css/options.css
Normal file
81
css/options.css
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
.version {
|
||||||
|
padding: 0px 5px 5px 0px;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.creator-tag {
|
||||||
|
margin: 10px 5px 5px 0px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.options-card {
|
||||||
|
width: 400px;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
height: auto;
|
||||||
|
padding-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#version-container {
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
width: 400px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.options-header {
|
||||||
|
padding: 16px 16px 0px 16px;
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#contributors_container {
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 30;
|
||||||
|
padding: 5px 20px 20px 20px;
|
||||||
|
width: auto;
|
||||||
|
margin-right: 20%;
|
||||||
|
margin-left: 20%;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#contributor-list {
|
||||||
|
max-width: 1200px;
|
||||||
|
margin: 0 auto;
|
||||||
|
display: grid;
|
||||||
|
grid-gap: 1rem;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||||
|
}
|
||||||
|
|
||||||
|
.contributor-card {
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 5px;
|
||||||
|
max-width: 1200px;
|
||||||
|
margin: 0 auto;
|
||||||
|
text-align: center;
|
||||||
|
display: grid;
|
||||||
|
grid-gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contributor-card img {
|
||||||
|
width: 200px;
|
||||||
|
height: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contributor-name {
|
||||||
|
font-weight: bold;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contributor-username {
|
||||||
|
margin: 0 0 5px 0;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contributor-title {
|
||||||
|
margin-bottom: 0;
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.open-source-tag {
|
||||||
|
padding: 10px;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
class Template{}
|
class Template {}
|
||||||
|
|
||||||
Template.Main = class {
|
Template.Main = class {
|
||||||
static modal() {
|
static modal() {
|
||||||
@@ -37,12 +37,12 @@ Template.Main = class {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>`
|
</div>`;
|
||||||
}
|
}
|
||||||
static extension_button() {
|
static extension_button() {
|
||||||
return `<td data-th="Plus"><input type="image" class="distButton" id="distButton" width="20" height="20" src='${chrome.extension.getURL('images/disticon.png')}'/></td>`
|
return `<td data-th="Plus"><input type="image" class="distButton" id="distButton" width="20" height="20" src='${chrome.extension.getURL("images/disticon.png")}'/></td>`;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
Template.Catalog = class {
|
Template.Catalog = class {
|
||||||
static loading() {
|
static loading() {
|
||||||
return `<div style="text-align:center">
|
return `<div style="text-align:center">
|
||||||
@@ -52,11 +52,11 @@ Template.Catalog = class {
|
|||||||
<h1 id="retrylabel"style="color: #F44336;display:none;">Failed to Load Courses</h1>
|
<h1 id="retrylabel"style="color: #F44336;display:none;">Failed to Load Courses</h1>
|
||||||
<br>
|
<br>
|
||||||
<button class=material-button id="retry" style="background: #F44336;display:none;">Retry</button>
|
<button class=material-button id="retry" style="background: #F44336;display:none;">Retry</button>
|
||||||
</div>`
|
</div>`;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
Template.UTPlanner = class {
|
Template.UTPlanner = class {
|
||||||
static modal(){
|
static modal() {
|
||||||
return `<div class=modal id=myModal>
|
return `<div class=modal id=myModal>
|
||||||
<div class=modal-content>
|
<div class=modal-content>
|
||||||
<span class=close>×</span>
|
<span class=close>×</span>
|
||||||
@@ -83,25 +83,19 @@ Template.UTPlanner = class {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>`
|
</div>`;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
Template.Calendar = class {
|
Template.Calendar = class {
|
||||||
static line(line) {
|
static line(line) {
|
||||||
let {
|
let { days, start_time, end_time, location_link, location_full } = line;
|
||||||
days,
|
|
||||||
start_time,
|
|
||||||
end_time,
|
|
||||||
location_link,
|
|
||||||
location_full
|
|
||||||
} = line;
|
|
||||||
return `<p class='time' style='font-size:large;'>
|
return `<p class='time' style='font-size:large;'>
|
||||||
<span style='display:inline-block;'>${days}:</span>
|
<span style='display:inline-block;'>${days}:</span>
|
||||||
<span style='margin-left:10px;display:inline-block;text-align:center;'>${start_time} to ${end_time}</span>
|
<span style='margin-left:10px;display:inline-block;text-align:center;'>${start_time} to ${end_time}</span>
|
||||||
<span style='float:right;display:inline-block;text-align:right;width: 25%;'>
|
<span style='float:right;display:inline-block;text-align:right;width: 25%;'>
|
||||||
<a target='_blank' style='color:#3c87a3;text-decoration:none;'href='${location_link}'>${location_full}</a>
|
<a target='_blank' style='color:#3c87a3;text-decoration:none;'href='${location_link}'>${location_full}</a>
|
||||||
</span>
|
</span>
|
||||||
</p>`
|
</p>`;
|
||||||
}
|
}
|
||||||
static modal() {
|
static modal() {
|
||||||
return `<div id="myModal" class="modal">
|
return `<div id="myModal" class="modal">
|
||||||
@@ -121,9 +115,9 @@ Template.Calendar = class {
|
|||||||
<button id="remove" class="matbut" style="font-size:medium;margin:10px;background: #FF0000;">Remove</button>
|
<button id="remove" class="matbut" style="font-size:medium;margin:10px;background: #FF0000;">Remove</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>`
|
</div>`;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
Template.Popup = class {
|
Template.Popup = class {
|
||||||
static list_item(i, list_tile_color, unique, department, number, profname, list_sub_color, line) {
|
static list_item(i, list_tile_color, unique, department, number, profname, list_sub_color, line) {
|
||||||
return `<li id='${i}' class='course_list_item'>
|
return `<li id='${i}' class='course_list_item'>
|
||||||
@@ -150,26 +144,20 @@ Template.Popup = class {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static conflict_message(conflict_message) {
|
static conflict_message(conflict_message) {
|
||||||
return `<p id='conflict' class='conflict_message'>${conflict_message}</>`
|
return `<p id='conflict' class='conflict_message'>${conflict_message}</>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
static line(line) {
|
static line(line) {
|
||||||
let {
|
let { days, start_time, end_time, location_link, location_full } = line;
|
||||||
days,
|
|
||||||
start_time,
|
|
||||||
end_time,
|
|
||||||
location_link,
|
|
||||||
location_full
|
|
||||||
} = line;
|
|
||||||
|
|
||||||
return `<span class='time_line_days'>${days}:</span>
|
return `<span class='time_line_days'>${days}:</span>
|
||||||
<span class='time_line_hours'>${start_time} to ${end_time}</span>
|
<span class='time_line_hours'>${start_time} to ${end_time}</span>
|
||||||
<span class='time_line_location'>
|
<span class='time_line_location'>
|
||||||
<a target='_blank' class= 'time_line_location_link' href='${location_link}'>${location_full}</a>
|
<a target='_blank' class= 'time_line_location_link' href='${location_link}'>${location_full}</a>
|
||||||
</span>
|
</span>
|
||||||
<br>`
|
<br>`;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
Template.Import = class {
|
Template.Import = class {
|
||||||
static import_button() {
|
static import_button() {
|
||||||
return `<button class='material-button' id='import' style='margin:15px 0px;'>${Text.button_text_default}</button><br>`;
|
return `<button class='material-button' id='import' style='margin:15px 0px;'>${Text.button_text_default}</button><br>`;
|
||||||
@@ -179,14 +167,13 @@ Template.Import = class {
|
|||||||
return `<button class='material-button' id='import_waitlist' style='margin:0px'>${Text.waitlist_button_text_default}</button><br>`;
|
return `<button class='material-button' id='import_waitlist' style='margin:0px'>${Text.waitlist_button_text_default}</button><br>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
static store_waitlist_message(){
|
static store_waitlist_message() {
|
||||||
return `<h1 id="nextlabel"style="color: #FF9800;display:none;"></h1>`
|
return `<h1 id="nextlabel"style="color: #FF9800;display:none;"></h1>`;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
}
|
|
||||||
|
|
||||||
Template.Options = class {
|
Template.Options = class {
|
||||||
static options_row(key, enabled){
|
static options_row(key, enabled) {
|
||||||
let button_text = enabled ? "Turn Off" : "Turn On";
|
let button_text = enabled ? "Turn Off" : "Turn On";
|
||||||
let button_color = enabled ? Colors.closed : Colors.open;
|
let button_color = enabled ? Colors.closed : Colors.open;
|
||||||
let label_text = capitalizeString(key.replace(/([A-Z]+)*([A-Z][a-z])/g, "$1 $2"));
|
let label_text = capitalizeString(key.replace(/([A-Z]+)*([A-Z][a-z])/g, "$1 $2"));
|
||||||
@@ -196,7 +183,14 @@ Template.Options = class {
|
|||||||
<button id="${key}" value=${enabled} class="material-button" style="display:inline-block;font-size:medium; float:right; background:${button_color}">
|
<button id="${key}" value=${enabled} class="material-button" style="display:inline-block;font-size:medium; float:right; background:${button_color}">
|
||||||
${button_text}
|
${button_text}
|
||||||
</button>
|
</button>
|
||||||
<br>`
|
<br>`;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
static contributor_card(username, name, image_url, profile_url) {
|
||||||
|
return `<div class='card contributor-card' id="${username}" data-url="${profile_url}">
|
||||||
|
<img class='contributor-image' src="${image_url}"></img>
|
||||||
|
${name ? `<p class='contributor-name'>${name}</p>` : ""}
|
||||||
|
<p class='contributor-username'>${username}</p>
|
||||||
|
</div>`;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|||||||
186
js/background.js
186
js/background.js
@@ -4,10 +4,10 @@ var departments = [];
|
|||||||
var should_open = false;
|
var should_open = false;
|
||||||
|
|
||||||
const default_options = {
|
const default_options = {
|
||||||
"loadAll": true,
|
loadAll: true,
|
||||||
"courseConflictHighlight": true,
|
courseConflictHighlight: true,
|
||||||
"storeWaitlist": true,
|
storeWaitlist: true,
|
||||||
}
|
};
|
||||||
|
|
||||||
onStartup();
|
onStartup();
|
||||||
|
|
||||||
@@ -44,18 +44,18 @@ chrome.runtime.onMessage.addListener(function (request, sender, response) {
|
|||||||
executeQuery(request.query, response);
|
executeQuery(request.query, response);
|
||||||
break;
|
break;
|
||||||
case "currentSemesters":
|
case "currentSemesters":
|
||||||
response({ semesters: current_semesters});
|
response({ semesters: current_semesters });
|
||||||
getCurrentSemesters();
|
getCurrentSemesters();
|
||||||
break;
|
break;
|
||||||
case "currentDepartments":
|
case "currentDepartments":
|
||||||
response({departments: departments});
|
response({ departments: departments });
|
||||||
break;
|
break;
|
||||||
case "setOpen":
|
case "setOpen":
|
||||||
should_open = true;
|
should_open = true;
|
||||||
chrome.tabs.create({ url: request.url});
|
chrome.tabs.create({ url: request.url });
|
||||||
break;
|
break;
|
||||||
case "shouldOpen":
|
case "shouldOpen":
|
||||||
response({open : should_open});
|
response({ open: should_open });
|
||||||
should_open = false;
|
should_open = false;
|
||||||
break;
|
break;
|
||||||
case "getOptionsValue":
|
case "getOptionsValue":
|
||||||
@@ -72,7 +72,7 @@ chrome.runtime.onMessage.addListener(function (request, sender, response) {
|
|||||||
xhr.onload = () => {
|
xhr.onload = () => {
|
||||||
console.log(xhr.responseUrl);
|
console.log(xhr.responseUrl);
|
||||||
response(xhr.responseText);
|
response(xhr.responseText);
|
||||||
}
|
};
|
||||||
xhr.onerror = () => response(xhr.statusText);
|
xhr.onerror = () => response(xhr.statusText);
|
||||||
if (method == "POST") {
|
if (method == "POST") {
|
||||||
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
|
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
|
||||||
@@ -87,13 +87,16 @@ chrome.runtime.onMessage.addListener(function (request, sender, response) {
|
|||||||
chrome.runtime.onInstalled.addListener(function (details) {
|
chrome.runtime.onInstalled.addListener(function (details) {
|
||||||
if (details.reason == "install") {
|
if (details.reason == "install") {
|
||||||
setDefaultOptions();
|
setDefaultOptions();
|
||||||
chrome.storage.sync.get('savedCourses', function (data) {
|
chrome.storage.sync.get("savedCourses", function (data) {
|
||||||
if (!data.savedCourses) {
|
if (!data.savedCourses) {
|
||||||
chrome.storage.sync.set({
|
chrome.storage.sync.set(
|
||||||
savedCourses: new Array()
|
{
|
||||||
}, function () {
|
savedCourses: new Array(),
|
||||||
console.log('initial course list');
|
},
|
||||||
});
|
function () {
|
||||||
|
console.log("initial course list");
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else if (details.reason == "update") {
|
} else if (details.reason == "update") {
|
||||||
@@ -102,85 +105,92 @@ chrome.runtime.onInstalled.addListener(function (details) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
chrome.storage.onChanged.addListener(function (changes) {
|
chrome.storage.onChanged.addListener(function (changes) {
|
||||||
for (key in changes) {
|
for (key in changes) {
|
||||||
console.log(changes);
|
console.log(changes);
|
||||||
if (key === 'savedCourses') {
|
if (key === "savedCourses") {
|
||||||
updateBadge(false, changes.savedCourses.newValue);
|
updateBadge(false, changes.savedCourses.newValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function onStartup(){
|
function onStartup() {
|
||||||
updateBadge(true);
|
updateBadge(true);
|
||||||
loadDataBase()
|
loadDataBase();
|
||||||
getCurrentSemesters();
|
getCurrentSemesters();
|
||||||
getCurrentDepartments();
|
getCurrentDepartments();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getOptionsValue(key, sendResponse){
|
function getOptionsValue(key, sendResponse) {
|
||||||
chrome.storage.sync.get('options', function (data) {
|
chrome.storage.sync.get("options", function (data) {
|
||||||
if (!data.options) {
|
if (!data.options) {
|
||||||
setDefaultOptions();
|
setDefaultOptions();
|
||||||
} else {
|
} else {
|
||||||
sendResponse({
|
sendResponse({
|
||||||
'value': data.options[key]
|
value: data.options[key],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function setOptionsValue(key, value, sendResponse){
|
function setOptionsValue(key, value, sendResponse) {
|
||||||
chrome.storage.sync.get('options', function (data) {
|
chrome.storage.sync.get("options", function (data) {
|
||||||
let new_options = data.options;
|
let new_options = data.options;
|
||||||
if (!data.options) {
|
if (!data.options) {
|
||||||
setDefaultOptions();
|
setDefaultOptions();
|
||||||
new_options = default_options;
|
new_options = default_options;
|
||||||
}
|
}
|
||||||
new_options[key] = value;
|
new_options[key] = value;
|
||||||
chrome.storage.sync.set({
|
chrome.storage.sync.set(
|
||||||
options: new_options
|
{
|
||||||
}, function () {
|
options: new_options,
|
||||||
|
},
|
||||||
|
function () {
|
||||||
console.log(key);
|
console.log(key);
|
||||||
console.log(new_options);
|
console.log(new_options);
|
||||||
sendResponse({
|
sendResponse({
|
||||||
'value': new_options[key]
|
value: new_options[key],
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function setDefaultOptions(){
|
function setDefaultOptions() {
|
||||||
chrome.storage.sync.get('options', function (data) {
|
chrome.storage.sync.get("options", function (data) {
|
||||||
if (!data.options) {
|
if (!data.options) {
|
||||||
chrome.storage.sync.set({
|
chrome.storage.sync.set(
|
||||||
options: default_options
|
{
|
||||||
}, function () {
|
options: default_options,
|
||||||
console.log('default options:');
|
},
|
||||||
|
function () {
|
||||||
|
console.log("default options:");
|
||||||
console.log(default_options);
|
console.log(default_options);
|
||||||
});
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCurrentSemesters(){
|
function getCurrentSemesters() {
|
||||||
$.get('https://registrar.utexas.edu/schedules', function (response) {
|
$.get("https://registrar.utexas.edu/schedules", function (response) {
|
||||||
if (response) {
|
if (response) {
|
||||||
htmlToNode(response).find('.callout2>ul>li>a').each(function (i) {
|
htmlToNode(response)
|
||||||
|
.find(".callout2>ul>li>a")
|
||||||
|
.each(function (i) {
|
||||||
if (i < Popup.num_semesters) {
|
if (i < Popup.num_semesters) {
|
||||||
let sem_name = $(this).text().trim();
|
let sem_name = $(this).text().trim();
|
||||||
if (sem_name != "Course Schedule Archive") {
|
if (sem_name != "Course Schedule Archive") {
|
||||||
// $("#semesters").append(`<option>${sem_name}</option>`);
|
// $("#semesters").append(`<option>${sem_name}</option>`);
|
||||||
current_semesters[sem_name] = "code";
|
current_semesters[sem_name] = "code";
|
||||||
$.get($(this).attr('href'), function (response) {
|
$.get($(this).attr("href"), function (response) {
|
||||||
if (response) {
|
if (response) {
|
||||||
let response_node = htmlToNode(response);
|
let response_node = htmlToNode(response);
|
||||||
let name = response_node.find(".page-title").text().substring(17).trim();
|
let name = response_node.find(".page-title").text().substring(17).trim();
|
||||||
response_node.find('.gobutton>a').each(function () {
|
response_node.find(".gobutton>a").each(function () {
|
||||||
let link = $(this).attr('href');
|
let link = $(this).attr("href");
|
||||||
var sem_num = link.substring(link.lastIndexOf('/') + 1).trim();
|
var sem_num = link.substring(link.lastIndexOf("/") + 1).trim();
|
||||||
if(current_semesters[name] != sem_num){
|
if (current_semesters[name] != sem_num) {
|
||||||
current_semesters[name] = sem_num;
|
current_semesters[name] = sem_num;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -193,13 +203,14 @@ function getCurrentSemesters(){
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getCurrentDepartments() {
|
||||||
function getCurrentDepartments(){
|
$.get("https://catalog.utexas.edu/undergraduate/appendix-b/", function (response) {
|
||||||
$.get('https://catalog.utexas.edu/undergraduate/appendix-b/', function(response){
|
if (response) {
|
||||||
if(response){;
|
|
||||||
departments = [];
|
departments = [];
|
||||||
htmlToNode(response).find('.column1').each(function(i){
|
htmlToNode(response)
|
||||||
if(i > 1){
|
.find(".column1")
|
||||||
|
.each(function (i) {
|
||||||
|
if (i > 1) {
|
||||||
let abv = $(this).text();
|
let abv = $(this).text();
|
||||||
departments.push(abv);
|
departments.push(abv);
|
||||||
}
|
}
|
||||||
@@ -212,53 +223,51 @@ function updateBadge(first, new_changes) {
|
|||||||
if (new_changes) {
|
if (new_changes) {
|
||||||
updateBadgeText(first, new_changes);
|
updateBadgeText(first, new_changes);
|
||||||
} else {
|
} else {
|
||||||
chrome.storage.sync.get('savedCourses', function (data) {
|
chrome.storage.sync.get("savedCourses", function (data) {
|
||||||
let courses = data.savedCourses;
|
let courses = data.savedCourses;
|
||||||
updateBadgeText(first, courses);
|
updateBadgeText(first, courses);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function updateBadgeText(first, courses) {
|
function updateBadgeText(first, courses) {
|
||||||
let badge_text = courses.length > 0 ? `${courses.length}` : "";
|
let badge_text = courses.length > 0 ? `${courses.length}` : "";
|
||||||
let flash_time = !first ? 200 : 0;
|
let flash_time = !first ? 200 : 0;
|
||||||
chrome.browserAction.setBadgeText({
|
chrome.browserAction.setBadgeText({
|
||||||
text: badge_text
|
text: badge_text,
|
||||||
});
|
});
|
||||||
if (!first) {
|
if (!first) {
|
||||||
chrome.browserAction.setBadgeBackgroundColor({
|
chrome.browserAction.setBadgeBackgroundColor({
|
||||||
color: Colors.badge_flash
|
color: Colors.badge_flash,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
chrome.browserAction.setBadgeBackgroundColor({
|
chrome.browserAction.setBadgeBackgroundColor({
|
||||||
color: Colors.badge_default
|
color: Colors.badge_default,
|
||||||
});
|
});
|
||||||
}, flash_time);
|
}, flash_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find all the conflicts in the courses and send them out/ if there is even a conflict*/
|
/* Find all the conflicts in the courses and send them out/ if there is even a conflict*/
|
||||||
function checkConflicts(sendResponse) {
|
function checkConflicts(sendResponse) {
|
||||||
chrome.storage.sync.get('savedCourses', function (data) {
|
chrome.storage.sync.get("savedCourses", function (data) {
|
||||||
var conflicts = [];
|
var conflicts = [];
|
||||||
var courses = data.savedCourses;
|
var courses = data.savedCourses;
|
||||||
for (let i = 0; i < courses.length; i++) {
|
for (let i = 0; i < courses.length; i++) {
|
||||||
for (let j = i + 1; j < courses.length; j++) {
|
for (let j = i + 1; j < courses.length; j++) {
|
||||||
let course_a = courses[i];
|
let course_a = courses[i];
|
||||||
let course_b = courses[j];
|
let course_b = courses[j];
|
||||||
if (isConflict(course_a.datetimearr, course_b.datetimearr))
|
if (isConflict(course_a.datetimearr, course_b.datetimearr)) conflicts.push([course_a, course_b]);
|
||||||
conflicts.push([course_a, course_b]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (conflicts.length == 0) {
|
if (conflicts.length == 0) {
|
||||||
sendResponse({
|
sendResponse({
|
||||||
isConflict: false
|
isConflict: false,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
sendResponse({
|
sendResponse({
|
||||||
isConflict: true,
|
isConflict: true,
|
||||||
between: conflicts
|
between: conflicts,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -266,7 +275,7 @@ function checkConflicts(sendResponse) {
|
|||||||
|
|
||||||
/* Find if the course at unique and with currdatearr is contained in the saved courses and if it conflicts with any other courses*/
|
/* Find if the course at unique and with currdatearr is contained in the saved courses and if it conflicts with any other courses*/
|
||||||
function isSingleConflict(currdatearr, unique, sendResponse) {
|
function isSingleConflict(currdatearr, unique, sendResponse) {
|
||||||
chrome.storage.sync.get('savedCourses', function (data) {
|
chrome.storage.sync.get("savedCourses", function (data) {
|
||||||
var courses = data.savedCourses;
|
var courses = data.savedCourses;
|
||||||
var conflict_list = [];
|
var conflict_list = [];
|
||||||
var conflict = false;
|
var conflict = false;
|
||||||
@@ -284,14 +293,11 @@ function isSingleConflict(currdatearr, unique, sendResponse) {
|
|||||||
sendResponse({
|
sendResponse({
|
||||||
isConflict: conflict,
|
isConflict: conflict,
|
||||||
alreadyContains: contains,
|
alreadyContains: contains,
|
||||||
conflictList: conflict_list
|
conflictList: conflict_list,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Check if conflict between two date-time-arrs*/
|
/* Check if conflict between two date-time-arrs*/
|
||||||
function isConflict(adtarr, bdtarr) {
|
function isConflict(adtarr, bdtarr) {
|
||||||
for (var i = 0; i < adtarr.length; i++) {
|
for (var i = 0; i < adtarr.length; i++) {
|
||||||
@@ -312,25 +318,25 @@ function isConflict(adtarr, bdtarr) {
|
|||||||
|
|
||||||
/* Add the requested course to the storage*/
|
/* Add the requested course to the storage*/
|
||||||
function add(request, sender, sendResponse) {
|
function add(request, sender, sendResponse) {
|
||||||
chrome.storage.sync.get('savedCourses', function (data) {
|
chrome.storage.sync.get("savedCourses", function (data) {
|
||||||
var courses = data.savedCourses;
|
var courses = data.savedCourses;
|
||||||
if (!contains(courses, request.course.unique)) {
|
if (!contains(courses, request.course.unique)) {
|
||||||
courses.push(request.course)
|
courses.push(request.course);
|
||||||
console.log(courses);
|
console.log(courses);
|
||||||
chrome.storage.sync.set({
|
chrome.storage.sync.set({
|
||||||
savedCourses: courses
|
savedCourses: courses,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
sendResponse({
|
sendResponse({
|
||||||
done: "Added: (" + request.course.unique + ") " + request.course.coursename,
|
done: "Added: (" + request.course.unique + ") " + request.course.coursename,
|
||||||
label: "Remove Course -",
|
label: "Remove Course -",
|
||||||
value: "remove"
|
value: "remove",
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
/* Find and Remove the requested course from the storage*/
|
/* Find and Remove the requested course from the storage*/
|
||||||
function remove(request, sender, sendResponse) {
|
function remove(request, sender, sendResponse) {
|
||||||
chrome.storage.sync.get('savedCourses', function (data) {
|
chrome.storage.sync.get("savedCourses", function (data) {
|
||||||
var courses = data.savedCourses;
|
var courses = data.savedCourses;
|
||||||
console.log(courses);
|
console.log(courses);
|
||||||
var index = 0;
|
var index = 0;
|
||||||
@@ -339,22 +345,22 @@ function remove(request, sender, sendResponse) {
|
|||||||
}
|
}
|
||||||
courses.splice(index, 1);
|
courses.splice(index, 1);
|
||||||
chrome.storage.sync.set({
|
chrome.storage.sync.set({
|
||||||
savedCourses: courses
|
savedCourses: courses,
|
||||||
});
|
});
|
||||||
sendResponse({
|
sendResponse({
|
||||||
done: "Removed: (" + request.course.unique + ") " + request.course.coursename,
|
done: "Removed: (" + request.course.unique + ") " + request.course.coursename,
|
||||||
label: "Add Course +",
|
label: "Add Course +",
|
||||||
value: "add"
|
value: "add",
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find if the unique is already contained within the storage*/
|
/* Find if the unique is already contained within the storage*/
|
||||||
function alreadyContains(unique, sendResponse) {
|
function alreadyContains(unique, sendResponse) {
|
||||||
chrome.storage.sync.get('savedCourses', function (data) {
|
chrome.storage.sync.get("savedCourses", function (data) {
|
||||||
var courses = data.savedCourses;
|
var courses = data.savedCourses;
|
||||||
sendResponse({
|
sendResponse({
|
||||||
alreadyContains: contains(courses, unique)
|
alreadyContains: contains(courses, unique),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -371,14 +377,14 @@ function contains(courses, unique) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function isSameCourse(course, unique) {
|
function isSameCourse(course, unique) {
|
||||||
return course.unique == unique
|
return course.unique == unique;
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateTabs() {
|
function updateTabs() {
|
||||||
chrome.tabs.query({}, function (tabs) {
|
chrome.tabs.query({}, function (tabs) {
|
||||||
for (var i = 0; i < tabs.length; i++) {
|
for (var i = 0; i < tabs.length; i++) {
|
||||||
chrome.tabs.sendMessage(tabs[i].id, {
|
chrome.tabs.sendMessage(tabs[i].id, {
|
||||||
command: "updateCourseList"
|
command: "updateCourseList",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -388,9 +394,8 @@ const UPDATE_INTERVAL = 1000 * 60 * 16;
|
|||||||
setInterval(updateStatus, UPDATE_INTERVAL);
|
setInterval(updateStatus, UPDATE_INTERVAL);
|
||||||
// updateStatus();
|
// updateStatus();
|
||||||
|
|
||||||
|
|
||||||
function updateStatus(sendResponse) {
|
function updateStatus(sendResponse) {
|
||||||
chrome.storage.sync.get('savedCourses', function (data) {
|
chrome.storage.sync.get("savedCourses", function (data) {
|
||||||
var courses = data.savedCourses;
|
var courses = data.savedCourses;
|
||||||
var no_change = true;
|
var no_change = true;
|
||||||
for (let i = 0; i < courses.length; i++) {
|
for (let i = 0; i < courses.length; i++) {
|
||||||
@@ -403,37 +408,34 @@ function updateStatus(sendResponse) {
|
|||||||
success: function (result) {
|
success: function (result) {
|
||||||
if (result) {
|
if (result) {
|
||||||
console.log(result);
|
console.log(result);
|
||||||
var object = $('<div/>').html(result).contents();
|
var object = $("<div/>").html(result).contents();
|
||||||
let new_status = object.find('[data-th="Status"]').text();
|
let new_status = object.find('[data-th="Status"]').text();
|
||||||
let register_link = object.find('td[data-th="Add"] a');
|
let register_link = object.find('td[data-th="Add"] a');
|
||||||
if (register_link)
|
if (register_link) register_link = register_link.attr("href");
|
||||||
register_link = register_link.attr('href');
|
var haschanged = new_status == old_status && register_link == old_link;
|
||||||
var haschanged = (new_status == old_status && register_link == old_link);
|
if (!haschanged) console.log(c.unique + " updated from " + old_status + " to " + new_status + " and " + old_link + " to " + register_link);
|
||||||
if (!haschanged)
|
|
||||||
console.log(c.unique + ' updated from ' + old_status + " to " + new_status + " and " + old_link + " to " + register_link);
|
|
||||||
no_change &= haschanged;
|
no_change &= haschanged;
|
||||||
c.registerlink = register_link;
|
c.registerlink = register_link;
|
||||||
c.status = new_status;
|
c.status = new_status;
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
console.log('Not logged into UT Coursebook. Could not update class statuses.');
|
console.log("Not logged into UT Coursebook. Could not update class statuses.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!no_change) {
|
if (!no_change) {
|
||||||
chrome.storage.sync.set({
|
chrome.storage.sync.set({
|
||||||
savedCourses: courses
|
savedCourses: courses,
|
||||||
});
|
});
|
||||||
console.log('updated status');
|
console.log("updated status");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function executeQuery(query, sendResponse) {
|
function executeQuery(query, sendResponse) {
|
||||||
console.log(grades)
|
console.log(grades);
|
||||||
var res = grades.exec(query)[0];
|
var res = grades.exec(query)[0];
|
||||||
sendResponse({
|
sendResponse({
|
||||||
data: res,
|
data: res,
|
||||||
@@ -443,7 +445,7 @@ function executeQuery(query, sendResponse) {
|
|||||||
/* Load the database*/
|
/* Load the database*/
|
||||||
function loadDataBase() {
|
function loadDataBase() {
|
||||||
sql = window.SQL;
|
sql = window.SQL;
|
||||||
loadBinaryFile('grades.db', function (data) {
|
loadBinaryFile("grades.db", function (data) {
|
||||||
var sqldb = new SQL.Database(data);
|
var sqldb = new SQL.Database(data);
|
||||||
grades = sqldb;
|
grades = sqldb;
|
||||||
});
|
});
|
||||||
@@ -460,4 +462,4 @@ function loadBinaryFile(path, success) {
|
|||||||
success(arr.join(""));
|
success(arr.join(""));
|
||||||
};
|
};
|
||||||
xhr.send();
|
xhr.send();
|
||||||
};
|
}
|
||||||
|
|||||||
72
js/config.js
72
js/config.js
@@ -1,27 +1,36 @@
|
|||||||
class Timing{}
|
class Timing {}
|
||||||
Timing.fade_time = 100;
|
Timing.fade_time = 100;
|
||||||
Timing.calendar_fade_time = 100;
|
Timing.calendar_fade_time = 100;
|
||||||
Timing.button_delay = 75;
|
Timing.button_delay = 75;
|
||||||
|
|
||||||
|
class Colors {}
|
||||||
class Colors{}
|
Colors.material_colors = [
|
||||||
Colors.material_colors = ['#4CAF50', '#CDDC39',
|
"#4CAF50",
|
||||||
'#FFC107', '#2196F3', '#F57C00', '#9C27B0', '#FF5722', '#673AB7',
|
"#CDDC39",
|
||||||
'#FF5252', '#E91E63', '#009688', '#00BCD4',
|
"#FFC107",
|
||||||
'#4E342E', '#424242', '#9E9E9E'
|
"#2196F3",
|
||||||
|
"#F57C00",
|
||||||
|
"#9C27B0",
|
||||||
|
"#FF5722",
|
||||||
|
"#673AB7",
|
||||||
|
"#FF5252",
|
||||||
|
"#E91E63",
|
||||||
|
"#009688",
|
||||||
|
"#00BCD4",
|
||||||
|
"#4E342E",
|
||||||
|
"#424242",
|
||||||
|
"#9E9E9E",
|
||||||
];
|
];
|
||||||
Colors.open = "#4CAF50";
|
Colors.open = "#4CAF50";
|
||||||
Colors.waitlisted = "#FF9800";
|
Colors.waitlisted = "#FF9800";
|
||||||
Colors.closed = "#FF5722";
|
Colors.closed = "#FF5722";
|
||||||
Colors.no_status = "#607D8B";
|
Colors.no_status = "#607D8B";
|
||||||
|
|
||||||
|
|
||||||
Colors.open_light = "#C8E6C9";
|
Colors.open_light = "#C8E6C9";
|
||||||
Colors.waitlisted_light = "#FFE0B2";
|
Colors.waitlisted_light = "#FFE0B2";
|
||||||
Colors.closed_light = "#FFCCBC";
|
Colors.closed_light = "#FFCCBC";
|
||||||
Colors.no_status_light = "#CFD8DC";
|
Colors.no_status_light = "#CFD8DC";
|
||||||
|
|
||||||
|
|
||||||
Colors.highlight_conflict = "#F44336";
|
Colors.highlight_conflict = "#F44336";
|
||||||
Colors.highlight_default = "#333333";
|
Colors.highlight_default = "#333333";
|
||||||
Colors.highlight_saved = "#4CAF50";
|
Colors.highlight_saved = "#4CAF50";
|
||||||
@@ -29,31 +38,50 @@ Colors.highlight_saved = "#4CAF50";
|
|||||||
Colors.badge_flash = "#FF5722";
|
Colors.badge_flash = "#FF5722";
|
||||||
Colors.badge_default = "#bf5700";
|
Colors.badge_default = "#bf5700";
|
||||||
|
|
||||||
|
class Export {}
|
||||||
class Export{}
|
|
||||||
Export.png_options = {
|
Export.png_options = {
|
||||||
foreignObjectRendering: true,
|
foreignObjectRendering: true,
|
||||||
logging: true,
|
logging: true,
|
||||||
removeContainer: true,
|
removeContainer: true,
|
||||||
async: true,
|
async: true,
|
||||||
}
|
};
|
||||||
|
|
||||||
class Popup {}
|
class Popup {}
|
||||||
Popup.num_semesters = 2;
|
Popup.num_semesters = 2;
|
||||||
|
|
||||||
class Text{}
|
class Text {}
|
||||||
Text.emptyText = function(){
|
Text.emptyText = function () {
|
||||||
let arr = ["Doesn't Look Like Anything To Me.", "You Can't Fail Classes You're Not In.", "Pro-Tip: Don't Take O-Chem.",
|
let arr = [
|
||||||
"No Work Happens On PCL 5th Floor.", "Sophomore But Freshman By Credit.", "Pain is temporary, GPA is forever.",
|
"Doesn't Look Like Anything To Me.",
|
||||||
"You've Yee'd Your Last Haw.", "lol everything is already waitlisted.", "At Least You're Not At A&M.",
|
"You Can't Fail Classes You're Not In.",
|
||||||
`It's ${moment().format("h:mm")} and OU Still Sucks.`, 'TeXAs iS BaCK GuYZ', "'Academically Challenged'",
|
"Pro-Tip: Don't Take O-Chem.",
|
||||||
'Does McCombs teach Parseltongue?', 'Lets make Daddy Fenves proud.', 'Feel bad if you say Wampus.', 'No Cruce Enfrente Del Bus.',
|
"Jendy's Fofofo™",
|
||||||
'Midterm 1 has been Unmuted', 'Omae Wa Mou Shindeiru...', 'Bevo Bucks are the new Bitcoin', 'Subway Robber > Machete Guy'
|
"Fine Dining at Jester City Limits",
|
||||||
]
|
"Rec Sports is full and it's only 2pm.",
|
||||||
|
"Hope Domino is doing well rn 🥺",
|
||||||
|
"The year is 2055 and Welch still isn't finished.",
|
||||||
|
"Wear a Mask.",
|
||||||
|
"Motivation dropping faster than ur GPA",
|
||||||
|
"No Work Happens On PCL 5th Floor.",
|
||||||
|
"Sophomore But Freshman By Credit.",
|
||||||
|
"Pain is temporary, GPA is forever.",
|
||||||
|
"You've Yee'd Your Last Haw.",
|
||||||
|
"lol everything is already waitlisted.",
|
||||||
|
"At Least You're Not At A&M.",
|
||||||
|
`It's ${moment().format("h:mm")} and OU Still Sucks.`,
|
||||||
|
"TeXAs iS BaCK GuYZ",
|
||||||
|
"'Academically Challenged'",
|
||||||
|
"Does McCombs teach Parseltongue?",
|
||||||
|
"Feel bad if you say Wampus.",
|
||||||
|
"No Cruce Enfrente Del Bus.",
|
||||||
|
"Midterm 1 has been Unmuted",
|
||||||
|
"Omae Wa Mou Shindeiru...",
|
||||||
|
"Bevo Bucks are the new Bitcoin",
|
||||||
|
];
|
||||||
let index = Math.floor(Math.random() * arr.length);
|
let index = Math.floor(Math.random() * arr.length);
|
||||||
|
|
||||||
return arr[index];
|
return arr[index];
|
||||||
}
|
};
|
||||||
Text.button_text_default = "<span style='font-size:small'>Import to </span><b>UT Reg +<b>";
|
Text.button_text_default = "<span style='font-size:small'>Import to </span><b>UT Reg +<b>";
|
||||||
Text.waitlist_button_text_default = "<span style='font-size:small'>Import Waitlists to </span><b>UT Reg +<b>";
|
Text.waitlist_button_text_default = "<span style='font-size:small'>Import Waitlists to </span><b>UT Reg +<b>";
|
||||||
Text.button_success = "Courses Saved!";
|
Text.button_success = "Courses Saved!";
|
||||||
|
|||||||
@@ -1,36 +1,54 @@
|
|||||||
var manifestData = chrome.runtime.getManifest();
|
var manifestData = chrome.runtime.getManifest();
|
||||||
$("#version").text(manifestData.version);
|
$("#version").text(manifestData.version);
|
||||||
|
|
||||||
chrome.storage.sync.get('options', function(data){
|
chrome.storage.sync.get("options", function (data) {
|
||||||
if(data.options){
|
if (data.options) {
|
||||||
console.log(data.options);
|
console.log(data.options);
|
||||||
Object.keys(data.options).forEach(key => {
|
Object.keys(data.options).forEach(key => {
|
||||||
let enabled = data.options[key];
|
let enabled = data.options[key];
|
||||||
$('#options_container').append(Template.Options.options_row(key, enabled));
|
$("#options_container").append(Template.Options.options_row(key, enabled));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$("body").on("click","button",function(){
|
$("body").on("click", "button", function () {
|
||||||
let key = $(this).attr('id');
|
let key = $(this).attr("id");
|
||||||
let old_status = $(this).val() === 'true';
|
let old_status = $(this).val() === "true";
|
||||||
let new_status = !old_status;
|
let new_status = !old_status;
|
||||||
chrome.runtime.sendMessage({
|
chrome.runtime.sendMessage(
|
||||||
|
{
|
||||||
command: "setOptionsValue",
|
command: "setOptionsValue",
|
||||||
key: key,
|
key: key,
|
||||||
value: new_status
|
value: new_status,
|
||||||
}, function (response) {
|
},
|
||||||
|
function (response) {
|
||||||
console.log(response.value);
|
console.log(response.value);
|
||||||
toggle(key, response.value)
|
toggle(key, response.value);
|
||||||
updateAllTabsCourseList();
|
updateAllTabsCourseList();
|
||||||
});
|
}
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$.get("https://api.github.com/repos/sghsri/UT-Registration-Plus/stats/contributors", data => {
|
||||||
|
data = data.sort((a, b) => b.total - a.total);
|
||||||
|
console.log("data", data);
|
||||||
|
for (var contributorData of data) {
|
||||||
|
$.get(`https://api.github.com/users/${contributorData.author.login}`, userData => {
|
||||||
|
let fullData = { ...contributorData, ...userData };
|
||||||
|
let { login, avatar_url, html_url, name } = fullData;
|
||||||
|
$("#contributor-list").append(Template.Options.contributor_card(login, name, avatar_url, html_url));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$("body").on("click", ".contributor-card", function () {
|
||||||
|
console.log("hello world");
|
||||||
|
window.open($(this).data("url"), "_blank");
|
||||||
|
});
|
||||||
|
|
||||||
function toggle(key, value) {
|
function toggle(key, value) {
|
||||||
let button_text = value ? "Turn Off": "Turn On";
|
let button_text = value ? "Turn Off" : "Turn On";
|
||||||
let button_color = value ? Colors.closed : Colors.open ;
|
let button_color = value ? Colors.closed : Colors.open;
|
||||||
$(`#${key}`).text(button_text);
|
$(`#${key}`).text(button_text);
|
||||||
$(`#${key}`).css("background", button_color);
|
$(`#${key}`).css("background", button_color);
|
||||||
$(`#${key}`).val(value);
|
$(`#${key}`).val(value);
|
||||||
|
|||||||
31
options.html
31
options.html
@@ -1,23 +1,30 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<link rel="stylesheet" href="css/styles.css" />
|
||||||
|
<link rel="stylesheet" href="css/options.css" />
|
||||||
|
</head>
|
||||||
|
|
||||||
<head>
|
<body>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<div id="version-container">
|
||||||
<link rel="stylesheet" href="css/styles.css">
|
<p class="version">(v<span id="version"></span>)</p>
|
||||||
</head>
|
</div>
|
||||||
|
<div class="card options-card" id="header">
|
||||||
<body>
|
<h2 class="options-header"><u>Options</u></h2>
|
||||||
<div class="card" style="width: 400px; margin-left:auto;margin-right: auto; height:auto;" id="header">
|
<div id="options_container"></div>
|
||||||
<h2 style="padding:16px 16px 0px 16px;font-size: 20px"> <u>Options</u> </h2>
|
<p class="creator-tag"><a href="https://sghsri.github.io">Sriram Hariharan</a> (2018)</p>
|
||||||
<div id="options_container">
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p style="padding:0px 5px 5px 0px; float: right">(v<span id="version"></span>), Sriram Hariharan, 2018</p>
|
<div class="card options-card" id="contributors_container">
|
||||||
|
<h3 class="contributor-title">Amazing people who've contributed to the extension!</h3>
|
||||||
|
<p class="creator-tag open-source-tag">Code is open source here <a href="https://github.com/sghsri/UT-Registration-Plus">here</a> :)</p>
|
||||||
|
<div id="contributor-list"></div>
|
||||||
|
</div>
|
||||||
<script src="js/config.js"></script>
|
<script src="js/config.js"></script>
|
||||||
<script src="js/lib/jquery-3.3.1.min.js"></script>
|
<script src="js/lib/jquery-3.3.1.min.js"></script>
|
||||||
<script src="js/util.js"></script>
|
<script src="js/util.js"></script>
|
||||||
<script src="js/Template.js"></script>
|
<script src="js/Template.js"></script>
|
||||||
<script src="js/options.js"></script>
|
<script src="js/options.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
Reference in New Issue
Block a user