Firefox 4: Fixing middlemouse.content load, and hacking jars (Shallow Thoughts)

Akkana's Musings on Open Source Computing and Technology, Science, and Nature.

Mon, 09 May 2011

Firefox 4: Fixing middlemouse.content load, and hacking jars

Mostly the transition to Firefox4 has pretty smooth. But there's been one big hassle: middlemouse content load URL doesn't work as well as it used to.

Middlemouse content load is a great Firefox feature on Linux and other Unix platforms. You see a URL somewhere that doesn't have clickable URLs -- say, a plaintext mail message, or something somebody typed in IRC. You highlight it with the mouse -- no need to Copy explicitly -- X does that automatically whenever you highlight text). Then move to the Firefox window and click the middle mouse button somewhere in the content window -- anywhere as long as it's not over a link or text input -- and Firefox goes straight to the URL you pasted.

A few silly Linux distros, like Ubuntu, disable this feature by default. You can turn it back on by going to about:config, searching for middlemouse, and setting middlemouse.contentLoadURL to true.

Except, in Firefox 4, much of the time nothing happens. In Firefox 4, contentLoadURL only works if the URL you pasted is a complete URL, like http://example.com. This is completely silly, because most of the time, if you had a complete URL, it would have been clickable already in whatever window you originally found it in. When you need contentLoadURL is when someone types "Go to example.com if you want to see this". It's also great for when you get those horrible Facebook or Stumbleupon or Google URLs like http://www.facebook.com/l/bfd4f/example.com/somelink and you want just the real link (example.com/somelink), without the added cruft.

Hacking the jar

Hooray! It turns out the offending code is in browser.js, so it's hackable without needing to recompile all of Firefox. You just need to unpack omni.jar, patch browser.js, then zip up a new omni.jar.

In other words, something like this (on Ubuntu Natty, starting in an empty directory):

$ cp /usr/lib/firefox-4.0/omni.jar ~/omni-jar.sav
$ unzip /usr/lib/firefox-4.0/omni.jar
  [ edit or patch chrome/browser/content/browser/browser.js ]
$ rm -f /tmp/new-omni.jar; zip /tmp/new-omni.jar `find .`
$ sudo cp /tmp/new-omni.jar /usr/lib/firefox-4.0/omni.jar

Getting Firefox to notice code changes

Except, as I was testing this, I discovered: I could make changes and most of the time Firefox wouldn't see them. I would put in something obvious like alert("Hello, world");, verify that the alert was really in omni.jar, run Firefox, click the middle mouse button and -- no alert. Where was Firefox getting the code it was actually running, if not from omni.jar?

I'll spare you the agonizing details of the hunt and just say that eventually I discovered that if I ran Firefox from a different profile on the same machine, I got a different result. It turns out that if you remove either of two files, extensions.sqlite and XUL.mfasl, Firefox4 will re-read the new code in omni.jar.

Removing XUL.mfasl seems to be a little safer: extensions.sqlite contains some details of which extensions are enabled. Of course, back up both files first before experimenting with removing them.

Why these files are keeping a cache of code that's already in omni.jar is anybody's guess.

The Patch: fix contentLoadURL

Oh, and the change? Mikachu came up with a cleaner fix than mine, so this is his. It accepts partial URLs like example.com and also bookmarklet keywords:

--- browser.js.sav      2011-05-07 16:40:03.672540242 -0700
+++ omni/chrome/browser/content/browser/browser.js      2011-05-08 16:29:28.943313984 -0700
@@ -10597,12 +10597,10 @@
   clipboard.replace(/\s*\n\s*/g, "");
 
   let url = getShortcutOrURI(clipboard);
-  try {
-    makeURI(url);
-  } catch (ex) {
-    // Not a valid URI.
-    return;
-  }
+  var URIFixup = Components.classes["@mozilla.org/docshell/urifixup;1"]
+                           .getService(Components.interfaces.nsIURIFixup);
+  url = URIFixup.createFixupURI(url, 1).spec;
+  // 1 is FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP
 
   try {
     addToUrlbarHistory(url);

Tags: , , ,
[ 20:28 May 09, 2011    More tech/web | permalink to this entry | ]

Comments via Disqus:

blog comments powered by Disqus