Last active
May 30, 2017 01:12
-
-
Save oshybystyi/8cf882bc8b0c9a95a116 to your computer and use it in GitHub Desktop.
Load default preferences for firefox bootstrap (restartless) addons
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Default addon bootstrap file | |
* full example can be found here https://github.com/oshybystyi/FireX-Pixel-Perfect/blob/issue-5-make-addon-restartless/bootstrap.js | |
*/ | |
const defaultPreferencesLoaderLink = 'chrome://<addon-alias/<path-to>/defaultPreferencesLoader.jsm'; | |
function startup(data) { | |
/** some code here ... **/ | |
loadDefaultPreferences(data.installPath); | |
/** some code here ... **/ | |
} | |
function shutdown(data, reason) { | |
if (reason == APP_SHUTDOWN) | |
return; | |
/** Remove default preferences on extension being uninstalled **/ | |
unloadDefaultPreferences(); | |
/** some code here ... **/ | |
} | |
function loadDefaultPreferences(installPath) { | |
Cu.import(defaultPreferencesLoaderLink); | |
this.defaultPreferencesLoader = new DefaultPreferencesLoader(installPath); | |
this.defaultPreferencesLoader.parseDirectory(); | |
} | |
function unloadDefaultPreferences() { | |
this.defaultPreferencesLoader.clearDefaultPrefs(); | |
Cu.unload(defaultPreferencesLoaderLink); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Working example can be found here | |
* https://github.com/oshybystyi/FireX-Pixel-Perfect/blob/issue-5-make-addon-restartless/content/lib/defaultPreferencesLoader.jsm | |
* | |
* Important this module was tested only with <em:unpack>true</em:unpack>, most | |
* likely it won't work with false value | |
* | |
* A lot of stuff was borrowed from https://github.com/firebug/firebug/blob/master/extension/modules/prefLoader.js | |
*/ | |
const { utils: Cu, classes: Cc, interfaces: Ci } = Components; | |
Cu.import('resource://gre/modules/Services.jsm'); | |
var EXPORTED_SYMBOLS = ['DefaultPreferencesLoader']; | |
/** | |
* Read defaults/preferences/* and set Services.pref default branch | |
*/ | |
function DefaultPreferencesLoader(installPath) { | |
let readFrom = installPath.clone(); // don't modify the original object | |
['defaults', 'preferences'].forEach(function(dir) { | |
readFrom.append(dir); | |
}); | |
this.baseURI = Services.io.newFileURI(readFrom); | |
if (readFrom.exists() !== true) { | |
throw new DefaultsDirectoryMissingError(readFrom); | |
} | |
this.readFrom = readFrom; | |
this.defaultBranch = Services.prefs.getDefaultBranch(""); | |
} | |
DefaultPreferencesLoader.prototype = { | |
/** | |
* Iterate over files in the default/preferences/* | |
* | |
* @param {function} prefFunc the function that should be used instead of | |
* pref | |
*/ | |
parseDirectory: function(prefFunc) { | |
prefFunc = prefFunc || this.pref.bind(this); | |
let entries = this.readFrom.directoryEntries; | |
while (entries.hasMoreElements()) { | |
let fileURI = Services.io.newFileURI(entries.getNext()); | |
Services.scriptloader.loadSubScript(fileURI.spec, { pref: prefFunc }); | |
} | |
}, | |
/** | |
* Emulates firefox pref function to load default preferences | |
*/ | |
pref: function(key, value) { | |
switch (typeof value) { | |
case 'boolean': | |
this.defaultBranch.setBoolPref(key, value); | |
break; | |
case 'number': | |
this.defaultBranch.setIntPref(key, value); | |
break; | |
case 'string': | |
/** | |
* Using setComplexValue instead of setCharPref because of | |
* unicode support | |
*/ | |
let str = Cc["@mozilla.org/supports-string;1"].createInstance(Ci.nsISupportsString); | |
str.value = value; | |
this.defaultBranch.setComplexValue(key, Ci.nsISupportsString, str); | |
break; | |
default: | |
throw new NotSupportedValueTypeError(key); | |
break; | |
} | |
}, | |
/** | |
* Clears default preferences according to AMO reviewers reccommendation | |
* This should be invoked on bootstrap::shutdown | |
* @see https://github.com/firebug/firebug/blob/master/extension/modules/prefLoader.js | |
*/ | |
clearDefaultPrefs: function() { | |
this.parseDirectory(this.prefUnload.bind(this)); | |
}, | |
prefUnload: function(key) { | |
let branch = this.defaultBranch; | |
if (branch.prefHasUserValue(key) !== true) { | |
branch.deleteBranch(key); | |
} | |
} | |
}; | |
/** | |
* Exception type on missing defaults/preferences folder | |
*/ | |
function DefaultsDirectoryMissingError(installPath) { | |
this.name = 'DefaultsDirectoryMissingError'; | |
this.message = '\'' + installPath.path + '\' does no exist'; | |
} | |
/** Inherit from Error for error stack and pretty output in terminal **/ | |
DefaultsDirectoryMissingError.prototype = new Error(); | |
/** | |
* Not supported value type to store by pref | |
*/ | |
function NotSupportedValueTypeError(key) { | |
this.name = 'NotSupportedValueType'; | |
this.message = 'Value type for key \'' + key + '\' is not supported'; | |
} | |
NotSupportedValueTypeError.prototype = new Error(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This doesn't appear to work for a packed extension. The code in
function DefaultPreferencesLoader
is trying to append the path "defaults/preferences" to the path of the XPI file, which doesn't work. I think you need to implement alternative code usingnsIZipReader
or something.Something like this seems to work (the rest of the code other than the section shown here remains unchanged):