diff --git a/clearurls.js b/clearurls.js index bb59d23..05c15d2 100644 --- a/clearurls.js +++ b/clearurls.js @@ -3,386 +3,404 @@ * # Fetch Rules & Exception from URL # * ################################################################## */ -var data = []; var providers = []; var prvKeys = []; -var globalStatus; var badges = []; -var log = []; -var logging = false; -var badgedStatus; var tabid = 0; -var globalCounter; -var globalurlcounter; var siteBlockedAlert = 'javascript:void(0)'; var dataHash; var localDataHash; var os; -/** -* Save OS Version -*/ -browser.runtime.getPlatformInfo(function(info) { - os = info.os; +var storage = []; +getDataFromDisk(); + +function start(items) +{ + initStorage(items); /** - * Initialize the JSON provider object keys. - * - * @param {JSON Object} obj + * Save OS Version */ - function getKeys(obj){ - for(var key in obj){ - prvKeys.push(key); + browser.runtime.getPlatformInfo(function(info) { + + os = info.os; + + + /** + * Initialize the JSON provider object keys. + * + * @param {JSON Object} obj + */ + function getKeys(obj){ + for(var key in obj){ + prvKeys.push(key); + } } - } - /** - * Initialize the providers form the JSON object. - * - */ - function createProviders() - { - for(var p = 0; p < prvKeys.length; p++) + /** + * Initialize the providers form the JSON object. + * + */ + function createProviders() { - //Create new provider - providers.push(new Provider(prvKeys[p],data.providers[prvKeys[p]].completeProvider)); + data = storage.ClearURLsData; - //Add URL Pattern - providers[p].setURLPattern(data.providers[prvKeys[p]].urlPattern); - - //Add rules to provider - for(var r = 0; r < data.providers[prvKeys[p]].rules.length; r++) + for(var p = 0; p < prvKeys.length; p++) { - providers[p].addRule(data.providers[prvKeys[p]].rules[r]); - } + //Create new provider + providers.push(new Provider(prvKeys[p],data.providers[prvKeys[p]].completeProvider)); - //Add exceptions to provider - for(var e = 0; e < data.providers[prvKeys[p]].exceptions.length; e++) - { - providers[p].addException(data.providers[prvKeys[p]].exceptions[e]); - } + //Add URL Pattern + providers[p].setURLPattern(data.providers[prvKeys[p]].urlPattern); - //Add redirections to provider - for(var re = 0; re < data.providers[prvKeys[p]].redirections.length; re++) - { - providers[p].addRedirection(data.providers[prvKeys[p]].redirections[re]); - } - } - } - - /** - * Convert the external data to JSON Objects and - * call the create provider function. - * - * @param {String} retrievedText - pure data form github - */ - function toJSON(retrievedText) { - data = JSON.parse(retrievedText); - getKeys(data.providers); - createProviders(); - } - - /** - * Load local saved data, if the browser is offline or - * some other network trouble. - */ - function loadOldDataFromStore() - { - browser.storage.local.get('ClearURLsData', function(localData){ - if(localData.ClearURLsData){ - data = localData.ClearURLsData; - } - else { - data = ""; - } - - localDataHash = $.sha256(data); - - }); - } - - /** - * Save the hash status to the local storage. - * The status can have the following values: - * 1 "up to date" - * 2 "updated" - * 3 "update available" - * @param status_code the number for the status - */ - function storeHashStatus(status_code) - { - switch(status_code) - { - case 1: status_code = "up to date"; - break; - case 2: status_code = "updated"; - break; - case 3: status_code = "update available"; - break; - default: status_code = "error"; - } - browser.storage.local.set({"hashStatus": status_code}); - } - - /** - * Get the hash for the rule file on github. - * Check the hash with the hash form the local file. - * If the hash has changed, then download the new rule file. - * Else do nothing. - */ - function getHash() - { - //Get the target hash from github - fetch("https://raw.githubusercontent.com/KevinRoebert/ClearUrls/master/data/rules.hash?flush_cache=true") - .then(function(response){ - var responseTextHash = response.clone().text().then(function(responseTextHash){ - if(response.ok) + //Add rules to provider + for(var r = 0; r < data.providers[prvKeys[p]].rules.length; r++) { - dataHash = responseTextHash; + providers[p].addRule(data.providers[prvKeys[p]].rules[r]); + } - if($.trim(dataHash) !== $.trim(localDataHash)) + //Add exceptions to provider + for(var e = 0; e < data.providers[prvKeys[p]].exceptions.length; e++) + { + providers[p].addException(data.providers[prvKeys[p]].exceptions[e]); + } + + //Add redirections to provider + for(var re = 0; re < data.providers[prvKeys[p]].redirections.length; re++) + { + providers[p].addRedirection(data.providers[prvKeys[p]].redirections[re]); + } + } + } + + /** + * Convert the external data to JSON Objects and + * call the create provider function. + * + * @param {String} retrievedText - pure data form github + */ + function toJSON(retrievedText) { + storage.ClearURLsData = JSON.parse(retrievedText); + getKeys(storage.ClearURLsData.providers); + createProviders(); + } + + /** + * Load local saved data, if the browser is offline or + * some other network trouble. + */ + function loadOldDataFromStore() + { + localDataHash = $.sha256(storage.ClearURLsData); + } + + /** + * Save the hash status to the local storage. + * The status can have the following values: + * 1 "up to date" + * 2 "updated" + * 3 "update available" + * @param status_code the number for the status + */ + function storeHashStatus(status_code) + { + switch(status_code) + { + case 1: status_code = "up to date"; + break; + case 2: status_code = "updated"; + break; + case 3: status_code = "update available"; + break; + default: status_code = "error"; + } + + storage.hashStatus = status_code; + } + + /** + * Get the hash for the rule file on github. + * Check the hash with the hash form the local file. + * If the hash has changed, then download the new rule file. + * Else do nothing. + */ + function getHash() + { + //Get the target hash from github + fetch("http://127.0.0.1/clearurls/rules.hash") + .then(function(response){ + var responseTextHash = response.clone().text().then(function(responseTextHash){ + if(response.ok) { - fetchFromURL(); + dataHash = responseTextHash; + + if($.trim(dataHash) !== $.trim(localDataHash)) + { + fetchFromURL(); + } + else { + toJSON(storage.ClearURLsData); + storeHashStatus(1); + } } else { - toJSON(data); - storeHashStatus(1); + dataHash = false; } - } - else { - dataHash = false; - } + }); }); - }); - } + } - /** - * Fetch the Rules & Exception from github. - */ - function fetchFromURL() - { - fetch("https://raw.githubusercontent.com/KevinRoebert/ClearUrls/master/data/data.json?flush_cache=true") - .then(checkResponse); - - function checkResponse(response) + /** + * Fetch the Rules & Exception from github. + */ + function fetchFromURL() { - var responseText = response.clone().text().then(function(responseText){ - if(response.ok) - { - var downloadedFileHash = $.sha256(responseText); + fetch("http://127.0.0.1/clearurls/data.json") + .then(checkResponse); - if($.trim(downloadedFileHash) === $.trim(dataHash)) - { - data = responseText; - browser.storage.local.set({"ClearURLsData": responseText}); - storeHashStatus(2); - } - else { - storeHashStatus(3); - } - toJSON(data); - } - }); - } - } - - // ################################################################## - - /* - * ################################################################## - * # Supertyp Provider # - * ################################################################## - */ - /** - * Declare constructor - * - * @param {String} _name Provider name - * @param {boolean} completeProvider Set URL Pattern as rule - */ - function Provider(_name,_completeProvider = false){ - var name = _name; - var urlPattern; - var rules = []; - var exceptions = []; - var canceling = _completeProvider; - var redirections = []; - - if(_completeProvider){ - rules.push(".*"); - } - - /** - * Returns the provider name. - * @return {String} - */ - this.getName = function() { - return name; - }; - - /** - * Add URL pattern. - * - * @require urlPatterns as RegExp - */ - this.setURLPattern = function(urlPatterns) { - urlPattern = new RegExp(urlPatterns, "mgi"); - }; - - /** - * Return if the Provider Request is canceled - * @return {Boolean} isCanceled - */ - this.isCaneling = function() { - return canceling; - }; - - /** - * Check the url is matching the ProviderURL. - * - * @return {boolean} ProviderURL as RegExp - */ - this.matchURL = function(url) { - return !(this.matchException(url)) && urlPattern.test(url); - }; - - /** - * Add a rule to the rule array. - * - * @param String rule RegExp as string - */ - this.addRule = function(rule) { - rules.push(rule); - }; - - /** - * Return all rules as an array. - * - * @return Array RegExp strings - */ - this.getRules = function() { - return rules; - }; - - /** - * Add a exception to the exceptions array. - * - * @param String exception RegExp as string - */ - this.addException = function(exception) { - exceptions.push(exception); - }; - - /** - * Private helper method to check if the url - * an exception. - * - * @param {String} url RegExp as string - * @return {boolean} if matching? true: false - */ - this.matchException = function(url) { - var result = false; - - //Add the site blocked alert to every exception - if(url == siteBlockedAlert) return true; - - for (var i = 0; i < exceptions.length; i++) { - if(result) { break; } - - exception_regex = new RegExp(exceptions[i], "gi"); - result = exception_regex.test(url); - } - - return result; - }; - - /** - * Add a redirection to the redirections array. - * - * @param String redirection RegExp as string - */ - this.addRedirection = function(redirection) { - redirections.push(redirection); - }; - - /** - * Return all redirection. - * - * @return url - */ - this.getRedirection = function(url) { - var re = null; - - for(var i = 0; i < redirections.length; i++) + function checkResponse(response) { - result = (url.match(new RegExp(redirections[i], "gi"))); + var responseText = response.clone().text().then(function(responseText){ + if(response.ok) + { + var downloadedFileHash = $.sha256(responseText); - if (result && result.length > 0) - { - re = (new RegExp(redirections[i], "gi")).exec(url)[1]; + if($.trim(downloadedFileHash) === $.trim(dataHash)) + { + storage.ClearURLsData = responseText; + storeHashStatus(2); + } + else { + storeHashStatus(3); + } + toJSON(storage.ClearURLsData); + } + }); + } + } - break; - } + // ################################################################## + + /* + * ################################################################## + * # Supertyp Provider # + * ################################################################## + */ + /** + * Declare constructor + * + * @param {String} _name Provider name + * @param {boolean} completeProvider Set URL Pattern as rule + */ + function Provider(_name,_completeProvider = false){ + var name = _name; + var urlPattern; + var rules = []; + var exceptions = []; + var canceling = _completeProvider; + var redirections = []; + + if(_completeProvider){ + rules.push(".*"); } - return re; - }; - } - // ################################################################## - - /** - * Helper function which remove the tracking fields - * for each provider given as parameter. - * - * @param {Provider} provider Provider-Object - * @param {webRequest} request webRequest-Object - * @return {Array} Array with changes and url fields - */ - function removeFieldsFormURL(provider, request) - { - var url = request.url; - var rules = provider.getRules(); - var changes = false; - var cancel = false; - - if(provider.matchURL(url)) - { - /* - * Expand the url by provider redirections. So no tracking on - * url redirections form sites to sites. + /** + * Returns the provider name. + * @return {String} */ - var re = provider.getRedirection(url); - if(re !== null) - { - url = decodeURIComponent(re); - //Log the action - pushToLog(request.url, re, "This url is redirected."); + this.getName = function() { + return name; + }; - return { - "redirect": true, - "url": url - }; - } + /** + * Add URL pattern. + * + * @require urlPatterns as RegExp + */ + this.setURLPattern = function(urlPatterns) { + urlPattern = new RegExp(urlPatterns, "mgi"); + }; - for (var i = 0; i < rules.length; i++) { - var beforReplace = url; + /** + * Return if the Provider Request is canceled + * @return {Boolean} isCanceled + */ + this.isCaneling = function() { + return canceling; + }; - url = url.replace(new RegExp(rules[i], "gi"), ""); + /** + * Check the url is matching the ProviderURL. + * + * @return {boolean} ProviderURL as RegExp + */ + this.matchURL = function(url) { + return !(this.matchException(url)) && urlPattern.test(url); + }; - if(beforReplace != url) + /** + * Add a rule to the rule array. + * + * @param String rule RegExp as string + */ + this.addRule = function(rule) { + rules.push(rule); + }; + + /** + * Return all rules as an array. + * + * @return Array RegExp strings + */ + this.getRules = function() { + return rules; + }; + + /** + * Add a exception to the exceptions array. + * + * @param String exception RegExp as string + */ + this.addException = function(exception) { + exceptions.push(exception); + }; + + /** + * Private helper method to check if the url + * an exception. + * + * @param {String} url RegExp as string + * @return {boolean} if matching? true: false + */ + this.matchException = function(url) { + var result = false; + + //Add the site blocked alert to every exception + if(url == siteBlockedAlert) return true; + + for (var i = 0; i < exceptions.length; i++) { + if(result) { break; } + + exception_regex = new RegExp(exceptions[i], "gi"); + result = exception_regex.test(url); + } + + return result; + }; + + /** + * Add a redirection to the redirections array. + * + * @param String redirection RegExp as string + */ + this.addRedirection = function(redirection) { + redirections.push(redirection); + }; + + /** + * Return all redirection. + * + * @return url + */ + this.getRedirection = function(url) { + var re = null; + + for(var i = 0; i < redirections.length; i++) { - //Log the action - pushToLog(beforReplace, url, rules[i]); + result = (url.match(new RegExp(redirections[i], "gi"))); + if (result && result.length > 0) + { + re = (new RegExp(redirections[i], "gi")).exec(url)[1]; + + break; + } + } + + return re; + }; + } + // ################################################################## + + /** + * Helper function which remove the tracking fields + * for each provider given as parameter. + * + * @param {Provider} provider Provider-Object + * @param {webRequest} request webRequest-Object + * @return {Array} Array with changes and url fields + */ + function removeFieldsFormURL(provider, request) + { + var url = request.url; + var rules = provider.getRules(); + var changes = false; + var cancel = false; + + if(provider.matchURL(url)) + { + /* + * Expand the url by provider redirections. So no tracking on + * url redirections form sites to sites. + */ + var re = provider.getRedirection(url); + if(re !== null) + { + url = decodeURIComponent(re); + //Log the action + pushToLog(request.url, re, "This url is redirected."); + + return { + "redirect": true, + "url": url + }; + } + + for (var i = 0; i < rules.length; i++) { + var beforReplace = url; + + url = url.replace(new RegExp(rules[i], "gi"), ""); + + if(beforReplace != url) + { + //Log the action + pushToLog(beforReplace, url, rules[i]); + + if(badges[tabid] == null) + { + badges[tabid] = 0; + } + storage.globalCounter++; + + if(!checkOSAndroid()) + { + if(storage.badgedStatus) { + browser.browserAction.setBadgeText({text: (++badges[tabid]).toString(), tabId: tabid}); + } + else + { + browser.browserAction.setBadgeText({text: "", tabId: tabid}); + } + } + + changes = true; + } + } + + if(provider.isCaneling()){ + pushToLog(request.url, request.url, "This domain is blocked."); if(badges[tabid] == null) { badges[tabid] = 0; } - browser.storage.local.set({"globalCounter": ++globalCounter}); + storage.globalCounter++; + if(!checkOSAndroid()) { - if(badgedStatus) { + if(storage.badgedStatus) { browser.browserAction.setBadgeText({text: (++badges[tabid]).toString(), tabId: tabid}); } else @@ -391,118 +409,51 @@ browser.runtime.getPlatformInfo(function(info) { } } - changes = true; + cancel = true; } + + return { + "changes": changes, + "url": url, + "cancel": cancel + }; } - - if(provider.isCaneling()){ - pushToLog(request.url, request.url, "This domain is blocked."); - if(badges[tabid] == null) - { - badges[tabid] = 0; - } - - browser.storage.local.set({"globalCounter": ++globalCounter}); - if(!checkOSAndroid()) - { - if(badgedStatus) { - browser.browserAction.setBadgeText({text: (++badges[tabid]).toString(), tabId: tabid}); - } - else - { - browser.browserAction.setBadgeText({text: "", tabId: tabid}); - } - } - - cancel = true; + else { + return { + "changes": false + }; } - - return { - "changes": changes, - "url": url, - "cancel": cancel - }; } - else { - return { - "changes": false - }; - } - } - /** - * Return the number of parameters query strings. - * @param {String} url URL as String - * @return {int} Number of Parameters - */ - function countFields(url) - { - var matches = (url.match(/[^\/|\?|&]+=[^\/|\?|&]+/gi) || []); - var count = matches.length; - - return count; - } - - /** - * Function which called from the webRequest to - * remove the tracking fields from the url. - * - * @param {webRequest} request webRequest-Object - * @return {Array} redirectUrl or none - */ - function clearUrl(request) - { - if(globalurlcounter === null || typeof(globalurlcounter) == "undefined") + /** + * Return the number of parameters query strings. + * @param {String} url URL as String + * @return {int} Number of Parameters + */ + function countFields(url) { - /** - * Get the globalURLCounter value from the browser storage - * @param {(data){} Return value form browser.storage.local.get - */ - browser.storage.local.get('globalurlcounter', function(data){ - if(data.globalurlcounter){ - globalurlcounter = data.globalurlcounter; - } - else { - globalurlcounter = 0; - } + var matches = (url.match(/[^\/|\?|&]+=[^\/|\?|&]+/gi) || []); + var count = matches.length; - return clearUrl(request); - }); + return count; } - else if(globalCounter === null || typeof(globalCounter) == "undefined") { - /** - * Get the globalCounter value from the browser storage - * @param {(data){} Return value form browser.storage.local.get - */ - browser.storage.local.get('globalCounter', function(data){ - if(data.globalCounter){ - globalCounter = data.globalCounter; - } - else { - globalCounter = 0; - } - return clearUrl(request); - }); - } - else { + /** + * Function which called from the webRequest to + * remove the tracking fields from the url. + * + * @param {webRequest} request webRequest-Object + * @return {Array} redirectUrl or none + */ + function clearUrl(request) + { var URLbeforeReplaceCount = countFields(request.url); //Add Fields form Request to global url counter - globalurlcounter += URLbeforeReplaceCount; - browser.storage.local.set({"globalurlcounter": globalurlcounter}); - browser.storage.local.get('globalStatus', clear); + storage.globalurlcounter += URLbeforeReplaceCount; - function clear(data){ - globalStatus = data.globalStatus; - - if(globalStatus == null){ - globalStatus = true; - } - } - - if(globalStatus){ + if(storage.globalStatus){ var result = { "changes": false, @@ -548,237 +499,246 @@ browser.runtime.getPlatformInfo(function(info) { } } } - } - // Default case - return {}; - } - - /** - * This function get the log on start and load the - * json data in to the log variable. - * If no log in the local storage, this function - * create a foundation json variable. - */ - function getLogOnStart() - { - browser.storage.local.get('log', function(data) { - if(data.log) - { - log = JSON.parse(data.log); - } - else{ - //Create foundation for log variable - log = {"log": []}; - } - }); - } - - /** - * Function to log all activities from ClearUrls. - * Only logging when activated. - * The log is only temporary saved in the cache and will - * permanently saved with the saveLogOnClose function. - * - * @param beforeProcessing the url before the clear process - * @param afterProcessing the url after the clear process - * @param rule the rule that triggered the process - */ - function pushToLog(beforeProcessing, afterProcessing, rule) - { - if(logging) - { - log.log.push( - { - "before": beforeProcessing, - "after": afterProcessing, - "rule": rule, - "timestamp": Date.now() - } - ); - } - } - - /** - * This function is triggered by the event windows.onRemoved and tabs.onCreated - * and will save the log permanently to the local storage. - * We only save the log anticyclically based on performance. - */ - function saveLog() - { - if(logging) - { - browser.storage.local.get('resetLog', function(data) { - if(data.resetLog) - { - log = {"log": []}; // Delete the old log - browser.storage.local.set({"resetLog": false}); - } - else - { - browser.storage.local.set({"log": JSON.stringify(log)}); - } - }); - } - } - - /** - * Check if the status from logging has changed. - * - * The default value is false (off). - */ - function getLoggingStatus() - { - browser.storage.local.get('loggingStatus', function(data) { - if(data.loggingStatus) { - logging = data.loggingStatus; - } - else if(data.loggingStatus === null || typeof(data.loggingStatus) == "undefined"){ - logging = false; - } - else { - logging = false; - } - }); - } - - /** - * Call by each windows is closed or created. - */ - if(!checkOSAndroid()) - { - console.log("ClearURLs: Log listener is added.") - browser.windows.onRemoved.addListener(saveLog); - } - browser.tabs.onCreated.addListener(saveLog); - - /** - * Function that calls some function on storage change. - */ - function reactToStorageChange() - { - setBadgedStatus(); - getLoggingStatus(); - } - - /** - * Get the badged status from the browser storage and put the value - * into a local variable. - * - */ - function setBadgedStatus() { - if(!checkOSAndroid()){ - browser.storage.local.get('badgedStatus', function(data) { - if(data.badgedStatus) { - badgedStatus = data.badgedStatus; - browser.browserAction.setBadgeBackgroundColor({ - 'color': 'orange' - }); - } - else if(data.badgedStatus === null || typeof(data.badgedStatus) == "undefined"){ - badgedStatus = false; - } - else { - badgedStatus = false; - } - }); - } - } - - /** - * Check if it is an android device. - * @return bool - */ - function checkOSAndroid() - { - if(os == "android") - { - return true; - } - else{ - return false; - } - } - - /** - * Call loadOldDataFromStore, getHash, counter, status and log functions - */ - - loadOldDataFromStore(); - getHash(); - setBadgedStatus(); - getLogOnStart(); - - /** - * Call by each change in the browser storage. - */ - browser.storage.onChanged.addListener(reactToStorageChange); - - /** - * Call by each tab is updated. - * And if url has changed. - */ - function handleUpdated(tabId, changeInfo, tabInfo) { - if(changeInfo.url) - { - delete badges[tabId]; - } - } - - /** - * Call by each tab is updated. - */ - browser.tabs.onUpdated.addListener(handleUpdated); - - /** - * Call by each tab change to set the actual tab id - */ - function handleActivated(activeInfo) { - tabid = activeInfo.tabId; - } - - /** - * Call by each tab change. - */ - browser.tabs.onActivated.addListener(handleActivated); - - /** - * Check the request. - */ - function promise(requestDetails) - { - if(isDataURL(requestDetails)) - { + // Default case return {}; } - else { - var ret = clearUrl(requestDetails); - return ret; + + /** + * Function to log all activities from ClearUrls. + * Only logging when activated. + * The log is only temporary saved in the cache and will + * permanently saved with the saveLogOnClose function. + * + * @param beforeProcessing the url before the clear process + * @param afterProcessing the url after the clear process + * @param rule the rule that triggered the process + */ + function pushToLog(beforeProcessing, afterProcessing, rule) + { + if(storage.loggingStatus) + { + storage.log.log.push( + { + "before": beforeProcessing, + "after": afterProcessing, + "rule": rule, + "timestamp": Date.now() + } + ); + } } + /** + * Get the badged status from the browser storage and put the value + * into a local variable. + * + */ + function setBadgedStatus() { + if(!checkOSAndroid() && storage.badgedStatus){ + browser.browserAction.setBadgeBackgroundColor({ + 'color': 'orange' + }); + } + } + + /** + * Check if it is an android device. + * @return bool + */ + function checkOSAndroid() + { + if(os == "android") + { + return true; + } + else{ + return false; + } + } + + /** + * Call loadOldDataFromStore, getHash, counter, status and log functions + */ + + loadOldDataFromStore(); + getHash(); + setBadgedStatus(); + + /** + * Call by each tab is updated. + * And if url has changed. + */ + function handleUpdated(tabId, changeInfo, tabInfo) { + if(changeInfo.url) + { + delete badges[tabId]; + } + } + + /** + * Call by each tab is updated. + */ + browser.tabs.onUpdated.addListener(handleUpdated); + + /** + * Call by each tab change to set the actual tab id + */ + function handleActivated(activeInfo) { + tabid = activeInfo.tabId; + } + + /** + * Call by each tab change. + */ + browser.tabs.onActivated.addListener(handleActivated); + + /** + * Check the request. + */ + function promise(requestDetails) + { + if(isDataURL(requestDetails)) + { + return {}; + } + else { + var ret = clearUrl(requestDetails); + return ret; + } + + } + + /** + * To prevent long loading on data urls + * we will check here for data urls. + * + * @type {requestDetails} + * @return {boolean} + */ + function isDataURL(requestDetails) { + var s = requestDetails.url; + + return s.substring(0,4) == "data"; + } + + /** + * Call by each Request and checking the url. + * + * @type {Array} + */ + browser.webRequest.onBeforeRequest.addListener( + promise, + {urls: [""]}, + ["blocking"] + ); + }); +} + +/** +* Writes the storage variable to the disk. +*/ +window.onbeforeunload = saveOnExit(); + +function saveOnExit() +{ + var json = {}; + + Object.entries(storage).forEach(([key, value]) => { + switch (key) { + case "ClearURLsData": + case "log": + json[key] = JSON.stringify(value); + break; + default: + json[key] = value; + } + }); + console.log("[ClearURLs]: Save on disk."); + browser.storage.local.set(json); +} + +/** +* Save the value under the key on the disk. +* @param {String} key +* @param {Object} value +*/ +function saveOnDisk(key, value) +{ + browser.storage.local.set({key: value}); +} + +/** +* Retrieve everything and save on the RAM. +*/ +function getDataFromDisk() +{ + browser.storage.local.get().then(start, error); +} + +/** +* Get the value under the key. +* @param {String} key +* @return {Object} +*/ +function getData(key) +{ + return storage[key]; +} + +/** +* Save the value under the key on the RAM. +* @param {String} key +* @param {Object} value +*/ +function setData(key, value) +{ + switch (key) { + case "ClearURLsData": + case "log": + storage[key] = JSON.parse(value); + break; + default: + storage[key] = value; } +} - /** - * To prevent long loading on data urls - * we will check here for data urls. - * - * @type {requestDetails} - * @return {boolean} - */ - function isDataURL(requestDetails) { - var s = requestDetails.url; +/** +* Write error on console. +*/ +function error() +{ + console.log("The addon could not started."); +} - return s.substring(0,4) == "data"; +/** +* Set default values, if the storage is empty. +* @param {Object} items +*/ +function initStorage(items) +{ + storage.ClearURLsData = []; + storage.badgedStatus = true; + storage.globalStatus = true; + storage.globalurlcounter = 0; + storage.globalCounter = 0; + storage.hashStatus = "error"; + storage.loggingStatus = false; + storage.log = {"log": []}; + + if(!isEmpty(items)) { + Object.entries(items).forEach(([key, value]) => { + setData(key, value); + }); } +} - /** - * Call by each Request and checking the url. - * - * @type {Array} - */ - browser.webRequest.onBeforeRequest.addListener( - promise, - {urls: [""]}, - ["blocking"] - ); -}); +/** +* Check if an object is empty. +* @param {Object} obj +* @return {Boolean} +*/ +function isEmpty(obj) +{ + return (Object.getOwnPropertyNames(obj).length === 0); +} diff --git a/core_js/log.js b/core_js/log.js index dba3d5e..c60a4f5 100644 --- a/core_js/log.js +++ b/core_js/log.js @@ -1,14 +1,21 @@ /** * Get the log and display the data as table. */ -var log = []; +var log = {}; + +var core = function (func) { + return browser.runtime.getBackgroundPage().then(func); +}; /** * Reset the global log */ function resetGlobalLog(){ - browser.storage.local.remove("log"); - browser.storage.local.set({"resetLog": true}); + core(function (ref){ + obj = {"log": []}; + ref.setData('log', JSON.stringify(obj)); + }); + getLog(); location.reload(); } @@ -17,15 +24,8 @@ function resetGlobalLog(){ */ function getLog() { - browser.storage.local.get('log', function(data) { - if(data.log) - { - log = JSON.parse(data.log); - } - else{ - //Create foundation for log variable - log = {"log": []}; - } + core(function (ref){ + log = ref.getData('log'); var length = Object.keys(log.log).length; var row; @@ -42,7 +42,7 @@ function getLog() } } $('#logTable').DataTable({ - "pageLength": 5 + "pageLength": 10 } ).order([3, 'desc']).draw(); }); } diff --git a/core_js/popup_new.js b/core_js/popup_new.js index 32a92f7..7aefdc9 100644 --- a/core_js/popup_new.js +++ b/core_js/popup_new.js @@ -1,3 +1,32 @@ +var element = $("#statistics_value"); +var elGlobalPercentage = $("#statistics_value_global_percentage"); +var elProgressbar_blocked = $('#progress_blocked'); +var elProgressbar_non_blocked = $('#progress_non_blocked'); +var elTotal = $('#statistics_total_elements'); +var globalPercentage = 0; +var globalCounter; +var globalurlcounter; +var globalStatus; +var badgedStatus; +var hashStatus; +var loggingStatus; + +var core = function (func) { + return browser.runtime.getBackgroundPage().then(func); +}; + +function getData() +{ + core(function (ref){ + globalCounter = ref.getData('globalCounter'); + globalurlcounter = ref.getData('globalurlcounter'); + globalStatus = ref.getData('globalStatus'); + badgedStatus = ref.getData('badgedStatus'); + hashStatus = ref.getData('hashStatus'); + loggingStatus = ref.getData('loggingStatus'); + }); +} + /** * Initialize the UI. * @@ -16,43 +45,15 @@ function init() * @param {(data){} Return value form browser.storage.local.get */ function changeStatistics(){ - var element = $("#statistics_value"); - var elGlobalPercentage = $("#statistics_value_global_percentage"); - var elProgressbar_blocked = $('#progress_blocked'); - var elProgressbar_non_blocked = $('#progress_non_blocked'); - var elTotal = $('#statistics_total_elements'); - var globalPercentage = 0; - var globalCounter; - var globalurlcounter; + globalPercentage = ((globalCounter/globalurlcounter)*100).toFixed(3); - browser.storage.local.get('globalCounter', function(data){ - if(data.globalCounter){ - globalCounter = data.globalCounter; - } - else { - globalCounter = 0; - } + if(isNaN(Number(globalPercentage))) globalPercentage = 0; - element.text(globalCounter.toLocaleString()); - }); - - browser.storage.local.get('globalurlcounter', function(data){ - if(data.globalurlcounter){ - globalurlcounter = data.globalurlcounter; - } - else { - globalurlcounter = 0; - } - - globalPercentage = ((globalCounter/globalurlcounter)*100).toFixed(3); - - if(isNaN(Number(globalPercentage))) globalPercentage = 0; - - elGlobalPercentage.text(globalPercentage+"%"); - elProgressbar_blocked.css('width', globalPercentage+'%'); - elProgressbar_non_blocked.css('width', (100-globalPercentage)+'%'); - elTotal.text(globalurlcounter.toLocaleString()); - }); + element.text(globalCounter.toLocaleString()); + elGlobalPercentage.text(globalPercentage+"%"); + elProgressbar_blocked.css('width', globalPercentage+'%'); + elProgressbar_non_blocked.css('width', (100-globalPercentage)+'%'); + elTotal.text(globalurlcounter.toLocaleString()); } /** @@ -63,7 +64,9 @@ function changeStatistics(){ function changeGlobalStatus() { var element = $('#globalStatus').is(':checked'); - browser.storage.local.set({'globalStatus': element}); + core(function (ref){ + ref.setData('globalStatus', element); + }); } /** @@ -71,19 +74,7 @@ function changeGlobalStatus() { */ function setGlobalStatus() { var element = $('#globalStatus'); - - browser.storage.local.get('globalStatus', function(data) { - if(data.globalStatus) { - element.prop('checked', true); - } - else if(data.globalStatus === null || typeof(data.globalStatus) == "undefined"){ - element.prop('checked', true); - browser.storage.local.set({'globalStatus': true}); - } - else { - element.prop('checked', false); - } - }); + element.prop('checked', globalStatus); } /** @@ -94,7 +85,9 @@ function setGlobalStatus() { function changeTabcounter() { var element = $('#tabcounter').is(':checked'); - browser.storage.local.set({'badgedStatus': element}); + core(function (ref){ + ref.setData('badgedStatus', element); + }); } /** @@ -102,20 +95,7 @@ function changeTabcounter() { */ function setTabcounter() { var element = $('#tabcounter'); - - browser.storage.local.get('badgedStatus', function(data) { - if(data.badgedStatus) - { - element.prop('checked', true); - } - else if(data.badgedStatus === null || typeof(data.badgedStatus) == "undefined"){ - element.prop('checked', true); - browser.storage.local.set({'badgedStatus': true}); - } - else { - element.prop('checked', false); - } - }); + element.prop('checked', badgedStatus); } /** @@ -124,8 +104,9 @@ function setTabcounter() { function changeLogging() { var element = $('#logging').is(':checked'); - - browser.storage.local.set({'loggingStatus': element}); + core(function (ref){ + ref.setData('loggingStatus', element); + }); } /** @@ -135,15 +116,14 @@ function setHashStatus() { var element = $('#hashStatus'); - browser.storage.local.get('hashStatus', function(data) { - if(data.hashStatus) - { - element.text(data.hashStatus); - } - else { - element.text('Oops something went wrong!'); - } - }); + if(hashStatus) + { + element.text(hashStatus); + } + else { + element.text('Oops something went wrong!'); + } + } /** @@ -152,31 +132,22 @@ function setHashStatus() function setLogging() { var element = $('#logging'); - - browser.storage.local.get('loggingStatus', function(data) { - if(data.loggingStatus) - { - element.prop('checked', true); - } - else if(data.loggingStatus === null || typeof(data.loggingStatus) == "undefined"){ - element.prop('checked', false); - browser.storage.local.set({'loggingStatus': false}); - } - else { - element.prop('checked', false); - } - }); + element.prop('checked', loggingStatus); } /** * Reset the global statistic -* */ function resetGlobalCounter(){ - browser.storage.local.set({"globalCounter": 0}); - browser.storage.local.set({"globalurlcounter": 0}); + core(function (ref){ + globalurlcounter = 0; + globalCounter = 0; + ref.setData('globalCounter', 0); + ref.setData('globalurlcounter', 0); + }); } +getData(); $(document).ready(function(){ init(); $("#globalStatus").on("change", changeGlobalStatus); diff --git a/manifest.json b/manifest.json index 91cd96a..6d4f0af 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 2, "name": "ClearURLs", - "version": "1.2.1.4", + "version": "1.2.2.0", "author": "Kevin R.", "description": "Remove tracking elements form URLs.", "homepage_url": "https://github.com/KevinRoebert/ClearUrls",