diff --git a/platform/firefox/frameScript.js b/platform/firefox/frameScript.js index 12644490b..c94f260de 100644 --- a/platform/firefox/frameScript.js +++ b/platform/firefox/frameScript.js @@ -4,7 +4,7 @@ 'use strict'; -var +let appName = 'ublock', contentBaseURI = 'chrome://' + appName + '/content/js/', listeners = {}, @@ -25,7 +25,7 @@ var addMessageListener('µBlock:broadcast', function(msg) { for (var id in listeners) { - listeners[id](msg.data); + listeners[id](msg); } }); diff --git a/platform/firefox/install.rdf b/platform/firefox/install.rdf index bc2f7b3b5..17fd41513 100644 --- a/platform/firefox/install.rdf +++ b/platform/firefox/install.rdf @@ -1,34 +1,34 @@ - - {2b10c1c8-a11f-4bad-fe9c-1c11e82cac42} - 0.7.0.11 - µBlock - Finally, an efficient blocker. Easy on CPU and memory. - https://github.com/gorhill/uBlock - Raymond Hill - 2 - true - true - 3 - chrome://ublock/content/dashboard.html + + {2b10c1c8-a11f-4bad-fe9c-1c11e82cac42} + 0.7.0.11 + µBlock + Finally, an efficient blocker. Easy on CPU and memory. + https://github.com/gorhill/uBlock + Raymond Hill + 2 + true + true + 3 + chrome://ublock/content/dashboard.html - - - - {ec8030f7-c20a-464f-9b0e-13a3a9e97384} - 24.0 - 37.0 - - + + + + {ec8030f7-c20a-464f-9b0e-13a3a9e97384} + 24.0 + 37.0 + + - - - - {92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a} - 2.21 - 2.34 - - - + + + + {92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a} + 2.21 + 2.34 + + + diff --git a/platform/firefox/vapi-background.js b/platform/firefox/vapi-background.js index a80bc51e1..733c694fe 100644 --- a/platform/firefox/vapi-background.js +++ b/platform/firefox/vapi-background.js @@ -43,6 +43,180 @@ vAPI.firefox = true; /******************************************************************************/ +var SQLite = { + open: function() { + var path = Services.dirsvc.get('ProfD', Ci.nsIFile); + path.append('extension-data'); + + if (!path.exists()) { + path.create(Ci.nsIFile.DIRECTORY_TYPE, parseInt('0774', 8)); + } + + if (!path.isDirectory()) { + throw Error('Should be a directory...'); + } + + path.append('uBlock.sqlite'); + this.db = Services.storage.openDatabase(path); + this.db.executeSimpleSQL( + 'CREATE TABLE IF NOT EXISTS settings' + + '(name TEXT PRIMARY KEY NOT NULL, value TEXT);' + ); + }, + close: function() { + this.run('VACUUM'); + this.db.asyncClose(); + }, + run: function(query, values, callback) { + if (!this.db) { + this.open(); + } + + var result = {}; + + query = this.db.createAsyncStatement(query); + + if (Array.isArray(values) && values.length) { + var i = values.length; + + while (i--) { + query.bindByIndex(i, values[i]); + } + } + + query.executeAsync({ + handleResult: function(rows) { + if (!rows || typeof callback !== 'function') { + return; + } + + var row; + + while (row = rows.getNextRow()) { + // we assume that there will be two columns, since we're + // using it only for preferences + result[row.getResultByIndex(0)] = row.getResultByIndex(1); + } + }, + handleCompletion: function(reason) { + if (typeof callback === 'function' && reason === 0) { + callback(result); + } + }, + handleError: function(error) { + console.error('SQLite error ', error.result, error.message); + } + }); + } +}; + +/******************************************************************************/ + +vAPI.storage = { + QUOTA_BYTES: 100 * 1024 * 1024, + sqlWhere: function(col, valNum) { + if (valNum > 0) { + valNum = Array(valNum + 1).join('?, ').slice(0, -2); + return ' WHERE ' + col + ' IN (' + valNum + ')'; + } + + return ''; + }, + get: function(details, callback) { + if (typeof callback !== 'function') { + return; + } + + var values = [], defaults = false; + + if (details !== null) { + if (Array.isArray(details)) { + values = details; + } + else if (typeof details === 'object') { + defaults = true; + values = Object.keys(details); + } + else { + values = [details.toString()]; + } + } + + SQLite.run( + 'SELECT * FROM settings' + this.sqlWhere('name', values.length), + values, + function(result) { + var key; + + for (key in result) { + result[key] = JSON.parse(result[key]); + } + + if (defaults) { + for (key in details) { + if (!result[key]) { + result[key] = details[key]; + } + } + } + + callback(result); + } + ); + }, + set: function(details, callback) { + var key, values = [], questionmarks = []; + + for (key in details) { + values.push(key); + values.push(JSON.stringify(details[key])); + questionmarks.push('?, ?'); + } + + if (!values.length) { + return; + } + + SQLite.run( + 'INSERT OR REPLACE INTO settings (name, value) SELECT ' + + questionmarks.join(' UNION SELECT '), + values, + callback + ); + }, + remove: function(keys, callback) { + if (typeof keys === 'string') { + keys = [keys]; + } + + SQLite.run( + 'DELETE FROM settings' + this.sqlWhere('name', keys.length), + keys, + callback + ); + }, + clear: function(callback) { + SQLite.run('DELETE FROM settings', null, callback); + SQLite.run('VACUUM'); + }, + getBytesInUse: function(keys, callback) { + if (typeof callback !== 'function') { + return; + } + + SQLite.run( + "SELECT 'size' AS size, SUM(LENGTH(value)) FROM settings" + + this.sqlWhere('name', Array.isArray(keys) ? keys.length : 0), + keys, + function(result) { + callback(result.size); + } + ); + } +}; + +/******************************************************************************/ + vAPI.messaging = { gmm: Cc['@mozilla.org/globalmessagemanager;1'].getService(Ci.nsIMessageListenerManager), frameScript: 'chrome://ublock/content/frameScript.js', @@ -133,8 +307,11 @@ vAPI.messaging.setup = function(defaultHandler) { /******************************************************************************/ -vAPI.messaging.broadcast = function(msg) { - this.gmm.broadcastAsyncMessage(vAPI.app.name + ':broadcast', msg); +vAPI.messaging.broadcast = function(message) { + this.gmm.broadcastAsyncMessage( + vAPI.app.name + ':broadcast', + JSON.stringify({broadcast: true, msg: message}) + ); }; /******************************************************************************/ @@ -148,8 +325,9 @@ vAPI.lastError = function() { // clean up when the extension is disabled window.addEventListener('unload', function() { + SQLite.close(); vAPI.messaging.gmm.removeMessageListener( - app.name + ':background', + vAPI.app.name + ':background', vAPI.messaging.postMessage ); vAPI.messaging.gmm.removeDelayedFrameScript(vAPI.messaging.frameScript); diff --git a/platform/firefox/vapi-common.js b/platform/firefox/vapi-common.js index 45825e77d..71a0e5453 100644 --- a/platform/firefox/vapi-common.js +++ b/platform/firefox/vapi-common.js @@ -93,4 +93,3 @@ setScriptDirection(navigator.language); })(); /******************************************************************************/ - diff --git a/platform/safari/Settings.plist b/platform/safari/Settings.plist index 40cc1ff16..6c80bbb43 100644 --- a/platform/safari/Settings.plist +++ b/platform/safari/Settings.plist @@ -2,21 +2,21 @@ - - DefaultValue - - FalseValue - - Key - open_prefs - Secure - - Title - Click to see the Preferences - TrueValue - - Type - CheckBox - + + DefaultValue + + FalseValue + + Key + open_prefs + Secure + + Title + Click to see the Preferences + TrueValue + + Type + CheckBox + diff --git a/src/css/3p-filters.css b/src/css/3p-filters.css index a5bbde3a8..a9b13ea47 100644 --- a/src/css/3p-filters.css +++ b/src/css/3p-filters.css @@ -119,7 +119,7 @@ body[dir=rtl] #externalListsDiv { font-size: smaller; width: 48em; height: 8em; - white-space: nowrap; + white-space: pre; } body #busyOverlay { position: fixed; diff --git a/tools/xpi-convert-locale.py b/tools/xpi-convert-locale.py index 1467f3612..582e9a288 100644 --- a/tools/xpi-convert-locale.py +++ b/tools/xpi-convert-locale.py @@ -3,42 +3,34 @@ import os import json import sys -from shutil import rmtree as rmt +from shutil import rmtree from collections import OrderedDict if not sys.argv[1]: raise SystemExit('Build dir missing.') -osp = os.path -pj = osp.join - - -def rmtree(path): - if osp.exists(path): - rmt(path) - def mkdirs(path): try: os.makedirs(path) finally: - return osp.exists(path) + return os.path.exists(path) -build_dir = osp.abspath(sys.argv[1]) -source_locale_dir = pj(build_dir, '_locales') -target_locale_dir = pj(build_dir, 'locale') +build_dir = os.path.abspath(sys.argv[1]) +source_locale_dir = os.path.join(build_dir, '_locales') +target_locale_dir = os.path.join(build_dir, 'locale') for alpha2 in os.listdir(source_locale_dir): - locale_path = pj(source_locale_dir, alpha2, 'messages.json') + locale_path = os.path.join(source_locale_dir, alpha2, 'messages.json') with open(locale_path, encoding='utf-8') as f: string_data = json.load(f, object_pairs_hook=OrderedDict) alpha2 = alpha2.replace('_', '-') - mkdirs(pj(target_locale_dir, alpha2)) + mkdirs(os.path.join(target_locale_dir, alpha2)) - locale_path = pj(target_locale_dir, alpha2, 'messages.properties') + locale_path = os.path.join(target_locale_dir, alpha2, 'messages.properties') with open(locale_path, 'wt', encoding='utf-8', newline='\n') as f: for string_name in string_data: f.write(string_name)