Implement some tweaks and fixes for minification

This commit is contained in:
chylex 2017-05-20 22:23:13 +02:00
parent ed68136e25
commit 03bc03c51d
8 changed files with 124 additions and 118 deletions

View File

@ -20,4 +20,13 @@ t
m
f
e
a
a
author
id
username
timestamp
content
edited_timestamp
mentions
embeds
attachments

View File

@ -13,28 +13,32 @@ var DOM = (function(){
/*
* Returns a child element by its ID. Parent defaults to the entire document.
*/
id: function(id, parent){
return (parent || document).getElementById(id);
},
id: (id, parent) => (parent || document).getElementById(id),
/*
* Returns an array of all child elements containing the specified class. Parent defaults to the entire document.
*/
cls: function(cls, parent){
return Array.prototype.slice.call((parent || document).getElementsByClassName(cls));
},
cls: (cls, parent) => Array.prototype.slice.call((parent || document).getElementsByClassName(cls)),
/*
* Returns an array of all child elements that have the specified tag. Parent defaults to the entire document.
*/
tag: function(tag, parent){
return Array.prototype.slice.call((parent || document).getElementsByTagName(tag));
},
tag: (tag, parent) => Array.prototype.slice.call((parent || document).getElementsByTagName(tag)),
/*
* Returns the first child element containing the specified class. Parent defaults to the entire document.
*/
fcls: (cls, parent) => (parent || document).getElementsByClassName(cls)[0],
/*
* Returns the first child element that has the specified tag. Parent defaults to the entire document.
*/
ftag: (tag, parent) => (parent || document).getElementsByTagName(tag)[0],
/*
* Creates an element, adds it to the DOM, and returns it.
*/
createElement: function(tag, parent){
createElement: (tag, parent) => {
var ele = document.createElement(tag);
parent.appendChild(ele);
return ele;
@ -43,15 +47,11 @@ var DOM = (function(){
/*
* Removes an element from the DOM.
*/
removeElement: function(ele){
ele.parentNode.removeChild(ele);
},
removeElement: (ele) => ele.parentNode.removeChild(ele),
/*
* Converts characters to their HTML entity form.
*/
escapeHTML: function(html){
return String(html).replace(entityRegex, s => entityMap[s]);
}
escapeHTML: (html) => String(html).replace(entityRegex, s => entityMap[s])
};
})();

View File

@ -75,7 +75,7 @@ var GUI = (function(){
eventOnOptMessagesPerPageChanged && eventOnOptMessagesPerPageChanged();
});
Array.prototype.forEach.call(DOM.tag("button", DOM.cls("nav")[0]), button => {
DOM.tag("button", DOM.fcls("nav")).forEach(button => {
button.disabled = true;
button.addEventListener("click", () => {
@ -164,7 +164,7 @@ var GUI = (function(){
Array.prototype.forEach.call(eleChannels.children, ele => {
ele.addEventListener("click", e => {
var currentChannel = DOM.cls("active", eleChannels)[0];
var currentChannel = DOM.fcls("active", eleChannels);
if (currentChannel){
currentChannel.classList.remove("active");

View File

@ -1,11 +1,13 @@
var SAVEFILE = function(parsedObj){
this.meta = parsedObj.meta;
this.meta.users = this.meta.users || {};
this.meta.userindex = this.meta.userindex || [];
this.meta.servers = this.meta.servers || [];
this.meta.channels = this.meta.channels || {};
var me = this;
this.data = parsedObj.data;
me.meta = parsedObj.meta;
me.meta.users = me.meta.users || {};
me.meta.userindex = me.meta.userindex || [];
me.meta.servers = me.meta.servers || [];
me.meta.channels = me.meta.channels || {};
me.data = parsedObj.data;
};
SAVEFILE.isValid = function(parsedObj){

View File

@ -6,7 +6,7 @@ var DISCORD = (function(){
* Sets up a callback hook to trigger whenever a message request returns a response (the callback is given the channel ID and message array).
*/
setupMessageRequestHook: function(callback){
HOOKS.onAjaxResponse(function(args, req){
HOOKS.onAjaxResponse((args, req) => {
var match = args[1].match(regexMessageRequest);
if (match){
@ -26,18 +26,18 @@ var DISCORD = (function(){
getSelectedChannel: function(){
var obj;
var channelListEle = DOM.cls("private-channels")[0];
var channelListEle = DOM.fcls("private-channels");
var channel;
if (channelListEle){
channel = DOM.cls("selected", channelListEle)[0];
channel = DOM.fcls("selected", channelListEle);
if (!channel || !channel.classList.contains("private")){
return null;
}
else{
var linkSplit = DOM.tag("a", channel)[0].getAttribute("href").split("/");
var name = [].find.call(DOM.cls("channel-name", channel)[0].childNodes, node => node.nodeType === Node.TEXT_NODE).nodeValue;
var linkSplit = DOM.ftag("a", channel).href.split("/");
var name = [].find.call(DOM.fcls("channel-name", channel).childNodes, node => node.nodeType === Node.TEXT_NODE).nodeValue;
obj = {
"server": name,
@ -48,18 +48,18 @@ var DISCORD = (function(){
}
}
else{
channelListEle = DOM.cls("guild-channels")[0];
channel = channelListEle && DOM.cls("selected", channelListEle)[0];
channelListEle = DOM.fcls("guild-channels");
channel = channelListEle && DOM.fcls("selected", channelListEle);
if (!channel){
return null;
}
else{
var linkSplit = DOM.tag("a", channel)[0].getAttribute("href").split("/");
var linkSplit = DOM.ftag("a", channel).href.split("/");
obj = {
"server": DOM.tag("span", DOM.cls("guild-header")[0])[0].innerHTML,
"channel": DOM.cls("channel-name", DOM.cls("selected", channelListEle)[0])[0].innerHTML,
"server": DOM.ftag("span", DOM.fcls("guild-header")).innerHTML,
"channel": DOM.fcls("channel-name", DOM.fcls("selected", channelListEle)).innerHTML,
"id": linkSplit[linkSplit.length-1],
"type": "SERVER"
};
@ -72,36 +72,30 @@ var DISCORD = (function(){
/*
* Returns true if the message column is visible.
*/
isInMessageView: function(){
return DOM.cls("messages").length > 0;
},
isInMessageView: (_) => DOM.cls("messages").length > 0,
/*
* Returns true if there are more messages available.
*/
hasMoreMessages: function(){
return DOM.cls("messages")[0].children[0].classList.contains("has-more");
},
hasMoreMessages: (_) => DOM.fcls("messages").children[0].classList.contains("has-more"),
/*
* Forces the message column to scroll all the way up to load older messages.
*/
loadOlderMessages: function(){
DOM.cls("messages")[0].scrollTop = 0;
},
loadOlderMessages: (_) => DOM.fcls("messages").scrollTop = 0,
/*
* Selects the next text channel and returns true, otherwise returns false if there are no more channels.
*/
selectNextTextChannel: function(){
var nextChannel = DOM.cls("selected", DOM.cls("channels-wrap")[0])[0].nextElementSibling;
var nextChannel = DOM.fcls("selected", DOM.fcls("channels-wrap")).nextElementSibling;
var classes = nextChannel && nextChannel.classList;
if (nextChannel === null || !classes.contains("channel") || !(classes.contains("private") || classes.contains("channel-text"))){
return false;
}
else{
DOM.tag("a", nextChannel)[0].click();
DOM.ftag("a", nextChannel).click();
return true;
}
}

View File

@ -23,76 +23,71 @@ var DOM = (function(){
return obj;
};
var createElement = (tag, parent) => {
var ele = document.createElement(tag);
parent.appendChild(ele);
return ele;
};
return {
/*
* Returns a child element by its ID. Parent defaults to the entire document.
*/
id: function(id, parent){
return (parent || document).getElementById(id);
},
id: (id, parent) => (parent || document).getElementById(id),
/*
* Returns an array of all child elements containing the specified class. Parent defaults to the entire document.
*/
cls: function(cls, parent){
return Array.prototype.slice.call((parent || document).getElementsByClassName(cls));
},
cls: (cls, parent) => Array.prototype.slice.call((parent || document).getElementsByClassName(cls)),
/*
* Returns an array of all child elements that have the specified tag. Parent defaults to the entire document.
*/
tag: function(tag, parent){
return Array.prototype.slice.call((parent || document).getElementsByTagName(tag));
},
tag: (tag, parent) => Array.prototype.slice.call((parent || document).getElementsByTagName(tag)),
/*
* Returns the first child element containing the specified class. Parent defaults to the entire document.
*/
fcls: (cls, parent) => (parent || document).getElementsByClassName(cls)[0],
/*
* Returns the first child element that has the specified tag. Parent defaults to the entire document.
*/
ftag: (tag, parent) => (parent || document).getElementsByTagName(tag)[0],
/*
* Creates an element, adds it to the DOM, and returns it.
*/
createElement: function(tag, parent){
var ele = document.createElement(tag);
parent.appendChild(ele);
return ele;
},
createElement: (tag, parent) => createElement(tag, parent),
/*
* Removes an element from the DOM.
*/
removeElement: function(ele){
ele.parentNode.removeChild(ele);
},
removeElement: (ele) => ele.parentNode.removeChild(ele),
/*
* Creates a new style element with the specified CSS contents and returns it.
*/
createStyle: function(styles){
var ele = document.createElement("style");
document.head.appendChild(ele);
styles.forEach(function(style){
ele.sheet.insertRule(style, 0);
});
createStyle: (styles) => {
var ele = createElement("style", document.head);
styles.forEach(rule => ele.sheet.insertRule(rule, 0));
return ele;
},
/*
* Runs a callback function after a set amount of time. Returns an object which contains several functions and properties for easy management.
*/
setTimer: function(callback, timeout){
return setupTimerFunction(window.setTimeout, window.clearTimeout, callback, timeout);
},
setTimer: (callback, timeout) => setupTimerFunction(window.setTimeout, window.clearTimeout, callback, timeout),
/*
* Runs a callback function periodically after a set amount of time. Returns an object which contains several functions and properties for easy management.
* Convenience addEventListener function to save space after minification.
*/
setInterval: function(callback, interval){
return setupTimerFunction(window.setInterval, window.clearInterval, callback, interval);
},
listen: (ele, event, callback) => ele.addEventListener(event, callback),
/*
* Triggers a UTF-8 text file download.
*/
downloadTextFile: function(fileName, fileContents){
downloadTextFile: (fileName, fileContents) => {
var blob = new Blob([fileContents], { "type": "octet/stream" });
var url = window.URL.createObjectURL(blob);

View File

@ -80,18 +80,20 @@ var GUI = (function(){
// main
var btn = (id, title) => "<button id='dht-ctrl-"+id+"'>"+title+"</button>";
controller.ele = DOM.createElement("div", document.body);
controller.ele.id = "dht-ctrl";
controller.ele.innerHTML = [
"<button id='dht-ctrl-upload'>Upload &amp; Combine</button>",
"<button id='dht-ctrl-settings'>Settings</button>",
"<button id='dht-ctrl-track'></button>",
"<button id='dht-ctrl-download'>Download</button>",
"<button id='dht-ctrl-reset'>Reset</button>",
btn("upload", "Upload &amp; Combine"),
btn("settings", "Settings"),
btn("track", ""),
btn("download", "Download"),
btn("reset", "Reset"),
"<p id='dht-ctrl-status'></p>",
"<input id='dht-ctrl-upload-input' type='file' multiple>",
"<button id='dht-ctrl-close'>X</button>"
btn("close", "X")
].join("");
// elements
@ -109,33 +111,33 @@ var GUI = (function(){
// events
controller.ui.btnUpload.addEventListener("click", () => {
DOM.listen(controller.ui.btnUpload, "click", () => {
controller.ui.inputUpload.click();
});
controller.ui.btnSettings.addEventListener("click", () => {
DOM.listen(controller.ui.btnSettings, "click", () => {
root.showSettings();
});
controller.ui.btnToggleTracking.addEventListener("click", () => {
DOM.listen(controller.ui.btnToggleTracking, "click", () => {
STATE.toggleTracking();
});
controller.ui.btnDownload.addEventListener("click", () => {
DOM.listen(controller.ui.btnDownload, "click", () => {
STATE.downloadSavefile();
});
controller.ui.btnReset.addEventListener("click", () => {
DOM.listen(controller.ui.btnReset, "click", () => {
STATE.resetState();
root.showSettings();
});
controller.ui.btnClose.addEventListener("click", () => {
DOM.listen(controller.ui.btnClose, "click", () => {
root.hideController();
window.DHT_LOADED = false;
});
controller.ui.inputUpload.addEventListener("change", () => {
DOM.listen(controller.ui.inputUpload, "change", () => {
for(var file of controller.ui.inputUpload.files){
var reader = new FileReader();
@ -191,7 +193,7 @@ var GUI = (function(){
settings.overlay = DOM.createElement("div", document.body);
settings.overlay.id = "dht-cfg-overlay";
settings.overlay.addEventListener("click", () => {
DOM.listen(settings.overlay, "click", () => {
root.hideSettings();
});
@ -200,18 +202,20 @@ var GUI = (function(){
settings.ele = DOM.createElement("div", document.body);
settings.ele.id = "dht-cfg";
var radio = (type, id, label) => "<label><input id='dht-cfg-"+type+"-"+id+"' name='dht-"+type+"' type='radio'> "+label+"</label><br>";
settings.ele.innerHTML = [
"<label><input id='dht-cfg-autoscroll' type='checkbox'> Autoscroll</label><br>",
"<br>",
"<label>After reaching the first message in channel...</label><br>",
"<label><input id='dht-cfg-afm-nothing' name='dht-afm' type='radio'> Do Nothing</label><br>",
"<label><input id='dht-cfg-afm-pause' name='dht-afm' type='radio'> Pause Tracking</label><br>",
"<label><input id='dht-cfg-afm-switch' name='dht-afm' type='radio'> Switch to Next Channel</label><br>",
radio("afm", "nothing", "Do Nothing"),
radio("afm", "pause", "Pause Tracking"),
radio("afm", "switch", "Switch to Next Channel"),
"<br>",
"<label>After reaching a previously saved message...</label><br>",
"<label><input id='dht-cfg-asm-nothing' name='dht-asm' type='radio'> Do Nothing</label><br>",
"<label><input id='dht-cfg-asm-pause' name='dht-asm' type='radio'> Pause Tracking</label><br>",
"<label><input id='dht-cfg-asm-switch' name='dht-asm' type='radio'> Switch to Next Channel</label><br>",
radio("asm", "nothing", "Do Nothing"),
radio("asm", "pause", "Pause Tracking"),
radio("asm", "switch", "Switch to Next Channel"),
"<p id='dht-cfg-note'>",
"Tracking will only trigger when Discord loads new messages. ",
"To ensure that all messages are saved, go to your Friends list to avoid loading any messages, refresh the website, and run the script again.",
@ -245,13 +249,13 @@ var GUI = (function(){
});
Object.keys(settings.ui.optsAfterFirstMsg).forEach(key => {
settings.ui.optsAfterFirstMsg[key].addEventListener("click", () => {
DOM.listen(settings.ui.optsAfterFirstMsg[key], "click", () => {
STATE.settings.afterFirstMsg = key;
});
});
Object.keys(settings.ui.optsAfterSavedMsg).forEach(key => {
settings.ui.optsAfterSavedMsg[key].addEventListener("click", () => {
DOM.listen(settings.ui.optsAfterSavedMsg[key], "click", () => {
STATE.settings.afterSavedMsg = key;
});
});

View File

@ -66,29 +66,31 @@
*/
var SAVEFILE = function(parsedObj){
var me = this;
if (SAVEFILE.isValid(parsedObj)){
this.meta = parsedObj.meta;
this.meta.users = this.meta.users || {};
this.meta.userindex = this.meta.userindex || [];
this.meta.servers = this.meta.servers || [];
this.meta.channels = this.meta.channels || {};
me.meta = parsedObj.meta;
me.meta.users = me.meta.users || {};
me.meta.userindex = me.meta.userindex || [];
me.meta.servers = me.meta.servers || [];
me.meta.channels = me.meta.channels || {};
this.data = parsedObj.data;
me.data = parsedObj.data;
}
else{
this.meta = {};
this.meta.users = {};
this.meta.userindex = [];
this.meta.servers = [];
this.meta.channels = {};
this.data = {};
me.meta = {};
me.meta.users = {};
me.meta.userindex = [];
me.meta.servers = [];
me.meta.channels = {};
me.data = {};
}
this.tmp = {};
this.tmp.userlookup = {};
this.tmp.channelkeys = new Set();
this.tmp.messagekeys = new Set();
me.tmp = {};
me.tmp.userlookup = {};
me.tmp.channelkeys = new Set();
me.tmp.messagekeys = new Set();
};
SAVEFILE.isValid = function(parsedObj){