diff --git a/Firefox/@betterdiscord-0.0.1.xpi b/Firefox/@betterdiscord-0.0.1.xpi new file mode 100644 index 0000000..6fbd52d Binary files /dev/null and b/Firefox/@betterdiscord-0.0.1.xpi differ diff --git a/Firefox/data/css/main.css b/Firefox/data/css/main.css new file mode 100644 index 0000000..b76d867 --- /dev/null +++ b/Firefox/data/css/main.css @@ -0,0 +1,3 @@ +.guilds { + background:red !important; +} \ No newline at end of file diff --git a/Firefox/data/js/main.js b/Firefox/data/js/main.js new file mode 100644 index 0000000..bce3fc3 --- /dev/null +++ b/Firefox/data/js/main.js @@ -0,0 +1,199 @@ +var emotesTwitch = null, emotesTwitchSub = null, emotesFfz = null, emotesBttv = null, emotesBttv2 = null; + +var twitchEmoteUrlStart = "https://static-cdn.jtvnw.net/emoticons/v1/"; +var twitchEmoteUrlEnd = "/1.0"; +var ffzEmoteUrlStart = "https://cdn.frankerfacez.com/emoticon/"; +var ffzEmoteUrlEnd = "/1"; +var bttvEmoteUrlStart = "https://cdn.betterttv.net/emote/"; +var bttvEmoteUrlEnd = "/1x"; + +var _emoteModule; +function EmoteModule() { + +} + +EmoteModule.prototype.init = function() { + _emoteModule.loadEmoteData(); +}; + +EmoteModule.prototype.obsCallback = function(mutation) { + var self = this; + for(var i = 0 ; i < mutation.addedNodes.length ; ++i) { + var next = mutation.addedNodes.item(i); + if (next) { + var nodes = self.getNodes(next); + for(var node in nodes) { + if (nodes.hasOwnProperty(node)) { + self.injectEmote(nodes[node]); + } + } + } + } +}; + +EmoteModule.prototype.getNodes = function(node) { + var next; + var nodes = []; + var treeWalker = document.createTreeWalker(node, NodeFilter.SHOW_TEXT, null, false); + + while((next = treeWalker.nextNode()) != null) { + nodes.push(next); + } + return nodes; +}; + +EmoteModule.prototype.injectEmote = function(node) { + + if (!node.parentElement) { + return; + } + + var parent = node.parentElement; + if (parent.tagName != "SPAN") { + return; + } + if(!$(parent.parentElement).hasClass("markup") && !$(parent.parentElement).hasClass("message-content")) { return; } + + var parentInnerHTML = parent.innerHTML; + var words = parentInnerHTML.split(/\s+/g); + if (!words) { + return; + } + + words.some(function(word) { + if (word.length < 4) { + return; + } + if(emotesTwitch != null) { + if (emotesTwitch.emotes.hasOwnProperty(word)) { + var len = Math.round(word.length / 4); + parentInnerHTML = parentInnerHTML.replace(word, '' + word.substr(0, len) + '); + return; + } + } + if(emotesTwitchSub != null) { + if (emotesTwitchSub.hasOwnProperty(word)) { + var len = Math.round(word.length / 4); + parentInnerHTML = parentInnerHTML.replace(word, '' + word.substr(0, len) + '); + return; + } + } + if(emotesFfz != null) { + if(emotesFfz.hasOwnProperty(word)) { + var len = Math.round(word.length / 4); + parentInnerHTML = parentInnerHTML.replace(word, '' + word.substr(0, len) + '); + return; + } + } + if(emotesBttv != null) { + if(emotesBttv.hasOwnProperty(word)) { + var len = Math.round(word.length / 4); + parentInnerHTML = parentInnerHTML.replace(word, '' + word.substr(0, len) + '); + return; + } + } + if(emotesBttv2 != null) { + if(emotesBttv2.hasOwnProperty(word)) { + var len = Math.round(word.length / 4); + parentInnerHTML = parentInnerHTML.replace(word, '' + word.substr(0, len) + '); + return; + } + } + }); + + parent.innerHTML = parentInnerHTML.replace(new RegExp("\uFDD9", "g"), ""); +}; + +EmoteModule.prototype.loadEmoteData = function(type) { + if(_hash == null) { + _utils.getHash(this.loadEmoteData); + return; + } + + switch(type) { + default: + _emoteModule.loadEmoteData("twitch"); + break; + case "twitch": + _utils.log("Loading twitch global emotes"); + $.getJSON('https://twitchemotes.com/api_cache/v2/global.json', function(data) { + _utils.log("Loaded twitch global emotes"); + emotesTwitch = data; + _emoteModule.loadEmoteData("twitch-sub"); + }); + break; + case "twitch-sub": + emotesTwitchSub = {}; + _utils.log("Loading twitch subscriber emotes"); + $.getJSON('https://twitchemotes.com/api_cache/v2/subscriber.json', function(data) { + $.each(data.channels, function(key, val){ + $.each(val.emotes, function(key, val) { + emotesTwitchSub[val.code] = val.image_id; + }); + }); + + _emoteModule.loadEmoteData("ffz"); + }); + break; + case "ffz": + emotesFfz = {}; + _utils.log("Loading FFZ emotes"); + $.getJSON('https://cdn.rawgit.com/Jiiks/BetterDiscordApp/'+_hash+'/data/emotedata_ffz.json', function(data) { + emotesFfz = data; + _emoteModule.loadEmoteData("bttv"); + }); + break; + case "bttv": + emotesBttv = {}; + _utils.log("Loading Basic BTTV emotes"); + $.getJSON('https://api.betterttv.net/2/emotes', function(data) { + $.each(data.emotes, function(key, val) { + emotesBttv[val.code] = val.id; + }); + _emoteModule.loadEmoteData("bttv2"); + }); + break; + case "bttv2": + emotesBttv2 = {}; + _utils.log("Loading BTTV emotes"); + $.getJSON('https://cdn.rawgit.com/Jiiks/BetterDiscordApp/'+_hash+'/data/emotedata_bttv.json', function(data) { + emotesBttv2 = data; + }); + break; + } +}; + +var _utils; + +var _hash = null; +function Utils() {} + +Utils.prototype.getHash = function(callback) { + _utils.log("Getting HASH"); + $.getJSON("https://api.github.com/repos/Jiiks/BetterDiscordApp/commits/master", function(data){ + _hash = data.sha; + _utils.log("HASH = " + _hash); + callback(); + }); +}; + +Utils.prototype.log = function(message) { + console.log("[BetterDiscord] - " + message); +}; + +(function() { + + _utils = new Utils(); + + _emoteModule = new EmoteModule(); + _emoteModule.init(); + + var mainObserver = new MutationObserver(function(mutations) { + mutations.forEach(function(mutation) { + _emoteModule.obsCallback(mutation); + }); + }); + + mainObserver.observe(document, { childList: true, subtree: true }); + +})(); \ No newline at end of file diff --git a/Firefox/icon.png b/Firefox/icon.png new file mode 100644 index 0000000..5587df6 Binary files /dev/null and b/Firefox/icon.png differ diff --git a/Firefox/index.js b/Firefox/index.js deleted file mode 100644 index 3bbc578..0000000 --- a/Firefox/index.js +++ /dev/null @@ -1,9 +0,0 @@ -var self = require('sdk/self'); - -// a dummy function, to show how tests work. -// to see how to test this function, look at test/test-index.js -function dummy(text, callback) { - callback(text); -} - -exports.dummy = dummy; diff --git a/Firefox/lib/BdPageMod.js b/Firefox/lib/BdPageMod.js new file mode 100644 index 0000000..4a34339 --- /dev/null +++ b/Firefox/lib/BdPageMod.js @@ -0,0 +1,14 @@ +"use sctrict" + +var pageMod = require('sdk/page-mod'); +var data = require("sdk/self").data; + +function BdPageMod(options, callbacks) { + pageMod.PageMod({ + include: '*.discordapp.com', + contentScriptFile: [data.url('../data/js/jquery-2.1.4.min.js'), data.url('../data/js/main.js')], + contentStyleFile: [] + }); +} + +exports.BdPageMod = BdPageMod; \ No newline at end of file diff --git a/Firefox/lib/BetterDiscord.js b/Firefox/lib/BetterDiscord.js new file mode 100644 index 0000000..2933e39 --- /dev/null +++ b/Firefox/lib/BetterDiscord.js @@ -0,0 +1,9 @@ +"use strict" + +var _bdPagemod = require('./BdPageMod.js'); + +function BetterDiscord(args) { + _bdPagemod = new _bdPagemod.BdPageMod(); +} + +exports.BetterDiscord = BetterDiscord; \ No newline at end of file diff --git a/Firefox/lib/main.js b/Firefox/lib/main.js new file mode 100644 index 0000000..555d28f --- /dev/null +++ b/Firefox/lib/main.js @@ -0,0 +1,9 @@ +"use strict"; + +var _betterDiscord = require("./BetterDiscord.js"); + +function main(options, callbacks) { + _betterDiscord = new _betterDiscord.BetterDiscord(); +} + +exports.main = main; \ No newline at end of file diff --git a/Firefox/package.json b/Firefox/package.json index 70181b3..fdf4ad1 100644 --- a/Firefox/package.json +++ b/Firefox/package.json @@ -3,10 +3,10 @@ "name": "betterdiscord", "version": "0.0.1", "description": "BetterDiscord enhances Discord with several features", - "main": "index.js", - "author": "Jiiks", + "main": "lib/main", + "author": "JiCode", "engines": { - "firefox": ">=38.0a1" + "firefox": ">=30" }, "license": "MIT", "keywords": [