MathJax

SyntaxHighlighter

Highlight

Custom CSS

Tuesday, May 25, 2010

Transaction behavior in Firefox 3.0 SQLite API

Small gotcha if you are writing a Firefox 3.0 extension: while SQLite lets you do nested transactions, multiple concurrent transactions, and checkpoints, the Firefox API doesn't fully support those. The beginTransaction, commitTransaction, and rollbackTransaction methods in mozIStorageConnection fully expect only one transaction to be active at a time (you'll get an exception if you try to nest transactions by beginning a transaction while another is active).

Update

For 3.5, it looks like this is still true; there is even a note that says the underlying engine does not support nested transactions (possibly an older version of SQLite is in use.. darn).

Wednesday, May 12, 2010

Storing Numbers in nsIPrefService

Tip of the day: don't use nsIPrefService to store JavaScript Number objects when writing a Firefox extension. Take a look at what happens in XPCShell:

js> var prefService = Components.classes["@mozilla.org/preferences-service;1"].
    getService(Components.interfaces.nsIPrefService);
js> var branch = prefService.getBranch("foo");
js> Date.now();
1273727558711
js> branch.setIntPref("date", Date.now());
js> branch.getIntPref("date");
-1877723439

The reason for this is that while JavaScript Number objects do not overflow, underlying ints in the C++ code that nsIPrefService is implemented in certainly will. I really should've been tipped off by the setIntPref method name =P

Monday, May 10, 2010

Peeking inside Components.classes for Firefox 3.5.8

For the longest time, I had wondered what kind of magical smurfs, krakens, and leprechauns lived inside of Components.classes; but today I felt like sort of an idiot because I realized I could just do this:

echo "for(var p in Components.classes){print(p)}" | xpcshell | sort > cc.txt
echo "for(var p in Components.interfaces){print(p)}" | xpcshell | sort > ci.txt

The xpcshell function is just a little bash function I have for running XPCShell (on Debian, XULRunner binaries are located in /usr/lib/xulrunner-1.9.1; they may vary for the reader):

function xpcshell {
  local DIR=/usr/lib/xulrunner-1.9.1
  $DIR/run-mozilla.sh $DIR/xpcshell $@
}

This is a pretty good tool for testing extension code out, as long as you don't want to do anything with a ChromeWindow; it'll crash if you try to get fresh with it like that!

$ xpcshell
[loading 'xpcshell.js'...]
js> var app = Components.classes["@mozilla.org/appshell/appShellService;1"].
  getService(Components.interfaces.nsIAppShellService);
js> var uri = Components.classes["@mozilla.org/network/io-service;1"].
  getService(Components.interfaces.nsIIOService).
  newURI("http://developer.mozilla.org", null, null);
js> app.createTopLevelWindow(null, uri, 0, 0, 0, null);

(process:8032): Gdk-CRITICAL **: gdk_screen_get_rgb_visual: assertion `GDK_IS_SCREEN (screen)' failed
/usr/lib/xulrunner-1.9.1/run-mozilla.sh: line 131:  8032 Segmentation fault      "$prog" ${1+"$@"}

Sources

https://developer.mozilla.org/en/XPCOM_Interface_Reference/nsIAppShellService
https://developer.mozilla.org/En/NsIURL