2

Is there an equivalent to this API or a way to call it from a restartless extension? I need to store a few strings between browser sessions.

I have found this but it seems too complicated for simple string storage. Does the SS API use the same thing behind the scene?

nmaier
  • 32,336
  • 5
  • 63
  • 78

3 Answers3

3

The simple-storage/localStorage APIs suck because of synchronous file I/O. There are alternatives such as IndexedDB which can be used from chrome/add-on code quite easily.

You can also use localStorage in your add-on (no need to use the SDK simple-storage API), but should not use window.localStorage in overlays because that would be shared between add-ons, and cannot use window.localStorage in bootstrap.js and/or js code modules because there simply is no window. But you can construct a storage object yourself.

function getStorage(uri) {
  if (!(uri instanceof Ci.nsIURI)) {
    uri = Services.io.newURI(uri, null, null);
  }
  let principal = Cc["@mozilla.org/scriptsecuritymanager;1"].
    getService(Ci.nsIScriptSecurityManager).
    getNoAppCodebasePrincipal(uri);
  let dsm = Cc["@mozilla.org/dom/localStorage-manager;1"].
    getService(Ci.nsIDOMStorageManager);
  return dsm.createStorage(principal, "");
}

var s1 = getStorage("chrome://my-addon/content/whatever.xul"); // does not actually have to point to a resource.

The usual limitations of localStorage apply (quotas and such).

BTW: The code also lets you access the localStorage of websites, e.g. getStorage("http://stackoverflow.com/");.

nmaier
  • 32,336
  • 5
  • 63
  • 78
  • `dsm.createStorage(principal, "")` did not work for me until I specified `null` as a first parameter `dsm.createStorage(null,principal, "")`. Maybe would be useful... Anyway, thanks! – smnbbrv Apr 10 '15 at 08:31
2

You can import any SDK module into normal restartless extensions this way:

const { devtools } = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
const { require } = devtools;

let ss = require('sdk/simple-storage');
diegocr
  • 1,000
  • 8
  • 13
  • 4
    Not entirely sure this is a good idea... This will give you a `simple-storage` instance that is shared between `devtools` and any other add-on that uses this hack. So if two different add-ons use this *shared* `devtools` instance with the same key, things will go **boom**. Better create a proper SDK loader yourself. – nmaier May 17 '14 at 02:08
  • Working on it as we speak. I just needed a temporary fix in the meantime. The add-on is used as a proof of concept right now, it's going live only after a lot of work :) – Sebastian-Laurenţiu Plesciuc May 17 '14 at 14:55
  • Importing SDK simple-storage into a normal restartless extensions will fail since simple-storage uses extension ID in `storeFile.append(jpSelf.id);` (line 192) which is not available. – erosman May 10 '16 at 16:58
1

You could use Session store API (nsISessionStore):

const ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
ss.setGlobalValue("my-extension-few-strings", "blah blah blah");
const fewStrings = ss.getGlobalValue("my-extension-few-strings");
// fewStrings === "blah blah blah";
ss.deleteGlobalValue("my-extension-few-strings");

Session store is shared across all extensions, so choose unique names for stored values (e.g. prepend all key names with your extension name). And unlike simple-storage and localStorage it's not limited in size.

p.s. setGlobalValue, getGlobalValue, deleteGlobalValue are not documented anywhere.

traxium
  • 2,701
  • 2
  • 16
  • 17