Improve handling of preferences in Firefox

This commit is contained in:
Jonas Jenwald 2014-01-30 18:09:31 +01:00
parent f46942758f
commit c158894d94
5 changed files with 118 additions and 62 deletions

View File

@ -16,7 +16,7 @@
*/ */
/* jshint esnext:true */ /* jshint esnext:true */
/* globals Components, Services, dump, XPCOMUtils, PdfStreamConverter, /* globals Components, Services, dump, XPCOMUtils, PdfStreamConverter,
PdfRedirector, APP_SHUTDOWN */ PdfRedirector, APP_SHUTDOWN, DEFAULT_PREFERENCES */
'use strict'; 'use strict';
@ -56,6 +56,27 @@ function log(str) {
dump(str + '\n'); dump(str + '\n');
} }
function initializeDefaultPreferences() {
Cu.import('resource://' + RESOURCE_NAME + '/default_preferences.js');
var defaultBranch = Services.prefs.getDefaultBranch(EXT_PREFIX + '.');
var defaultValue;
for (var key in DEFAULT_PREFERENCES) {
defaultValue = DEFAULT_PREFERENCES[key];
switch (typeof defaultValue) {
case 'boolean':
defaultBranch.setBoolPref(key, defaultValue);
break;
case 'number':
defaultBranch.setIntPref(key, defaultValue);
break;
case 'string':
defaultBranch.setCharPref(key, defaultValue);
break;
}
}
}
// Factory that registers/unregisters a constructor as a component. // Factory that registers/unregisters a constructor as a component.
function Factory() {} function Factory() {}
@ -124,6 +145,8 @@ function startup(aData, aReason) {
Ph.registerPlayPreviewMimeType('application/pdf', true, Ph.registerPlayPreviewMimeType('application/pdf', true,
'data:application/x-moz-playpreview-pdfjs;,'); 'data:application/x-moz-playpreview-pdfjs;,');
} }
initializeDefaultPreferences();
} }
function shutdown(aData, aReason) { function shutdown(aData, aReason) {

View File

@ -61,6 +61,27 @@ function getIntPref(aPref, aDefaultValue) {
} }
} }
function initializeDefaultPreferences() {
Cu.import('resource://pdf.js/default_preferences.js');
var defaultBranch = Services.prefs.getDefaultBranch(PREF_PREFIX + '.');
var defaultValue;
for (var key in DEFAULT_PREFERENCES) {
defaultValue = DEFAULT_PREFERENCES[key];
switch (typeof defaultValue) {
case 'boolean':
defaultBranch.setBoolPref(key, defaultValue);
break;
case 'number':
defaultBranch.setIntPref(key, defaultValue);
break;
case 'string':
defaultBranch.setCharPref(key, defaultValue);
break;
}
}
}
// Register/unregister a constructor as a factory. // Register/unregister a constructor as a factory.
function Factory() {} function Factory() {}
Factory.prototype = { Factory.prototype = {
@ -104,6 +125,8 @@ let PdfJs = {
Services.obs.addObserver(this, TOPIC_PDFJS_HANDLER_CHANGED, false); Services.obs.addObserver(this, TOPIC_PDFJS_HANDLER_CHANGED, false);
Services.obs.addObserver(this, TOPIC_PLUGINS_LIST_UPDATED, false); Services.obs.addObserver(this, TOPIC_PLUGINS_LIST_UPDATED, false);
Services.obs.addObserver(this, TOPIC_PLUGIN_INFO_UPDATED, false); Services.obs.addObserver(this, TOPIC_PLUGIN_INFO_UPDATED, false);
initializeDefaultPreferences();
}, },
_migrate: function migrate() { _migrate: function migrate() {

View File

@ -16,7 +16,7 @@
*/ */
/* jshint esnext:true */ /* jshint esnext:true */
/* globals Components, Services, XPCOMUtils, NetUtil, PrivateBrowsingUtils, /* globals Components, Services, XPCOMUtils, NetUtil, PrivateBrowsingUtils,
dump, NetworkManager, PdfJsTelemetry, DEFAULT_PREFERENCES */ dump, NetworkManager, PdfJsTelemetry */
'use strict'; 'use strict';
@ -33,16 +33,14 @@ const PDF_CONTENT_TYPE = 'application/pdf';
const PREF_PREFIX = 'PDFJSSCRIPT_PREF_PREFIX'; const PREF_PREFIX = 'PDFJSSCRIPT_PREF_PREFIX';
const PDF_VIEWER_WEB_PAGE = 'resource://pdf.js/web/viewer.html'; const PDF_VIEWER_WEB_PAGE = 'resource://pdf.js/web/viewer.html';
const MAX_DATABASE_LENGTH = 4096; const MAX_DATABASE_LENGTH = 4096;
const MAX_STRING_PREF_LENGTH = 4096; const MAX_NUMBER_OF_PREFS = 50;
const MAX_STRING_PREF_LENGTH = 128;
Cu.import('resource://gre/modules/XPCOMUtils.jsm'); Cu.import('resource://gre/modules/XPCOMUtils.jsm');
Cu.import('resource://gre/modules/Services.jsm'); Cu.import('resource://gre/modules/Services.jsm');
Cu.import('resource://gre/modules/NetUtil.jsm'); Cu.import('resource://gre/modules/NetUtil.jsm');
Cu.import('resource://pdf.js/network.js'); Cu.import('resource://pdf.js/network.js');
// Load the default preferences.
Cu.import('resource://pdf.js/default_preferences.js');
XPCOMUtils.defineLazyModuleGetter(this, 'PrivateBrowsingUtils', XPCOMUtils.defineLazyModuleGetter(this, 'PrivateBrowsingUtils',
'resource://gre/modules/PrivateBrowsingUtils.jsm'); 'resource://gre/modules/PrivateBrowsingUtils.jsm');
@ -453,56 +451,60 @@ ChromeActions.prototype = {
.updateControlState(result, findPrevious); .updateControlState(result, findPrevious);
}, },
setPreferences: function(prefs) { setPreferences: function(prefs) {
var prefValue, defaultValue, prefName, prefType, defaultType; var defaultBranch = Services.prefs.getDefaultBranch(PREF_PREFIX + '.');
var numberOfPrefs = 0;
for (var key in DEFAULT_PREFERENCES) { var prefValue, prefName;
for (var key in prefs) {
if (++numberOfPrefs > MAX_NUMBER_OF_PREFS) {
log('setPreferences - Exceeded the maximum number of preferences ' +
'that is allowed to be set at once.');
break;
} else if (!defaultBranch.getPrefType(key)) {
continue;
}
prefValue = prefs[key]; prefValue = prefs[key];
defaultValue = DEFAULT_PREFERENCES[key];
prefName = (PREF_PREFIX + '.' + key); prefName = (PREF_PREFIX + '.' + key);
switch (typeof prefValue) {
if (prefValue === undefined || prefValue === defaultValue) { case 'boolean':
Services.prefs.clearUserPref(prefName); setBoolPref(prefName, prefValue);
} else { break;
prefType = typeof prefValue; case 'number':
defaultType = typeof defaultValue; setIntPref(prefName, prefValue);
break;
if (prefType !== defaultType) { case 'string':
continue; if (prefValue.length > MAX_STRING_PREF_LENGTH) {
} log('setPreferences - Exceeded the maximum allowed length ' +
switch (defaultType) { 'for a string preference.');
case 'boolean': } else {
setBoolPref(prefName, prefValue); setStringPref(prefName, prefValue);
break; }
case 'number': break;
setIntPref(prefName, prefValue);
break;
case 'string':
// Protect against adding arbitrarily long strings in about:config.
if (prefValue.length <= MAX_STRING_PREF_LENGTH) {
setStringPref(prefName, prefValue);
}
break;
}
} }
} }
}, },
getPreferences: function() { getPreferences: function(prefs) {
var currentPrefs = {}; var defaultBranch = Services.prefs.getDefaultBranch(PREF_PREFIX + '.');
var defaultValue, prefName; var currentPrefs = {}, numberOfPrefs = 0;
var prefValue, prefName;
for (var key in DEFAULT_PREFERENCES) { for (var key in prefs) {
defaultValue = DEFAULT_PREFERENCES[key]; if (++numberOfPrefs > MAX_NUMBER_OF_PREFS) {
log('getPreferences - Exceeded the maximum number of preferences ' +
'that is allowed to be fetched at once.');
break;
} else if (!defaultBranch.getPrefType(key)) {
continue;
}
prefValue = prefs[key];
prefName = (PREF_PREFIX + '.' + key); prefName = (PREF_PREFIX + '.' + key);
switch (typeof prefValue) {
switch (typeof defaultValue) {
case 'boolean': case 'boolean':
currentPrefs[key] = getBoolPref(prefName, defaultValue); currentPrefs[key] = getBoolPref(prefName, prefValue);
break; break;
case 'number': case 'number':
currentPrefs[key] = getIntPref(prefName, defaultValue); currentPrefs[key] = getIntPref(prefName, prefValue);
break; break;
case 'string': case 'string':
currentPrefs[key] = getStringPref(prefName, defaultValue); currentPrefs[key] = getStringPref(prefName, prefValue);
break; break;
} }
} }

View File

@ -108,9 +108,10 @@ Preferences.prototype.writeToStorage = function(prefObj) {
FirefoxCom.requestSync('setPreferences', prefObj); FirefoxCom.requestSync('setPreferences', prefObj);
}; };
Preferences.prototype.readFromStorage = function() { Preferences.prototype.readFromStorage = function(prefObj) {
var readFromStoragePromise = new Promise(function (resolve) { var readFromStoragePromise = new Promise(function (resolve) {
var readPrefs = JSON.parse(FirefoxCom.requestSync('getPreferences')); var readPrefs = JSON.parse(FirefoxCom.requestSync('getPreferences',
prefObj));
resolve(readPrefs); resolve(readPrefs);
}); });
return readFromStoragePromise; return readFromStoragePromise;

View File

@ -24,12 +24,13 @@ var Preferences = (function PreferencesClosure() {
function Preferences() { function Preferences() {
this.prefs = {}; this.prefs = {};
this.isInitializedPromiseResolved = false; this.isInitializedPromiseResolved = false;
this.initializedPromise = this.readFromStorage().then(function(prefObj) { this.initializedPromise = this.readFromStorage(DEFAULT_PREFERENCES).then(
this.isInitializedPromiseResolved = true; function(prefObj) {
if (prefObj) { this.isInitializedPromiseResolved = true;
this.prefs = prefObj; if (prefObj) {
} this.prefs = prefObj;
}.bind(this)); }
}.bind(this));
} }
Preferences.prototype = { Preferences.prototype = {
@ -37,7 +38,7 @@ var Preferences = (function PreferencesClosure() {
return; return;
}, },
readFromStorage: function Preferences_readFromStorage() { readFromStorage: function Preferences_readFromStorage(prefObj) {
var readFromStoragePromise = Promise.resolve(); var readFromStoragePromise = Promise.resolve();
return readFromStoragePromise; return readFromStoragePromise;
}, },
@ -45,7 +46,7 @@ var Preferences = (function PreferencesClosure() {
reset: function Preferences_reset() { reset: function Preferences_reset() {
if (this.isInitializedPromiseResolved) { if (this.isInitializedPromiseResolved) {
this.prefs = {}; this.prefs = {};
this.writeToStorage(this.prefs); this.writeToStorage(DEFAULT_PREFERENCES);
} }
}, },
@ -70,6 +71,12 @@ var Preferences = (function PreferencesClosure() {
valueType + '\", expected a \"' + defaultType + '\".'); valueType + '\", expected a \"' + defaultType + '\".');
return; return;
} }
} else {
if (valueType === 'number' && (value | 0) !== value) {
console.error('Preferences_set: \'' + value +
'\' must be an \"integer\".');
return;
}
} }
this.prefs[name] = value; this.prefs[name] = value;
this.writeToStorage(this.prefs); this.writeToStorage(this.prefs);
@ -97,13 +104,13 @@ var Preferences = (function PreferencesClosure() {
//#if B2G //#if B2G
//Preferences.prototype.writeToStorage = function(prefObj) { //Preferences.prototype.writeToStorage = function(prefObj) {
// asyncStorage.setItem('preferences', JSON.stringify(prefObj)); // asyncStorage.setItem('pdfjs.preferences', JSON.stringify(prefObj));
//}; //};
// //
//Preferences.prototype.readFromStorage = function() { //Preferences.prototype.readFromStorage = function(prefObj) {
// var readFromStoragePromise = new Promise(function (resolve) { // var readFromStoragePromise = new Promise(function (resolve) {
// asyncStorage.getItem('preferences', function(prefString) { // asyncStorage.getItem('pdfjs.preferences', function(prefStr) {
// var readPrefs = JSON.parse(prefString); // var readPrefs = JSON.parse(prefStr);
// resolve(readPrefs); // resolve(readPrefs);
// }); // });
// }); // });
@ -114,14 +121,14 @@ var Preferences = (function PreferencesClosure() {
//#if !(FIREFOX || MOZCENTRAL || B2G) //#if !(FIREFOX || MOZCENTRAL || B2G)
Preferences.prototype.writeToStorage = function(prefObj) { Preferences.prototype.writeToStorage = function(prefObj) {
if (isLocalStorageEnabled) { if (isLocalStorageEnabled) {
localStorage.setItem('preferences', JSON.stringify(prefObj)); localStorage.setItem('pdfjs.preferences', JSON.stringify(prefObj));
} }
}; };
Preferences.prototype.readFromStorage = function() { Preferences.prototype.readFromStorage = function(prefObj) {
var readFromStoragePromise = new Promise(function (resolve) { var readFromStoragePromise = new Promise(function (resolve) {
if (isLocalStorageEnabled) { if (isLocalStorageEnabled) {
var readPrefs = JSON.parse(localStorage.getItem('preferences')); var readPrefs = JSON.parse(localStorage.getItem('pdfjs.preferences'));
resolve(readPrefs); resolve(readPrefs);
} }
}); });