diff --git a/src/background.js b/src/background.js index 1f6b2b4..ecfab8d 100644 --- a/src/background.js +++ b/src/background.js @@ -57,9 +57,7 @@ const Rbutr = () => { }; const ZERO = 0; - const ONE = 1; const FIRST_ARRAY_ELEMENT = 0; - const NO_MATCH_CODE = -1; const COLOR_VAL_ZERO = 0; const COLOR_VAL_HALF = 100; @@ -298,67 +296,60 @@ const Rbutr = () => { const tabLoaded = (tabId, url) => { setProp('rebuttals', tabId, null); - let vote = false; + let canVote = false; let recordedClick = getRecordedClickByToUrl(getProp('canonicalUrls', tabId)); // Don't show voting after you've voted if (recordedClick !== null && recordedClick.yourVote && recordedClick.yourVote === ZERO) { - vote = true; + canVote = true; } - $.get(api.getServerUrl(), { - getLinks: true, - fromPageUrlHash: b64_md5(url), - version: browser.runtime.getManifest().version, - cid: api.getCid() - }, (data) => { - rbutr.setProp('rebuttals', tabId, data); - rbutr.setProp('loggedIn', null, true); + rbutr.api.getRebuttals(b64_md5(url), (success, result) => { + if (success === true) { + let titleMessage = ''; - let m = rbutr.getProp('rebuttals', tabId).match(/id="not-logged-in"/g); - let titleMessage = ''; + const hasRebuttals = result.match(/No Rebuttals/g) === null; + const isLoggedIn = result.match(/id="not-logged-in"/g) === null; + rbutr.setProp('loggedIn', null, isLoggedIn); + + rbutr.setProp('rebuttals', tabId, result); + + if (hasRebuttals) { + let matches = result.match(/class="thumbsUp"/g); + let count = matches === null ? ZERO : matches.length; + rbutr.setProp('rebuttalCount', tabId, count); + + if (canVote && isLoggedIn) { + titleMessage = `You can vote on this, and there are also ${count} rebuttal(s).`; + utils.setExtTitle(tabId, titleMessage); + utils.setExtBadgeText(tabId, 'V ' + count); + utils.setExtBadgeBg(tabId, COLOR_LIGHT_RED); + } else { + titleMessage = `This page has ${count} rebuttal(s).`; + utils.setExtTitle(tabId, titleMessage); + utils.setExtBadgeText(tabId, count); + utils.setExtBadgeBg(tabId, COLOR_RED); + } - if (m !== null && m.length > ZERO) { - rbutr.setProp('loggedIn', null, false); - } - if (rbutr.getProp('rebuttals', tabId).indexOf('

No Rebuttals


') !== NO_MATCH_CODE) { - rbutr.setProp('rebuttalCount', tabId, ZERO); - // No rebuttals - browser.browserAction.setBadgeText({text: '', tabId: tabId}); - if (vote && rbutr.getProp('loggedIn')) { - browser.browserAction.setBadgeText({text: 'Vote', tabId: tabId}); - browser.browserAction.setBadgeBackgroundColor({color: COLOR_MAGENTA, tabId: tabId}); - titleMessage = 'You can vote on this.'; - browser.browserAction.setTitle({tabId: tabId, title: titleMessage}); rbutr.postMessage('showMessageBox', {message: titleMessage, url: rbutr.getProp('canonicalUrls', tabId)}); + } else { - browser.browserAction.setTitle({ - tabId: tabId, - title: 'RbutR - There are no rebuttals to this page, do you know of one?' - }); + rbutr.setProp('rebuttalCount', tabId, ZERO); + + if (canVote && isLoggedIn) { + titleMessage = 'You can vote on this.'; + utils.setExtTitle(tabId, titleMessage); + utils.setExtBadgeText(tabId, 'Vote'); + utils.setExtBadgeBg(tabId, COLOR_MAGENTA); + rbutr.postMessage('showMessageBox', {message: titleMessage, url: rbutr.getProp('canonicalUrls', tabId)}); + } else { + utils.setExtBadgeText(tabId, ''); + utils.setExtTitle(tabId, 'RbutR - There are no rebuttals to this page, do you know of one?'); + } } } else { - let matches = rbutr.getProp('rebuttals', tabId).match(/class="thumbsUp"/g); - let count = Number(matches === null ? ZERO : matches.length); - rbutr.setProp('rebuttalCount', tabId, count); - let rebuttal_plural = count === ONE ? 'rebuttal' : 'rebuttals'; - - if (vote && rbutr.getProp('loggedIn')) { - browser.browserAction.setBadgeText({text: 'V ' + count.toString(), tabId: tabId}); - browser.browserAction.setBadgeBackgroundColor({color: COLOR_LIGHT_RED, tabId: tabId}); - titleMessage = 'You can vote on this, and there is also ' + count + ' ' + rebuttal_plural + '.'; - browser.browserAction.setTitle({tabId: tabId, title: titleMessage}); - } else { - browser.browserAction.setBadgeText({text: count.toString(), tabId: tabId}); - browser.browserAction.setBadgeBackgroundColor({color: COLOR_RED, tabId: tabId}); - titleMessage = 'This page has ' + count + ' ' + rebuttal_plural + '.'; - browser.browserAction.setTitle({tabId: tabId, title: titleMessage}); - } - - rbutr.postMessage('showMessageBox', {message: titleMessage, url: rbutr.getProp('canonicalUrls', tabId)}); + getPopup().msg.add('error', result); } - }).error((msg) => { - rbutr.setProp('rebuttals', tabId, msg.responseText); }); }; diff --git a/src/rbutrApi.js b/src/rbutrApi.js index 6e75a13..f4805df 100644 --- a/src/rbutrApi.js +++ b/src/rbutrApi.js @@ -83,9 +83,7 @@ const RbutrApi = (utils) => { return domain + apiPath; }; - /* - const getRebuttals = () => {}; const postRebuttals = () => {}; const requestRebuttals = () => {}; const getTags = () => {}; @@ -105,10 +103,48 @@ const RbutrApi = (utils) => { const url = utils.buildUrl(getServerUrl(false), { getMenu: true, - version: browser.runtime.getManifest().version, + version: utils.getExtVersion, cid: getCid() }); + makeRequest(url, 'POST', callback); + }; + + + + /** + * @method getRebuttals + * @description Load menu from server and show message afterwards + * + * @param {String} urlHash - MD5 Hash of the desired rebuttal URL + * @param {Function} callback - Callback function to execute + * @return {void} + */ + const getRebuttals = (urlHash, callback) => { + + const url = utils.buildUrl(getServerUrl(), { + getLinks: true, + fromPageUrlHash: urlHash, + version: utils.getExtVersion, + cid: getCid() + }); + + makeRequest(url, 'GET', callback); + }; + + + + /** + * @method makeRequest + * @description Make a request to the server + * + * @param {String} url - Request URL + * @param {String} method - Request method, either "GET" or "POST" + * @param {Function} callback - Callback function to execute + * @return {void} + */ + const makeRequest = (url, method, callback) => { + fetch(url, {method: 'POST'}).then((response) => { if (response.ok) { return response.text(); @@ -119,10 +155,10 @@ const RbutrApi = (utils) => { callback(true, html); }).catch((error) => { callback(false, error.message); - utils.log('error', 'There has been a problem with your fetch operation: ' + error.message); + utils.log('error', 'There has been a problem with your fetch operation: ', error.message); }); }; - return {getCid, getServerUrl, getMenu}; + return {getCid, getServerUrl, getMenu, getRebuttals, makeRequest}; }; diff --git a/src/utils.js b/src/utils.js index 8cb8e71..dc55639 100644 --- a/src/utils.js +++ b/src/utils.js @@ -6,11 +6,24 @@ * Licensed under LGPL-3.0 */ -/*global console,JSON,*/ +/*global browser,console,JSON,*/ /*exported RbutrUtils*/ /*jslint browser:true,esnext:true */ +/** + * @description Multi-Browser support + */ +window.browser = (() => { + + 'use strict'; + + return window.msBrowser || + window.browser || + window.chrome; +})(); + + /** * @method RbutrUtils @@ -58,6 +71,24 @@ const RbutrUtils = () => { + /** + * @method getExtVersion + * @description Get extension version. Moved to separate method to make testing possible + * + * @return {String} Extension version + */ + const getExtVersion = () => { + const runtime = browser.runtime; + + if (typeof runtime === 'object') { + return runtime.getManifest().version; + } else { + return '0.1'; + } + }; + + + /** * @method isDev * @description Determine, wether development mode is enabled or not @@ -131,5 +162,59 @@ const RbutrUtils = () => { - return {log, isDev, url2Domain, unicode2String, buildUrl}; + /** + * @method setExtBadgeText + * @description Display a small badge on extension button with a given text + * + * @param {Integer} tabId - Current browser tab ID + * @param {*} text - Text to be displayed in the badge + * @return {void} + */ + const setExtBadgeText = (tabId, text) => { + + browser.browserAction.setBadgeText({ + tabId: tabId, + text: text.toString(), + }); + }; + + + + /** + * @method setExtBadgeBg + * @description Set badge background color + * + * @param {Integer} tabId - Current browser tab ID + * @param {Array} color - An array containing RGBA values + * @return {void} + */ + const setExtBadgeBg = (tabId, color) => { + + browser.browserAction.setBadgeBackgroundColor({ + tabId: tabId, + color: color, + }); + }; + + + + /** + * @method setExtTitle + * @description Set Hover-Text on extension button + * + * @param {Integer} tabId - Current browser tab ID + * @param {String} title - Text to be displayed on hover + * @return {void} + */ + const setExtTitle = (tabId, title) => { + + browser.browserAction.setTitle({ + tabId: tabId, + title: title, + }); + }; + + + + return {log, getExtVersion, isDev, url2Domain, unicode2String, buildUrl, setExtBadgeText, setExtBadgeBg, setExtTitle}; }; diff --git a/test/test.api.js b/test/test.api.js index 72fa08a..73e6778 100644 --- a/test/test.api.js +++ b/test/test.api.js @@ -37,8 +37,8 @@ describe('RbutrApi', () => { it('should return an object', () => { assert.strictEqual(typeof RbutrApi(), 'object'); }); - it('should return an object containing 3 properties', () => { - assert.strictEqual(Object.keys(RbutrApi()).length, 3); + it('should return an object containing 5 properties', () => { + assert.strictEqual(Object.keys(RbutrApi()).length, 5); }); }); diff --git a/test/test.utils.js b/test/test.utils.js index 37d7171..05d87a1 100644 --- a/test/test.utils.js +++ b/test/test.utils.js @@ -22,8 +22,8 @@ describe('Utils', function() { it('should return an object', function() { assert.strictEqual(typeof RbutrUtils(), 'object'); }); - it('should return an object containing 5 properties', () => { - assert.strictEqual(Object.keys(RbutrUtils()).length, 6); + it('should return an object containing 9 properties', () => { + assert.strictEqual(Object.keys(RbutrUtils()).length, 9); }); }); @@ -40,32 +40,6 @@ describe('Utils', function() { }); }); - describe('#RbutrUtils.getServerUrl()', function() { - afterEach(() => { - localStorage.clear(); - }); - it('should return https://russell.rbutr.com/rbutr/PluginServlet in dev mode', function() { - localStorage.setItem('rbutr.isDev', 'true'); - assert.strictEqual(RbutrUtils().getServerUrl(), 'https://russell.rbutr.com/rbutr/PluginServlet'); - }); - it('should return http://rbutr.com/rbutr/PluginServlet in productive mode', function() { - assert.strictEqual(RbutrUtils().getServerUrl(), 'http://rbutr.com/rbutr/PluginServlet'); - }); - }); - - describe('#RbutrUtils.getServerUrl(true)', function() { - afterEach(() => { - localStorage.clear(); - }); - it('should return https://russell.rbutr.com in dev mode', function() { - localStorage.setItem('rbutr.isDev', 'true'); - assert.strictEqual(RbutrUtils().getServerUrl(true), 'https://russell.rbutr.com'); - }); - it('should return http://rbutr.com in productive mode', function() { - assert.strictEqual(RbutrUtils().getServerUrl(true), 'http://rbutr.com'); - }); - }); - describe('#RbutrUtils.url2Domain()', function() { it('should extract domain from url', function() { var url = 'https://www.google.com/search?q=rbutr';