Shallow Thoughts : tags : firefox

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

Thu, 28 Sep 2023

Opening a URL in a New Tab of an Existing Browser Window

My search for a good desktop Mastodon client has led me down a path that involved learning some fun ways to interact with existing browser windows on Linux with X programs like xdotool and wmctrl.

Like many people, I've switched from The App Formerly Known As Twitter to Mastodon (where I'm @akkana@fosstodon.org). But the next question was which Mastodon app to use.

Read more ...

Tags: , , , , , ,
[ 11:48 Sep 28, 2023    More linux | permalink to this entry | ]

Tue, 10 Jan 2023

Exploring your Search History in Firefox

I wanted to find something I'd googled for recently. That should be easy, right? Just go to the browser's history window.

Well, actually not so much. You can see them in Firefox's history window, but they're interspersed with all the other places you've surfed so it's hard to skim the list quickly.

I decided to take a little time and figure out how to extract the search terms. I was pretty sure that they were in places.sqlite3 inside the firefox profile. And they were.

Read more ...

Tags: , , ,
[ 16:54 Jan 10, 2023    More tech/web | permalink to this entry | ]

Sat, 29 Jan 2022

View or Reset All Your Firefox Zoom Settings

Firefox's zoom settings are useful. You can zoom in on a page with Ctrl-+ (actually Ctrl-+ on a US-English keyboard), or out with Ctrl--.

Useful, that is, until you start noticing that lots of pages you visit have weirdly large or small font sizes, and it turns out that Firefox is remembering a Zoom setting you used on that site half a year ago on a different monitor.

Whenever you zoom, Firefox remembers that site, and uses that zoom setting any time you go to that site forevermore (unless you zoom back out).

Now that I'm using the same laptop in different modes — sometimes plugged into a monitor, sometimes using its own screen — that has become a problem.

Read more ...

Tags: , , ,
[ 18:04 Jan 29, 2022    More tech/web | permalink to this entry | ]

Fri, 03 Dec 2021

Importing Cookies from a Firefox Profile in Python

I wrote at length about my explorations into selenium to fetch stories from the New York Times (as a subscriber). But I mentioned in Part III that there was a much easier way to fetch those stories, as long as the stories didn't need JavaScript.

That way is to use normal file fetching (using urllib or requests), but with a CookieJar object containing the cookies from a Firefox session where I'd logged in.

Read more ...

Tags: , , , ,
[ 12:22 Dec 03, 2021    More programming | permalink to this entry | ]

Mon, 15 Nov 2021

Removing Bad Autocompletes from Firefox's Location Bar

A priest, a minister, and a rabbit walk into a bar.
The bartender asks the rabbit what he'll have to drink.
"How should I know?" says the rabbit. "I'm only here because of autocomplete."

Firefox folks like to call the location bar/URL bar the "awesomebar" because of the suggestions it makes. Sometimes, those suggestions are pretty great; there are a lot of sites I don't bother to bookmark because I know they will show up as the first suggestion.

Other times, the "awesomebar" not so awesome. It gets stuck on some site I never use, and there's seemingly no way to make Firefox forget that site.

Read more ...

Tags: , ,
[ 16:54 Nov 15, 2021    More tech/web | permalink to this entry | ]

Fri, 06 Aug 2021

Firefox Broken on Local Domains

I maintain quite a few domains, both domains I own and domains belonging to various nonprofits I belong to. For testing these websites, I make virtual domains in apache, choosing an alias for each site. For instance, for the LWVNM website, the apache site file has

<VirtualHost *:80>
    ServerName lwvlocal
and my host table, /etc/hosts, has
127.0.0.1    localhost lwvlocal
(The localhost line in my host table has entries for all the various virtual hosts I use, not just this one).

That all used to work fine. If I wanted to test a new page on the LWVNM website, I'd go to Firefox's urlbar and type something like lwvlocal/newpage.html and it would show me the new page, which I could work on until it was time to push it to the web server.

A month or so ago, a new update to Firefox broke that.

Read more ...

Tags: ,
[ 13:34 Aug 06, 2021    More tech/web | permalink to this entry | ]

Mon, 19 Jul 2021

Hack to fix Firefox 90.0's new invisible menu

Yesterday I started up my browser and discovered that I had no menu.

[Invisible Firefox menubar]

I understand that Mozilla wants us not to use the menu ... because why would anyone want to use any of Firefox's zillions of useful features that aren't available through the hamburger menu? ... but they've always made it possible to show a menubar if you really want one. Right-click in the area where the tabs are, and there's an option for Menu Bar that you can turn on.

And that option was still there, and the space above the tabs where it should show up was still taking up space ... there just weren't any menu buttons to click on.

Except they were. I tried clicking near the left edge and a familiar File menu popped up. Aha! The menubar is still there; it's just invisible. (In the screenshot above, if you look hard you can actually see the menu items, barely; in the theme I was actually using, which got uninstalled while I flailed around trying to fix the problem, they were much less visible.)

Read more ...

Tags:
[ 18:46 Jul 19, 2021    More tech/web | permalink to this entry | ]

Sat, 08 Aug 2020

U is for Unreliable UI (or: Why Firefox's "Do this automatically this from now on" checkbox is so flaky, and how to work around it)

It's been a frustration with Firefox for years. You click on a link and get the "What should Firefox do with this file?" dialog, even though it's a file type you view all the time -- PDF, say, or JPEG. You click "View in browser" or "Save file" or whatever ... then you check the "Do this automatically for files like this from now on" checkbox, thinking, I'm sure I checked this last time.

Then a few minutes later, you go to a file of the exact same time, and you get the dialog again. That damn checkbox is like the button on street crossings or elevators: a no-op to make you think you're doing something.

I never tried to get to the bottom of why this happens with some PDFs and not others, some JPGs but not others. But Los Alamos puts their government meetings on a site called Legistar. Legistar does everything as PDF -- and those PDFs all trigger this Firefox bug, prompting for a download rather than displaying in Firefox's PDF viewer.

Read more ...

Tags: , ,
[ 16:38 Aug 08, 2020    More tech/web | permalink to this entry | ]

Sun, 29 Jul 2018

Building Firefox: Changing the App Name

In my several recent articles about building Firefox from source, I omitted one minor change I made, which will probably sound a bit silly. A self-built Firefox thinks its name is "Nightly", so, for example, the Help menu includes About Nightly.

Somehow I found that unreasonably irritating. It's not a nightly build; in fact, I hope to build it as seldom as possible, ideally only after a git pull when new versions are released. Yet Firefox shows its name in quite a few places, so you're constantly faced with that "Nightly". After all the work to build Firefox, why put up with that?

To find where it was coming from, I used my recursive grep alias which skips the obj- directory plus things like object files and metadata. This is how I define it in my .zshrc (obviously, not all of these clauses are necessary for this Firefox search), and then how I called it to try to find instances of "Nightly" in the source:

gr() {
  find . \( -type f -and -not -name '*.o' -and -not -name '*.so' -and -not -name '*.a' -and -not -name '*.pyc' -and -not -name '*.jpg' -and -not -name '*.JPG' -and -not -name '*.png' -and -not -name '*.xcf*' -and -not -name '*.gmo' -and -not -name '.intltool*' -and -not -name '*.po' -and -not -name 'po' -and -not -name '*.tar*' -and -not -name '*.zip' -or -name '.metadata' -or -name 'build' -or -name 'obj-*' -or -name '.git' -or -name '.svn' -prune \) -print0 | xargs -0 grep $* /dev/null
}

gr Nightly | grep -v '//' | grep -v '#' | grep -v isNightly  | grep test | grep -v task | fgrep -v .js | fgrep -v .cpp | grep -v mobile >grep.out

Even with all those exclusions, that still ends up printing an enormous list. But it turns out all the important hits are in the browser directory, so you can get away with running it from there rather than from the top level.

I found a bunch of likely files that all had very similar "Nightly" lines in them:

Since I didn't know which one was relevant, I changed each of them to slightly different names, then rebuilt and checked to see which names I actually saw while running the browser.

It turned out that browser/branding/unofficial/locales/en-US/brand.dtd is the file that controls the application name in the Help menu and in Help->About -- though the title of the About window is still "Nightly" and I haven't found what controls that.

branding/unofficial/locales/en-US/brand.ftl controls the "Nightly" references in the Edit->Preferences window.

I don't know what all the others do. There may be other instances of "Nightly" that appear elsewhere in the app, the other files, but I haven't seen them yet.

Past Firefox building articles: Building Firefox Quantum; Building Firefox for ALSA (non PulseAudio) Sound; Firefox Quantum: Fixing Ctrl W (or other key bindings).

Tags: , , ,
[ 18:23 Jul 29, 2018    More tech/web | permalink to this entry | ]

Sat, 07 Jul 2018

Script to modify omni.ja for a custom Firefox

A quick followup to my article on Modifying Firefox Files Inside omni.ja:

The steps for modifying the file are fairly easy, but they have to be done a lot.

First there's the problem of Firefox updates: if a new omni.ja is part of the update, then your changes will be overwritten, so you'll have to make them again on the new omni.ja.

But, worse, even aside from updates they don't stay changed. I've had Ctrl-W mysteriously revert back to its old wired-in behavior in the middle of a Firefox session. I'm still not clear how this happens: I speculate that something in Firefox's update mechanism may allow parts of omni.ja to be overridden, even though I was told by Mike Kaply, the onetime master of overlays, that they weren't recommended any more (at least by users, though that doesn't necessarily mean they're not used for updates).

But in any case, you can be browsing merrily along and suddenly one of your changes doesn't work any more, even though the change is still right there in browser/omni.ja. And the only fix I've found so far is to download a new Firefox and re-apply the changes. Re-applying them to the current version doesn't work -- they're already there. And it doesn't help to keep the tarball you originally downloaded around so you can re-install that; firefox updates every week or two so that version is guaranteed to be out of date.

All this means that it's crazy not to script the omni changes so you can apply them easily with a single command. So here's a shell script that takes the path to the current Firefox, unpacks browser/omni.ja, makes a couple of simple changes and re-packs it. I called it kitfox-patch since I used to call my personally modified Firefox build "Kitfox".

Of course, if your changes are different from mine you'll want to edit the script to change the sed commands.

I hope eventually to figure out how it is that omni.ja changes stop working, and whether it's an overlay or something else, and whether there's a way to re-apply fixes without having to download a whole new Firefox. If I figure it out I'll report back.

Tags: ,
[ 15:01 Jul 07, 2018    More tech/web | permalink to this entry | ]

Sat, 23 Jun 2018

Modifying Firefox Files Inside Omni.ja

My article on Fixing key bindings in Firefox Quantum by modifying the source tree got attention from several people who offered helpful suggestions via Twitter and email on how to accomplish the same thing using just files in omni.ja, so it could be done without rebuilding the Firefox source. That would be vastly better, especially for people who need to change something like key bindings or browser messages but don't have a souped-up development machine to build the whole browser.

Brian Carpenter had several suggestions and eventually pointed me to an old post by Mike Kaply, Don’t Unpack and Repack omni.ja[r] that said there were better ways to override specific files.

Unfortunately, Mike Kaply responded that that article was written for XUL extensions, which are now obsolete, so the article ought to be removed. That's too bad, because it did sound like a much nicer solution. I looked into trying it anyway, but the instructions it points to for Overriding specific files is woefully short on detail on how to map a path inside omni.ja like chrome://package/type/original-uri.whatever, to a URL, and the single example I could find was so old that the file it referenced didn't exist at the same location any more. After a fruitless half hour or so, I took Mike's warning to heart and decided it wasn't worth wasting more time chasing something that wasn't expected to work anyway. (If someone knows otherwise, please let me know!)

But then Paul Wise offered a solution that actually worked, as an easy to follow sequence of shell commands. (I've changed some of them very slightly.)

$ tar xf ~/Tarballs/firefox-60.0.2.tar.bz2
  # (This creates a "firefox" directory inside the current one.)

$ mkdir omni
$ cd omni

$ unzip -q ../firefox/browser/omni.ja
warning [../firefox-60.0.2/browser/omni.ja]:  34187320 extra bytes at beginning or within zipfile
  (attempting to process anyway)
error [../firefox-60.0.2/browser/omni.ja]:  reported length of central directory is
  -34187320 bytes too long (Atari STZip zipfile?  J.H.Holm ZIPSPLIT 1.1
  zipfile?).  Compensating...
zsh: exit 2     unzip -q ../firefox-60.0.2/browser/omni.ja

$ sed -i 's/or enter address/or just twiddle your thumbs/' chrome/en-US/locale/browser/browser.dtd chrome/en-US/locale/browser/browser.properties

I was a little put off by all the warnings unzip gave, but kept going.

Of course, you can just edit those two files rather than using sed; but the sed command was Paul's way of being very specific about the changes he was suggesting, which I appreciated.

Use these flags to repackage omni.ja:

$ zip -qr9XD ../omni.ja *

I had tried that before (without the q since I like to see what zip and tar commands are doing) and hadn't succeeded. And indeed, when I listed the two files, the new omni.ja I'd just packaged was about a third the size of the original:

$ ls -l ../omni.ja ../firefox-60.0.2/browser/omni.ja
-rw-r--r-- 1 akkana akkana 34469045 Jun  5 12:14 ../firefox/browser/omni.ja
-rw-r--r-- 1 akkana akkana 11828315 Jun 17 10:37 ../omni.ja

But still, it's worth a try:

$ cp ../omni.ja ../firefox/browser/omni.ja

Then run the new Firefox. I have a spare profile I keep around for testing, but Paul's instructions included a nifty way of running with a brand new profile and it's definitely worth knowing:

$ cd ../firefox

$ MOZILLA_DISABLE_PLUGINS=1 ./firefox -safe-mode -no-remote -profile $(mktemp -d tmp-firefox-profile-XXXXXXXXXX) -offline about:blank

Also note the flags like safe-mode and no-remote, plus disabling plugins -- all good ideas when testing something new.

And it worked! When I started up, I got the new message, "Search or just twiddle your thumbs", in the URL bar.

Fixing Ctrl-W

Of course, now I had to test it with my real change. Since I like Paul's way of using sed to specify exactly what changes to make, here's a sed version of my Ctrl-W fix:

$ sed -i '/key_close/s/ reserved="true"//' chrome/browser/content/browser/browser.xul

Then run it. To test Ctrl-W, you need a website that includes a text field you can type in, so -offline isn't an option unless you happen to have a local web page that includes some text fields. Google is an easy way to test ... and you might as well re-use that firefox profile you just made rather than making another one:

$ MOZILLA_DISABLE_PLUGINS=1 ./firefox -safe-mode -no-remote -profile tmp-firefox-profile-* https://google.com

I typed a few words in the google search field that came up, deleted them with Ctrl-W -- all was good! Thanks, Paul! And Brian, and everybody else who sent suggestions.

Why are the sizes so different?

I was still puzzled by that threefold difference in size between the omni.ja I repacked and the original that comes with Firefox. Was something missing? Paul had the key to that too: use zipinfo on both versions of the file to see what differed. Turned out Mozilla's version, after a long file listing, ends with

2650 files, 33947999 bytes uncompressed, 33947999 bytes compressed:  0.0%
while my re-packaged version ends with
2650 files, 33947969 bytes uncompressed, 11307294 bytes compressed:  66.7%

So apparently Mozilla's omni.ja is using no compression at all. It may be that that makes it start up a little faster; but Quantum takes so long to start up that any slight difference in uncompressing omni.ja isn't noticable to me.

I was able to run through this whole procedure on my poor slow netbook, the one where building Firefox took something like 15 hours ... and in a few minutes I had a working modified Firefox. And with the sed command, this is all scriptable, so it'll be easy to re-do whenever Firefox has a security update. Win!

Update: I have a simple shell script to do this: Script to modify omni.ja for a custom Firefox.

Tags: ,
[ 20:37 Jun 23, 2018    More tech/web | permalink to this entry | ]

Thu, 14 Jun 2018

Firefox Quantum: Fixing Ctrl W (or other key bindings)

When I first tried switching to Firefox Quantum, the regression that bothered me most was Ctrl-W, which I use everywhere as word erase (try it -- you'll get addicted, like I am). Ctrl-W deletes words in the URL bar; but if you type Ctrl-W in a text field on a website, like when editing a bug report or a "Contact" form, it closes the current tab, losing everything you've just typed. It's always worked in Firefox in the past; this is a new problem with Quantum, and after losing a page of typing for about the 20th time, I was ready to give up and find another browser.

A web search found plenty of people online asking about key bindings like Ctrl-W, but apparently since the deprecation of XUL and XBL extensions, Quantum no longer offers any way to change or even just to disable its built-in key bindings.

I wasted a few days chasing a solution inspired by this clever way of remapping keys only for certain windows using xdotool getactivewindow; I even went so far as to write a Python script that intercepts keystrokes, determines the application for the window where the key was typed, and remaps it if the application and keystroke match a list of keys to be remapped. So if Ctrl-W is typed in a Firefox window, Firefox will instead receive Alt-Backspace. (Why not just type Alt-Backspace, you ask? Because it's much harder to type, can't be typed from the home position, and isn't in the same place on every keyboard the way W is.)

But sadly, that approach didn't work because it turned out my window manager, Openbox, acts on programmatically-generated key bindings as well as ones that are actually typed. If I type a Ctrl-W and it's in Firefox, that's fine: my Python program sees it, generates an Alt-Backspace and everything is groovy. But if I type a Ctrl-W in any other application, the program doesn't need to change it, so it generates a Ctrl-W, which Openbox sees and calls the program again, and you have an infinite loop. I couldn't find any way around this. And admittedly, it's a horrible hack having a program intercept every keystroke. So I needed to fix Firefox somehow.

But after spending days searching for a way to customize Firefox's keys, to no avail, I came to the conclusion that the only way was to modify the source code and rebuild Firefox from source.

Ironically, one of the snags I hit in building it was that I'd named my key remapper "pykey.py", and it was still in my PYTHONPATH; it turns out the Firefox build also has a module called pykey.py and mine was interfering. But eventually I got the build working.

Firefox Key Bindings

I was lucky: building was the only hard part, because a very helpful person on Mozilla's #introduction IRC channel pointed me toward the solution, saving me hours of debugging. Edit browser/base/content/browser-sets.inc around line 240 and remove reserved="true" from key_closeWindow. It turned out I needed to remove reserved="true" from the adjacent key_close line as well.

Another file that's related, but more general, is nsXBLWindowKeyHandler.cpp around line 832; but I didn't need that since the simpler fix worked.

Transferring omni.ja -- or Not

In theory, since browser-sets.inc isn't compiled C++, it seems like you should be able to make this fix without building the whole source tree. In an actual Firefox release, browser-sets.inc is part of omni.ja, and indeed if you unpack omni.ja you'll see the key_closeWindow and key_close lines. So it seems like you ought to be able to regenerate omni.ja without rebuilding all the C++ code.

Unfortunately, in practice omni.ja is more complicated than that. Although you can unzip it and edit the files, if you zip it back up, Firefox doesn't see it as valid. I guess that's why they renamed it .ja: long ago it used to be omni.jar and, like other .jar files, was a standard zip archive that you could edit. But the new .ja file isn't documented anywhere I could find, and all the web discussions I found on how to re-create it amounted to "it's complicated, you probably don't want to try".

And you'd think that I could take the omni.ja file from my desktop machine, where I built Firefox, and copy it to my laptop, replacing the omni.ja file from a released copy of Firefox. But no -- somehow, it isn't seen, and the old key bindings are still active. They must be duplicated somewhere else, and I haven't figured out where.

It sure would be nice to have a way to transfer an omni.ja. Building Firefox on my laptop takes nearly a full day (though hopefully rebuilding after pulling minor security updates won't be quite so bad). If anyone knows of a way, please let me know!

Tags: , ,
[ 16:45 Jun 14, 2018    More tech/web | permalink to this entry | ]

Sat, 09 Jun 2018

Building Firefox for ALSA (non PulseAudio) Sound

I did the work to built my own Firefox primarily to fix a couple of serious regressions that couldn't be fixed any other way. I'll start with the one that's probably more common (at least, there are many people complaining about it in many different web forums): the fact that Firefox won't play sound on Linux machines that don't use PulseAudio.

There's a bug with a long discussion of the problem, Bug 1345661 - PulseAudio requirement breaks Firefox on ALSA-only systems; and the discussion in the bug links to another discussion of the Firefox/PulseAudio problem). Some comments in those discussions suggest that some near-future version of Firefox may restore ALSA sound for non-Pulse systems; but most of those comments are six months old, yet it's still not fixed in the version Mozilla is distributing now.

In theory, ALSA sound is easy to enable. Build pptions in Firefox are controlled through a file called mozconfig. Create that file at the top level of your build directory, then add to it:

ac_add_options --enable-alsa
ac_add_options --disable-pulseaudio

You can see other options with ./configure --help

Of course, like everything else in the computer world, there were complications. When I typed mach build, I got:

Assertion failed in _parse_loader_output:
Traceback (most recent call last):
  File "/home/akkana/outsrc/gecko-dev/python/mozbuild/mozbuild/mozconfig.py", line 260, in read_mozconfig
    parsed = self._parse_loader_output(output)
  File "/home/akkana/outsrc/gecko-dev/python/mozbuild/mozbuild/mozconfig.py", line 375, in _parse_loader_output
    assert not in_variable
AssertionError
Error loading mozconfig: /home/akkana/outsrc/gecko-dev/mozconfig

Evaluation of your mozconfig produced unexpected output.  This could be
triggered by a command inside your mozconfig failing or producing some warnings
or error messages. Please change your mozconfig to not error and/or to catch
errors in executed commands.

mozconfig output:

------BEGIN_ENV_BEFORE_SOURCE
... followed by a many-page dump of all my environment variables, twice.

It turned out that was coming from line 449 of python/mozbuild/mozbuild/mozconfig.py:

   # Lines with a quote not ending in a quote are multi-line.
    if has_quote and not value.endswith("'"):
        in_variable = name
        current.append(value)
        continue
    else:
        value = value[:-1] if has_quote else value

I'm guessing this was added because some Mozilla developer sets a multi-line environment variable that has a quote in it but doesn't end with a quote. Or something. Anyway, some fairly specific case. I, on the other hand, have a different specific case: a short environment variable that includes one or more single quotes, and the test for their specific case breaks my build.

(In case you're curious why I have quotes in an environment variable: The prompt-setting code in my .zshrc includes a variable called PRIMES. In a login shell, this is set to the empty string, but in subshells, I add ' for each level of shell under the login shell. So my regular prompt might be (hostname)-, but if I run a subshell to test something, the prompt will be (hostname')-, a subshell inside that will be (hostname'')-, and so on. It's a reminder that I'm still in a subshell and need to exit when I'm done testing. In theory, I could do that with SHLVL, but SHLVL doesn't care about login shells, so my normal shells inside X are all SHLVL=2 while shells on a console or from an ssh are SHLVL=1, so if I used SHLVL I'd have to have some special case code to deal with that.

Also, of course I could use a character other than a single-quote. But in the thirty or so years I've used this, Firefox is the first program that's ever had a problem with it. And apparently I'm not the first one to have a problem with this: bug 1455065 was apparently someone else with the same problem. Maybe that will show up in the release branch eventually.)

Anyway, disabling that line fixed the problem:

   # Lines with a quote not ending in a quote are multi-line.
    if False and has_quote and not value.endswith("'"):
and after that, mach build succeeded, I built a new Firefox, and lo and behond! I can play sound in YouTube videos and on Xeno-Canto again, without needing an additional browser.

Tags: , ,
[ 16:49 Jun 09, 2018    More tech/web | permalink to this entry | ]

Sun, 03 Jun 2018

Building Firefox Quantum

With Firefox Quantum, Mozilla has moved away from letting users configure the browser they way they like. If I was going to switch to Quantum as my everyday browser, there were several problems I needed to fix first -- and they all now require modifying the source code, then building the whole browser from scratch.

I'll write separately about fixing the specific problems; but first I had to build Firefox. Although I was a Firefox developer way back in the day, the development environment has changed completely since then, so I might as well have been starting from scratch.

Setting up a Firefox build

I started with Mozilla's Linux build preparation page. There's a script called bootstrap.py that's amazingly comprehensive. It will check what's installed on your machine and install what's needed for a Firefox build -- and believe me, there are a lot of dependencies. Don't take the "quick" part of the "quick and easy" comment at the beginning of the script too seriously; I think on my machine, which already has a fairly full set of build tools, the script was downloading additional dependencies for 45 minutes or so. But it was indeed fairly easy: the script asks lots of questions about optional dependencies, and usually has suggestions, which I mostly followed.

Eventually bootstrap.py finishes loading the dependencies and gets to the point of wanting to check out the mozilla-unified repository, and that's where I got into trouble.

The script wants to check out the bleeding edge tip of Mozilla development. That's what you want if you're a developer checking in to the project. What I wanted was a copy of the currently released Firefox, but with a chance to make my own customizations. And that turns out to be difficult.

Getting a copy of the release tree

In theory, once you've checked out mozilla-unified with Mercurial, assuming you let bootstrap.py enable the recommended "firefoxtree" hg extension (which I did), you can switch to the release branch with:

hg pull release
hg up -c release

That didn't work for me: I tried it numerous times over the course of the day, and every time it died with "abort: HTTP request error (incomplete response; expected 5328 bytes got 2672)" after "adding manifests" when it started "adding file changes".

That sent me on a long quest aided by someone in Mozilla's helpful #introduction channel, where they help people with build issues. You might think it would be a common thing to want to build a copy of the released version of Firefox, and update it when a new release comes out. But apparently not; although #introduction is a friendly and helpful channel, everyone seemed baffled as to why hg up didn't work and what the possible alternatives might be.

Bundles and Artifacts

Eventually someone pointed me to the long list of "bundle" tarballs and advised me on how to get a release tarball there. I actually did that, and (skipping ahead briefly) it built and ran; but I later discovered that "bundles" aren't actually hg repositories and can't be updated. So once you've downloaded your 3 gigabytes or so of Mozilla stuff and built it, it's only good for a week or two until the next Mozilla release, when you're now hopelessly out of date and have to download a whole nuther bundle. Bundles definitely aren't the answer, and they aren't well supported or documented either. I recommend staying away from them.

I should also mention "artifact builds". These sound like a great idea: a lot of the source is already built for you, so you just build a little bit of it. However, artifact builds are only available for a few platforms and branches. If your OS differs in any way from whoever made the artifact build, or if you're requesting a branch, you're likely to waste a lot of time (like I did) downloading stuff only to get mysterious error messages. And even if it works, you won't be able to update it to keep on top of security fixes. Doesn't seem like a good bet.

GitHub to the rescue

Okay, so Mercurial's branch switching doesn't work. But it turns out you don't have to use Mercurial. There's a GitHub mirror for Firefox called gecko-dev, and after cloning it you can use normal git commands to switch branches:

git clone https://github.com/mozilla/gecko-dev.git
cd gecko-dev/
git checkout -t origin/release

You can verify you're on the right branch with git branch -vv, or if you want to list all branches and their remotes, git branch -avv.

Finally: a Firefox release branch that you can actually update!

Building Firefox

Once you have a source tree, you can use the all-powerful mach script to build the current release of Firefox:

./mach build

Of course that takes forever -- hours and hours, depending on how fast your machine is.

Running your New Firefox

The build, after it finishes, helpfully tells you to test it with ./mach run, which runs your newly-built firefox with a special profile, so it doesn't interfere with your running build. It also prints:

For more information on what to do now, see https://developer.mozilla.org/docs/Developer_Guide/So_You_Just_Built_Firefox

Great! Except there's no information there on how to package or run your build -- it's just a placeholder page asking people to contribute to the page.

It turns out that obj-whatever/dist/bin is the directory that corresponds to the tarball you download from Mozilla, and you can run /path/to/mozilla-release/obj-whatever/dist/bin/firefox from anywhere.

I tried filing a bug request to have a sub-page created explaining how to run a newly built Firefox, but it hasn't gotten any response. Maybe I'll just edit the "So You Just Built" page.

Update, 7 months later:
Nobody ever did respond to my bug, but someone on Mozilla's #introduction channel for help with builds gave me a blessing to modify the page directly, which I did.

Specifically, I added:

Your new Firefox executable can be found in: $OBJDIR/dist/bin/firefox. You can run it from there.

If you need to move it, e.g. to another machine, you can run:
./mach package
This should create an OS-specific package, e.g. a tarball on Linux, which will appear in $OBJDIR/dist. You can also copy the $OBJDIR/dist/bin directory -- be sure to use a copy method that expands soft links -- but the result will be much larger than what you get with mach package. On Windows you may want to read about Windows Installer Builds.

Incidentally, my gecko-dev build takes 16G of disk space, of which 9.3G is things it built, which are helpfully segregated in obj-x86_64-pc-linux-gnu.

Tags: ,
[ 15:55 Jun 03, 2018    More tech/web | permalink to this entry | ]

Thu, 31 May 2018

Trying Firefox Variants: From Firefox ESR to Pale Moon to Quantum

For the last year or so the Firefox development team has been making life ever harder for users. First they broke all the old extensions that were based on XUL and XBL, so a lot of customizations no longer worked. Then they made PulseAudio mandatory on Linux bug (1345661), so on systems like mine that don't run Pulse, there's no way to get sound in a web page. Forget YouTube or XenoCanto unless you keep another browser around for that purpose.

For those reasons I'd been avoiding the Firefox upgrade, sticking to Debian's firefox-esr ("Extended Support Release"). But when Debian updated firefox-esr to Firefox 56 ESR late last year, performance became unusable. Like half a minute between when you hit Page Down and when the page actually scrolls. It was time to switch browsers.

Pale Moon

I'd been hearing about the Firefox variant Pale Moon. It's a fork of an older Firefox, supposedly with an emphasis on openness and configurability.

I installed the Debian palemoon package. Performance was fine, similar to Firefox before the tragic firefox-56. It was missing a few things -- no built-in PDF viewer or Reader mode -- but I don't use Reader mode that often, and the built-in PDF viewer is an annoyance at least as often as it's a help. (In Firefox it's fairly random about when it kicks in anyway, so I'm never sure whether I'll get the PDF viewer or a Save-as prompt on any given PDF link).

For form and password autofill, for some reason Pale Moon doesn't fill out fields until you type the first letter. For instance, if I had an account with name "myname" and a stored password, when I loaded the page, both fields would be empty, as if there's nothing stored for that page. But typing an 'm' in the username field makes both username and password fields fill in. This isn't something Firefox ever did and I don't particularly like it, but it isn't a major problem.

Then there were some minor irritations, like the fact that profiles were stored in a folder named ~/.moonchild\ productions/ -- super long so it messed up directory listings, and with a space in the middle. PaleMoon was also very insistent about using new tabs for everything, including URLs launched from other programs -- there doesn't seem to be any way to get it to open URLs in the active tab.

I used it as my main browser for several months, and it basically worked. But the irritations started to get to me, and I started considering other options. The final kicker when I saw Pale Moon bug 86, in which, as far as I can tell, someone working on the PaleMoon in OpenBSD tries to use system libraries instead of PaleMoon's patched libraries, and is attacked for it in the bug. Reading the exchange made me want to avoid PaleMoon for two reasons. First, the rudeness: a toxic community that doesn't treat contributors well isn't likely to last long or to have the resources to keep on top of bug and security fixes. Second, the technical question: if Pale Moon's code is so quirky that it can't use standard system libraries and needs a bunch of custom-patched libraries, what does that say about how maintainable it will be in the long term?

Firefox Quantum

Much has been made in the technical press of the latest Firefox, called "Quantum", and its supposed speed. I was a bit dubious of that: it's easy to make your program seem fast after you force everybody into a few years of working with a program that's degraded its performance by an order of magnitude, like Firefox had. After firefox 56, anything would seem fast.

Still, maybe it would at least be fast enough to be usable. But I had trepidations too. What about all those extensions that don't work any more? What about sound not working? Could I live with that?

Debian has no current firefox package, so I downloaded the tarball from mozilla.org, unpacked it, made a new firefox profile and ran it.

Initial startup performance is terrible -- it takes forever to bring up the first window, and I often get a "Firefox seems slow to start up" message at the bottom of the screen, with a link to a page of a bunch of completely irrelevant hints. Still, I typically only start Firefox once a day. Once it's up, performance is a bit laggy but a lot better than firefox-esr 56 was, certainly usable.

I was able to find replacements for most of the really important extensions (the ones that control things like cookies and javascript). But sound, as predicted, didn't work. And there were several other, worse regressions from older Firefox versions.

As it turned out, the only way to make Firefox Quantum usable for me was to build a custom version where I could fix the regressions. To keep articles from being way too long, I'll write about all those issues separately: how to build Firefox, how to fix broken key bindings, and how to fix the PulseAudio problem.

Tags: ,
[ 16:07 May 31, 2018    More tech/web | permalink to this entry | ]

Tue, 22 May 2018

Downloading all the Books in a Humble Bundle

Humble Bundle has a great bundle going right now (for another 15 minutes -- sorry, I meant to post this earlier) on books by Nebula-winning science fiction authors, including some old favorites of mine, and a few I'd been meaning to read.

I like Humble Bundle a lot, but one thing about them I don't like: they make it very difficult to download books, insisting that you click on every single link (and then do whatever "Download this link / yes, really download, to this directory" dance your browser insists on) rather than offering a sane option like a tarball or zip file. I guess part of their business model includes wanting their customers to get RSI. This has apparently been a problem for quite some time; a web search found lots of discussions of ways of automating the downloads, most of which apparently no longer work (none of the ones I tried did).

But a wizard friend on IRC quickly came up with a solution: some javascript you can paste into Firefox's console. She started with a quickie function that fetched all but a few of the files, but then modified it for better error checking and the ability to get different formats.

In Firefox, open the web console (Tools/Web Developer/Web Console) and paste this in the single-line javascript text field at the bottom.

// How many seconds to delay between downloads.
var delay = 1000;
// whether to use window.location or window.open
// window.open is more convenient, but may be popup-blocked
var window_open = false;
// the filetypes to look for, in order of preference.
// Make sure your browser won't try to preview these filetypes.
var filetypes = ['epub', 'mobi', 'pdf'];

var downloads = document.getElementsByClassName('download-buttons');
var i = 0;
var success = 0;

function download() {
  var children = downloads[i].children;
  var hrefs = {};
  for (var j = 0; j < children.length; j++) {
    var href = children[j].getElementsByClassName('a')[0].href;
    for (var k = 0; k < filetypes.length; k++) {
      if (href.includes(filetypes[k])) {
        hrefs[filetypes[k]] = href;
        console.log('Found ' + filetypes[k] + ': ' + href);
      }
    }
  }
  var href = undefined;
  for (var k = 0; k < filetypes.length; k++) {
    if (hrefs[filetypes[k]] != undefined) {
      href = hrefs[filetypes[k]];
      break;
    }
  }
  if (href != undefined) {
    console.log('Downloading: ' + href);
    if (window_open) {
      window.open(href);
    } else {
      window.location = href;
    }
    success++;
  }
  i++;
  console.log(i + '/' + downloads.length + '; ' + success + ' successes.');
  if (i < downloads.length) {
    window.setTimeout(download, delay);
  }
}
download();

If you have "Always ask where to save files" checked in Preferences/General, you'll still get a download dialog for each book (but at least you don't have to click; you can hit return for each one). Even if this is your preference, you might want to consider changing it before downloading a bunch of Humble books.

Anyway, pretty cool! Takes the sting out of bundles, especially big ones like this 42-book collection.

Tags: , , ,
[ 17:49 May 22, 2018    More tech/web | permalink to this entry | ]

Fri, 11 May 2018

Making Videos (that work in Firefox) from a Series of Images

I was working on a weather project to make animated maps of the jet stream. Getting and plotting wind data is a much longer article (coming soon), but once I had all the images plotted, I wanted to combine them all into a time-lapse video showing how the jet stream moves.

Like most projects, it's simple once you find the right recipe. If your images are named outdir/filename00.png, outdir/filename01.png, outdir/filename02.png and so on, you can turn them into an MPEG4 video with ffmpeg:

ffmpeg -i outdir/filename%2d.png -filter:v "setpts=6.0*PTS" -pix_fmt yuv420p jetstream.mp4

%02d, for non-programmers, just means a 2-digit decimal integer with leading zeros, If the filenames just use 1, 2, 3, ... 10, 11 without leading zeros, use %2d instead; if they have three digits, use %03d or %3d, and so on.

Update: If your first photo isn't numbered 00, you can set a -start_number — but it must come before the -i and filename template. For instance:

ffmpeg -start_number 17 --i outdir/filename%2d.png -filter:v "setpts=6.0*PTS" -pix_fmt yuv420p jetstream.mp4

That "setpts=6.0*PTS" controls the speed of the playback, by adding or removing frames. PTS stands for "Presentation TimeStamps", which apparently is a measure of how far along a frame is in the file; setpts=6.0*PTS means for each frame, figure out how far it would have been in the file (PTS) and multiply that by 6. So if a frame would normally have been at timestamp 10 seconds, now it will be at 60 seconds, and the video will be six times longer and six times slower. And yes, you can also use values less than one to speed a video up. You can also change a video's playback speed by changing the frame rate, either with the -r option, e.g. -r 30, or with the fps filter, filter:v fps=30. The default frame rate is 25.

You can examine values like the frame rate, number of frames and duration of a video file with: ffprobe -select_streams v -show_streams filename or with the mediainfo program (not part of ffmpeg).

The -pix_fmt yuv420p turned out to be the tricky part. The recipes I found online didn't include that part, but without it, Firefox claims "Video can't be played because the file is corrupt", even though most other browsers can play it just fine. If you open Firefox's web console and reload, it offers the additional information "Details: mozilla::SupportChecker::AddMediaFormatChecker(const mozilla::TrackInfo&)::<lambda()>: Decoder may not have the capability to handle the requested video format with YUV444 chroma subsampling.":

Adding -pix_fmt yuv420p cured the problem and made the video compatible with Firefox, though at first I had problems with ffmpeg complaining "height not divisible by 2 (1980x1113)" (even though the height of the images was in fact divisible by 2). I'm not sure what was wrong; later ffmpeg stopped giving me that error message and converted the video. It may depend on where in the ffmpeg command you put the pix_fmt flag or what other flags are present. ffmpeg arguments are a mystery to me.

Of course, if you're only making something to be uploaded to youtube, the Firefox limitation probably doesn't matter and you may not need the -pix_fmt yuv420p argument.

Animated GIFs

Making an animated GIF is easier. You can use ImageMagick's convert:

convert -delay 30 -loop 0 *.png jetstream.gif
The GIF will be a lot larger, though. For my initial test of thirty 1000 x 500 images, the MP4 was 760K while the GIF was 4.2M.

Tags: , , ,
[ 09:59 May 11, 2018    More linux | permalink to this entry | ]

Wed, 04 Jan 2017

Firefox "Reader Mode" and NoScript

A couple of days ago I blogged about using Firefox's "Delete Node" to make web pages more readable. In a subsequent Twitter discussion someone pointed out that if the goal is to make a web page's content clearer, Firefox's relatively new "Reader Mode" might be a better way.

I knew about Reader Mode but hadn't used it. It only shows up on some pages. as a little "open book" icon to the right of the URLbar just left of the Refresh/Stop button. It did show up on the Pogue Yahoo article; but when I clicked it, I just got a big blank page with an icon of a circle with a horizontal dash; no text.

It turns out that to see Reader Mode content in noscript, you must explicitly enable javascript from about:reader.

There are some reasons it's not automatically whitelisted: see discussions in bug 1158071 and bug 1166455 -- so enable it at your own risk. But it's nice to be able to use Reader Mode, and I'm glad the Twitter discussion spurred me to figure out why it wasn't working.

Tags: ,
[ 11:37 Jan 04, 2017    More tech/web | permalink to this entry | ]

Mon, 02 Jan 2017

Firefox's "Delete Node" eliminates pesky content-hiding banners

It's trendy among web designers today -- the kind who care more about showing ads than about the people reading their pages -- to use fixed banner elements that hide part of the page. In other words, you have a header, some content, and maybe a footer; and when you scroll the content to get to the next page, the header and footer stay in place, meaning that you can only read the few lines sandwiched in between them. But at least you can see the name of the site no matter how far you scroll down in the article! Wouldn't want to forget the site name!

Worse, many of these sites don't scroll properly. If you Page Down, the content moves a full page up, which means that the top of the new page is now hidden under that fixed banner and you have to scroll back up a few lines to continue reading where you left off. David Pogue wrote about that problem recently and it got a lot of play when Slashdot picked it up: These 18 big websites fail the space-bar scrolling test.

It's a little too bad he concentrated on the spacebar. Certainly it's good to point out that hitting the spacebar scrolls down -- I was flabbergasted to read the Slashdot discussion and discover that lots of people didn't already know that, since it's been my most common way of paging since browsers were invented. (Shift-space does a Page Up.) But the Slashdot discussion then veered off into a chorus of "I've never used the spacebar to scroll so why should anyone else care?", when the issue has nothing to do with the spacebar: the issue is that Page Down doesn't work right, whichever key you use to trigger that page down.

But never mind that. Fixed headers that don't scroll are bad even if the content scrolls the right amount, because it wastes precious vertical screen space on useless cruft you don't need. And I'm here to tell you that you can get rid of those annoying fixed headers, at least in Firefox.

[Article with intrusive Yahoo headers]

Let's take Pogue's article itself, since Yahoo is a perfect example of annoying content that covers the page and doesn't go away. First there's that enormous header -- the bottom row of menus ("Tech Home" and so forth) disappear once you scroll, but the rest stay there forever. Worse, there's that annoying popup on the bottom right ("Privacy | Terms" etc.) which blocks content, and although Yahoo! scrolls the right amount to account for the header, it doesn't account for that privacy bar, which continues to block most of the last line of every page.

The first step is to call up the DOM Inspector. Right-click on the thing you want to get rid of and choose Inspect Element:

[Right-click menu with Inspect Element]


That brings up the DOM Inspector window, which looks like this (click on the image for a full-sized view):

[DOM Inspector]

The upper left area shows the hierarchical structure of the web page.

Don't Panic! You don't have to know HTML or understand any of this for this technique to work.

Hover your mouse over the items in the hierarchy. Notice that as you hover, different parts of the web page are highlighted in translucent blue.

Generally, whatever element you started on will be a small part of the header you're trying to eliminate. Move up one line, to the element's parent; you may see that a bigger part of the header is highlighted. Move up again, and keep moving up, one line at a time, until the whole header is highlighted, as in the screenshot. There's also a dark grey window telling you something about the HTML, if you're interested; if you're not, don't worry about it.

Eventually you'll move up too far, and some other part of the page, or the whole page, will be highlighted. You need to find the element that makes the whole header blue, but nothing else.

Once you've found that element, right-click on it to get a context menu, and look for Delete Node (near the bottom of the menu). Clicking on that will delete the header from the page.

Repeat for any other part of the page you want to remove, like that annoying bar at the bottom right. And you're left with a nice, readable page, which will scroll properly and let you read every line, and will show you more text per page so you don't have to scroll as often.

[Article with intrusive Yahoo headers]

It's a useful trick. You can also use Inspect/Delete Node for many of those popups that cover the screen telling you "subscribe to our content!" It's especially handy if you like to browse with NoScript, so you can't dismiss those popups by clicking on an X. So happy reading!

Addendum on Spacebars

By the way, in case you weren't aware that the spacebar did a page down, here's another tip that might come in useful: the spacebar also advances to the next slide in just about every presentation program, from PowerPoint to Libre Office to most PDF viewers. I'm amazed at how often I've seen presenters squinting with a flashlight at the keyboard trying to find the right-arrow or down-arrow or page-down or whatever key they're looking for. These are all ways of advancing to the next slide, but they're all much harder to find than that great big spacebar at the bottom of the keyboard.

Tags: ,
[ 16:23 Jan 02, 2017    More tech/web | permalink to this entry | ]

Sat, 07 May 2016

Setting "Emacs" key theme in gtk3 (and Firefox 46)

I recently let Firefox upgrade itself to 46.0.1, and suddenly I couldn't type anything any more. The emacs/readline editing bindings, which I use probably thousands of times a day, no longer worked. So every time I typed a Ctrl-H to delete the previous character, or Ctrl-B to move back one character, a sidebar popped up. When I typed Ctrl-W to delete the last word, it closed the tab. Ctrl-U, to erase the contents of the urlbar, opened a new View Source tab, while Ctrl-N, to go to the next line, opened a new window. Argh!

(I know that people who don't use these bindings are rolling their eyes and wondering "What's the big deal?" But if you're a touch typist, once you've gotten used to being able to edit text without moving your hands from the home position, it's hard to imagine why everyone else seems content with key bindings that require you to move your hands and eyes way over to keys like Backspace or Home/End that aren't even in the same position on every keyboard. I map CapsLock to Ctrl for the same reason, since my hands are too small to hit the PC-positioned Ctrl key without moving my whole hand. Ctrl was to the left of the "A" key on nearly all computer keyboards until IBM's 1986 "101 Enhanced Keyboard", and it made a lot more sense than IBM's redesign since few people use Caps Lock very often.)

I found a bug filed on the broken bindings, and lots of people commenting online, but it wasn't until I found out that Firefox 46 had switched to GTK3 that I understood had actually happened. And adding gtk3 to my web searches finally put me on the track to finding the solution, after trying several other supposed fixes that weren't.

Here's what actually worked: edit ~/.config/gtk-3.0/settings.ini and add, inside the [Settings] section, this line:

gtk-key-theme-name = Emacs

I think that's all that was needed. But in case that doesn't do it, here's something I had already tried, unsuccessfully, and it's possible that you actually need it in addition to the settings.ini change (I don't know how to undo magic Gnome settings so I can't test it):

gsettings set org.gnome.desktop.interface gtk-key-theme "Emacs"

Tags: , , , ,
[ 18:11 May 07, 2016    More linux | permalink to this entry | ]

Thu, 15 Oct 2015

Viewer for email attachments in Office formats

Update, December 2022:
viewmailattachments has been integrated with another mutt helper, viewhtmlmail.py, which can show HTML messages complete with embedded images. It's described in the article View Mail Attachments from Mutt and the script is at viewmailattachments.py. It no longer uses the "please wait" screen described in this article, but the rest of the discussion still applies.

I seem to have fallen into a nest of Mac users whose idea of email is a text part, an HTML part, plus two or three or seven attachments (no exaggeration!) in an unholy combination of .DOC, .DOCX, .PPT and other Microsoft Office formats, plus .PDF.

Converting to text in mutt

As a mutt user who generally reads all email as plaintext, normally my reaction to a mess like that would be "Thanks, but no thanks". But this is an organization that does a lot of good work despite their file format habits, and I want to help.

In mutt, HTML mail attachments are easy. This pair of entries in ~/.mailcap takes care of them:

text/html; firefox 'file://%s'; nametemplate=%s.html
text/html; lynx -dump %s; nametemplate=%s.html; copiousoutput
Then in .muttrc, I have
auto_view text/html
alternative_order text/plain text

If a message has a text/plain part, mutt shows that. If it has text/html but no text/plain, it looks for the "copiousoutput" mailcap entry, runs the HTML part through lynx (or I could use links or w3m) and displays that automatically. If, reading the message in lynx, it looks to me like the message has complex formatting that really needs a browser, I can go to mutt's attachments screen and display the attachment in firefox using the other mailcap entry.

Word attachments are not quite so easy, especially when there are a lot of them. The straightforward way is to save each one to a file, then run LibreOffice on each file, but that's slow and tedious and leaves a lot of temporary files behind. For simple documents, converting to plaintext is usually good enough to get the gist of the attachments. These .mailcap entries can do that:

application/msword; catdoc %s; copiousoutput
application/vnd.openxmlformats-officedocument.wordprocessingml.document; docx2txt %s -; copiousoutput
Alternatives to catdoc include wvText and antiword.

But none of them work so well when you're cross-referencing five different attachments, or for documents where color and formatting make a difference, like mail from someone who doesn't know how to get their mailer to include quoted text, and instead distinguishes their comments from the text they're replying to by making their new comments green (ugh!) For those, you really do need a graphical window.

I decided what I really wanted (aside from people not sending me these crazy emails in the first place!) was to view all the attachments as tabs in a new window. And the obvious way to do that is to convert them to formats Firefox can read.

Converting to HTML

I'd used wvHtml to convert .doc files to HTML, and it does a decent job and is fairly fast, but it can't handle .docx. (People who send Office formats seem to distribute their files fairly evenly between DOC and DOCX. You'd think they'd use the same format for everything they wrote, but apparently not.) It turns out LibreOffice has a command-line conversion program, unoconv, that can handle any format LibreOffice can handle. It's a lot slower than wvHtml but it does a pretty good job, and it can handle .ppt (PowerPoint) files too.

For PDF files, I tried using pdftohtml, but it doesn't always do so well, and it's hard to get it to produce a single HTML file rather than a directory of separate page files. And about three quarters of PDF files sent through email turn out to be PDF in name only: they're actually collections of images of single pages, wrapped together as a PDF file. (Mostly, when I see a PDF like that I just skip it and try to get the information elsewhere. But I wanted my program at least to be able to show what's in the document, and let the user choose whether to skip it.) In the end, I decided to open a firefox tab and let Firefox's built-in PDF reader show the file, though popping up separate mupdf windows is also an option.

I wanted to show the HTML part of the email, too. Sometimes there's formatting there (like the aforementioned people whose idea of quoting messages is to type their replies in a different color), but there can also be embedded images. Extracting the images and showing them in a browser window is a bit tricky, but it's a problem I'd already solved a couple of years ago: Viewing HTML mail messages from Mutt (or other command-line mailers).

Showing it all in a new Firefox window

So that accounted for all the formats I needed to handle. The final trick was the firefox window. Since some of these conversions, especially unoconv, are quite slow, I wanted to pop up a window right away with a "converting, please wait..." message. Initially, I used a javascript: URL, running the command:

firefox -new-window "javascript:document.writeln('<br><h1>Translating documents, please wait ...</h1>');"

I didn't want to rely on Javascript, though. A data: URL, which I hadn't used before, can do the same thing without javascript:

firefox -new-window "data:text/html,<br><br><h1>Translating documents, please wait ...</h1>"

But I wanted the first attachment to replace the contents of that same window as soon as it was ready, and then subsequent attachments open a new tab in that window. But it turned out that firefox is inconsistent about what -new-window and -new-tab do; there's no guarantee that -new-tab will show up in the same window you recently popped up with -new-window, and running just firefox URL might open in either the new window or the old, in a new tab or not, or might not open at all. And things got even more complicated after I decided that I should use -private-window to open these attachments in private browsing mode.

In the end, the only way firefox would behave in a repeatable, predictable way was to use -private-window for everything. The first call pops up the private window, and each new call opens a new tab in the private window. If you want two separate windows for two different mail messages, you're out of luck: you can't have two different private windows. I decided I could live with that; if it eventually starts to bother me, I can always give up on Firefox and write a little python-webkit wrapper to do what I need.

Using a file redirect instead

But that still left me with no way to replace the contents of the "Please wait..." window with useful content. Someone on #firefox came up with a clever idea: write the content to a page with a meta redirect.

So initially, I create a file pleasewait.html that includes the header:

<meta http-equiv="refresh" content="2;URL=pleasewait.html">
(other HTML, charset information, etc. as needed). The meta refresh means Firefox will reload the file every two seconds. When the first converted file is ready, I just change the header to redirect to URL=first_converted_file.html. Meanwhile, I can be opening the other documents in additional tabs.

Finally, I added the command to my .muttrc. When I'm viewing a message either in the index or pager screens, F10 will call the script and decode all the attachments.

macro index <F10> "<pipe-message>~/bin/viewmailattachments\n" "View all attachments in browser"
macro pager <F10> "<pipe-message>~/bin/viewmailattachments\n" "View all attachments in browser"

Whew! It was trickier than I thought it would be. But I find I'm using it quite a bit, and it takes a lot of the pain out of those attachment-full emails.

The script is available at: viewmailattachments.py on GitHub.

Tags: , , , , ,
[ 15:18 Oct 15, 2015    More linux | permalink to this entry | ]

Thu, 09 Jul 2015

Taming annoyances in the new Google Maps

For a year or so, I've been appending "output=classic" to any Google Maps URL. But Google disabled Classic mode last month. (There have been a few other ways to get classic Google maps back, but Google is gradually disabling them one by one.)

I have basically three problems with the new maps:

  1. If you search for something, the screen is taken up by a huge box showing you what you searched for; if you click the "x" to dismiss the huge box so you can see the map underneath, the box disappears but so does the pin showing your search target.
  2. A big swath at the bottom of the screen is taken up by a filmstrip of photos from the location, and it's an extra click to dismiss that.
  3. Moving or zooming the map is very, very slow: it relies on OpenGL support in the browser, which doesn't work well on Linux in general, or on a lot of graphics cards on any platform.

Now that I don't have the "classic" option any more, I've had to find ways around the problems -- either that, or switch to Bing maps. Here's how to make the maps usable in Firefox.

First, for the slowness: the cure is to disable webgl in Firefox. Go to about:config and search for webgl. Then doubleclick on the line for webgl.disabled to make it true.

For the other two, you can add userContent lines to tell Firefox to hide those boxes.

Locate your Firefox profile. Inside it, edit chrome/userContent.css (create that file if it doesn't already exist), and add the following two lines:

div#cards { display: none !important; }
div#viewcard { display: none !important; }

Voilà! The boxes that used to hide the map are now invisible. Of course, that also means you can't use anything inside them; but I never found them useful for anything anyway.

Tags: , , , ,
[ 10:54 Jul 09, 2015    More tech/web | permalink to this entry | ]

Mon, 06 Apr 2015

Quickly seeing bird sightings maps on eBird

The local bird community has gotten me using eBird. It's sort of social networking for birders -- you can report sightings, keep track of what birds you've seen where, and see what other people are seeing in your area.

The only problem is the user interface for that last part. The data is all there, but asking a question like "Where in this county have people seen broad-tailed hummingbirds so far this spring?" is a lengthy process, involving clicking through many screens and typing the county name (not even a zip code -- you have to type the name). If you want some region smaller than the county, good luck.

I found myself wanting that so often that I wrote an entry page for it.

My Bird Maps page is meant to be used as a smart bookmark (also known as bookmarklets or keyword bookmarks), so you can type birdmap hummingbird or birdmap golden eagle in your location bar as a quick way of searching for a species. It reads the bird you've typed in, and looks through a list of species, and if there's only one bird that matches, it takes you straight to the eBird map to show you where people have reported the bird so far this year.

If there's more than one match -- for instance, for birdmap hummingbird or birdmap sparrow -- it will show you a list of possible matches, and you can click on one to go to the map.

Like every Javascript project, it was both fun and annoying to write. Though the hardest part wasn't programming; it was getting a list of the nonstandard 4-letter bird codes eBird uses. I had to scrape one of their HTML pages for that. But it was worth it: I'm finding the page quite useful.

How to make a smart bookmark

I think all the major browsers offer smart bookmarks now, but I can only give details for Firefox. But here's a page about using them in Chrome.

Firefox has made it increasingly difficult with every release to make smart bookmarks. There are a few extensions, such as "Add Bookmark Here", which make it a little easier. But without any extensions installed, here's how you do it in Firefox 36:

[Firefox bookmarks dialog] First, go to the birdmap page (or whatever page you want to smart-bookmark) and click on the * button that makes a bookmark. Then click on the = next to the *, and in the menu, choose Show all bookmarks. In the dialog that comes up, find the bookmark you just made (maybe in Unsorted bookmarks?) and click on it.

Click the More button at the bottom of the dialog.
(Click on the image at right for a full-sized screenshot.)
[Firefox bookmarks dialog showing keyword]

Now you should see a Keyword entry under the Tags entry in the lower right of that dialog.

Change the Location to http://shallowsky.com/birdmap.html?bird=%s.

Then give it a Keyword of birdmap (or anything else you want to call it).

Close the dialog.

Now, you should be able to go to your location bar and type:
birdmap common raven or birdmap sparrow and it will take you to my birdmap page. If the bird name specifies just one bird, like common raven, you'll go straight from there to the eBird map. If there are lots of possible matches, as with sparrow, you'll stay on the birdmap page so you can choose which sparrow you want.

How to change the default location

If you're not in Los Alamos, you probably want a way to set your own coordinates. Fortunately, you can; but first you have to get those coordinates.

Here's the fastest way I've found to get coordinates for a region on eBird:

Then look at the URL: a part of it should look something like this: env.minX=-122.202087&env.minY=36.89291&env.maxX=-121.208778&env.maxY=37.484802 If the map isn't right where you want it, try editing the URL, hitting Enter for each change, and watch the map reload until it points where you want it to. Then copy the four parameters and add them to your smart bookmark, like this: http://shallowsky.com/birdmap.html?bird=%s&minX=-122.202087&minY=36.89291&maxX=-121.208778&maxY=37.484802

Note that all of the the "env." have been removed.

The only catch is that I got my list of 4-letter eBird codes from an eBird page for New Mexico. I haven't found any way of getting the list for the entire US. So if you want a bird that doesn't occur in New Mexico, my page might not find it. If you like birdmap but want to use it in a different state, contact me and tell me which state you need, and I'll add those birds.

Tags: , , , , , , ,
[ 14:30 Apr 06, 2015    More nature/birds | permalink to this entry | ]

Fri, 27 Mar 2015

Hide Google's begging (or any other web content) via a Firefox userContent trick

Lately, Google is wasting space at the top of every search with a begging plea to be my default search engine.

[Google begging: Switch your default search engine to Google] Google already is my default search engine -- that's how I got to that page. But if you don't have persistent Google cookies set, you have to see this begging every time you do a search. (Why they think pestering users is the way to get people to switch to them is beyond me.)

Fortunately, in Firefox you can hide the begging with a userContent trick. Find the chrome directory inside your Firefox profile, and edit userContent.css in that directory. (Create a new file with that name if you don't already have one.) Then add this:

#taw { display: none !important; }

Restart Firefox, do a Google search and the begs should be gone.

In case you have any similar pages where there's pointless content getting in the way and you want to hide it: what I did was to right-click inside the begging box and choose Inspect element. That brings up Firefox's DOM inspector. Mouse over various lines in the inspector and watch what gets highlighted in the browser window. Find the element that highlights everything you want to remove -- in this case, it's a div with id="taw". Then you can write CSS to address that: hide it, change its style or whatever you're trying to do.

You can even use Inspect element to remove elements immediately. That won't help you prevent them from showing up later, but it can be wonderful if you need to use a page that has an annoying blinking ad on it, or a mis-designed page that has images covering the content you're trying to read.

Tags: , ,
[ 08:17 Mar 27, 2015    More tech/web | permalink to this entry | ]

Sat, 14 Mar 2015

Making a customized Firefox search plug-in

It's getting so that I dread Firefox's roughly weekly "There's a new version -- do you want to upgrade?" With every new upgrade, another new crucial feature I use every day disappears and I have to spend hours looking for a workaround.

Last week, upgrading to Firefox 36.0.1, it was keyword search: the feature where, if I type something in the location bar that isn't a URL, Firefox would instead search using the search URL specified in the "keyword.URL" preference.

In my case, I use Google but I try to turn off the autocomplete feature, which I find it distracting and unhelpful when typing new search terms. (I say "try to" because complete=0 only works sporadically.) I also add the prefix allintext: to tell Google that I only want to see pages that contain my search term. (Why that isn't the default is anybody's guess.) So I set keyword.URL to: http://www.google.com/search?complete=0&q=allintext%3A+ (%3A is URL code for the colon character).

But after "up"grading to 36.0.1, search terms I typed in the location bar took me to Yahoo search. I guess Yahoo is paying Mozilla more than Google is now.

Now, Firefox has a Search tab under Edit->Preferences -- but that just gives you a list of standard search engines' default searches. It would let me use Google, but not with my preferred options.

If you follow the long discussions in bugzilla, there are a lot of people patting each other on the back about how much easier the preferences window is, with no discussion of how to specify custom searches except vague references to "search plugins". So how do these search plugins work, and how do you make one?

Fortunately a friend had a plugin installed, acquired from who knows where. It turns out that what you need is an XML file inside a directory called searchplugins in your profile directory. (If you're not sure where your profile lives, see Profiles - Where Firefox stores your bookmarks, passwords and other user data, or do a systemwide search for "prefs.js" or "search.json" or "cookies.sqlite" and it should lead you to your profile.)

Once you have one plugin installed, it's easy to edit it and modify it to do anything you want. The XML file looks roughly like this:

<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/" xmlns:os="http://a9.com/-/spec/opensearch/1.1/">
<os:ShortName>MySearchPlugin</os:ShortName>
<os:Description>The search engine I prefer to use</os:Description>
<os:InputEncoding>UTF-8</os:InputEncoding>
<os:Image width="16" height="16">data:image/x-icon;base64,ICON GOES HERE</os:Image>
<SearchForm>http://www.google.com/</SearchForm>
<os:Url type="text/html" method="GET" template="https://www.google.com/search">
  <os:Param name="complete" value="0"/>
  <os:Param name="q" value="allintext: {searchTerms}"/>
  <!--os:Param name="hl" value="en"/-->
</os:Url>
</SearchPlugin>

There are four things you'll want to modify. First, and most important, os:Url and os:Param control the base URL of the search engine and the list of parameters it takes. {searchTerms} in one of those Param arguments will be replaced by whatever terms you're searching for. So <os:Param name="q" value="allintext: {searchTerms}"/> gives me that allintext: parameter I wanted.

(The other parameter I'm specifying, <os:Param name="complete" value="0"/>, used to make Google stop the irritating autocomplete every time you try to modify your search terms. Unfortunately, this has somehow stopped working at exactly the same time that I upgraded Firefox. I don't see how Firefox could be causing it, but the timing is suspicious. I haven't been able to figure out another way of getting rid of the autocomplete.)

Next, you'll want to give your plugin a ShortName and Description so you'll be able to recognize it and choose it in the preferences window.

Finally, you may want to modify the icon: I'll tell you how to do that in a moment.

Using your new search plugin

[Firefox search prefs]

You've made all your modifications and saved the file to something inside the searchplugins folder in your Firefox profile. How do you make it your default?

I restarted firefox to make sure it saw the new plugin, though that may not have been necessary. Then Edit->Preferences and click on the Search icon at the top. The menu near the top under Default search engine is what you want: your new plugin should show up there.

Modifying the icon

Finally, what about that icon?

In the plugin XML file I was copying, the icon line looked like:

<os:Image width="16"
height="16">data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAA
... many more lines like this then ... ==</os:Image>
So how do I take that and make an image I can customize in GIMP?

I tried copying everything after "base64," and pasting it into a file, then opening it in GIMP. No luck. I tried base64 decoding it (you do this with base64 -d filename >outfilename) and reading it in with GIMP. Still no luck: "Unknown file type".

The method I found is roundabout, but works:

  1. Copy everything inside the tag: data:image/x-icon;base64,AA ... ==
  2. Paste that into Firefox's location bar and hit return. You'll see the icon from the search plugin you're modifying.
  3. Right-click on the image and choose Save image as...
  4. Save it to a file with the extension .ico -- GIMP won't open it without that extension.
  5. Open it in GIMP -- a 16x16 image -- and edit to your heart's content.
  6. File->Export as...
  7. Use the type "Microsoft Windows icon (*.ico)"
  8. Base64 encode the file you just saved, like this: base64 yourfile.ico >newfile
  9. Copy the contents of newfile and paste that into your os:Image line, replacing everything after data:image/x-icon;base64, and before </os:Image>

Whew! Lots of steps, but none of them are difficult. (Though if you're not on Linux and don't have the base64 command, you'll have to find some other way of encoding and decoding base64.)

But if you don't want to go through all the steps, you can download mine, with its lame yellow smiley icon, as a starting point: Google-clean plug-in.

Happy searching! See you when Firefox 36.0.2 comes out and they break some other important feature.

Tags: ,
[ 12:35 Mar 14, 2015    More tech/web | permalink to this entry | ]

Mon, 09 Feb 2015

Making flashblock work again; and why HTML5 video doesn't work in Firefox

Back in December, I wrote about Problems with Firefox 35's new deprecation of flash, and a partial solution for Debian. That worked to install a newer version of the flash plug-in on my Debian Linux machine; but it didn't fix the problem that the flashblock program no longer works properly on Firefox 35, so that clicking on the flashblock button does nothing at all.

A friend suggested that I try Firefox's built-in flash blocking. Go to Tools->Add-ons and click on Plug-ins if that isn't the default tab. Under Shockwave flash, choose Ask to Activate.

Unfortunately, the result of that is a link to click, which pops up a dialog that requires clicking a button to dismiss it -- a pointless and annoying extra step. And there's no way to enable flash for just the current page; once you've enabled it for a domain (like youtube), any flash from that domain will auto-play for the remainder of the Firefox session. Not what I wanted.

So I looked into whether there was a way to re-enable flashblock. It turns out I'm not the only one to have noticed the problem with it: the FlashBlock reviews page is full of recent entries from people saying it no longer works. Alas, flashblock seems to be orphaned; there's no comment about any of this on the main flashblock page, and the links on that page for discussions or bug reports go to a nonexistent mailing list.

But fortunately there's a comment partway down the reviews page from user "c627627" giving a fix.

Edit your chrome/userContent.css in your Firefox profile. If you're not sure where your profile lives, Mozilla has a poorly written page on it here, Profiles - Where Firefox stores your bookmarks, passwords and other user data, or do a systemwide search for "prefs.js" or "search.json" or "cookies.sqlite" and it will probably lead you to your profile.

Inside yourprofile/chrome/userContent.css (create it if it doesn't already exist), add these lines:

@namespace url(http://www.w3.org/1999/xhtml);
@-moz-document domain("youtube.com"){
#theater-background { display:none !important;}}

Now restart Firefox, and flashblock should work again, at least on YouTube. Hurray!

Wait, flash? What about HTML5 on YouTube?

Yes, I read that too. All the tech press sites were reporting week before last that YouTube was now streaming HTML5 by default.

Alas, not with Firefox. It works with most other browsers, but Firefox's HTML5 video support is too broken. And I guess it's a measure of Firefox's increasing irrelevance that almost none of the reportage two weeks ago even bothered to try it on Firefox before reporting that it worked everywhere.

It turns out that using HTML5 video on YouTube depends on something called Media Source Extensions (MSE). You can check your MSE support by going to YouTube's HTML5 info page. In Firefox 35, it's off by default.

You can enable MSE in Firefox by flipping the media.mediasource preference, but that's not enough; YouTube also wants "MSE & H2.64". Apparently if you care enough, you can set a new preference to enable MSE & H2.64 support on YouTube even though it's not supported by Firefox and is considered too buggy to enable.

If you search the web, you'll find lots of people talking about how HTML5 with MSE is enabled by default for Firefox 32 on youtube. But here we are at Firefox 35 and it requires jumping through hoops. What gives?

Well, it looks like they enabled it briefly, discovered it was too buggy and turned it back off again. I found bug 1129039: Disable MSE for Firefox 36, which seems an odd title considering that it's off in Firefox 35, but there you go.

Here is the dependency tree for the MSE tracking bug, 778617. Its dependency graph is even scarier. After taking a look at that, I switched my media.mediasource preference back off again. With a dependency tree like that, and nothing anywhere summarizing the current state of affairs ... I think I can live with flash. Especially now that I know how to get flashblock working.

Tags: ,
[ 17:08 Feb 09, 2015    More tech/web | permalink to this entry | ]

Thu, 18 Dec 2014

Firefox deprecates flash. How to get it back (on Debian).

Recently Firefox started refusing to run flash, including youtube videos (about the only flash I run). A bar would appear at the top of the page saying "This plug-in is vulnerable and should be upgraded". Apparently Adobe had another security bug. There's an "Update now" button in the Firefox bar, but it's a chimera: Firefox has never known how to install plug-ins for Linux (there are longstanding bugs filed on why it claims to be able to but can't), and it certainly doesn't know how to update a Debian package.

I use a Firefox downloaded from Mozilla.org, but flash from Debian's flashplugin-nonfree package. So I figured updating Debian -- apt-get update; apt-get dist-upgrade -- would fix it. Nope. I still got the same message.

A little googling found several pages recommending update-flashplugin-nonfree --install; I tried that but it didn't help either. It seemed to download a tarball, but as far as I could tell it never unpacked or installed the tarball it downloaded.

What finally did the trick was

apt-get install --reinstall flashplugin-nonfree
That downloaded a new tarball, AND unpacked and installed it. After restarting Firefox, I was able to view the video I'd been trying to watch.

Tags: , ,
[ 15:21 Dec 18, 2014    More linux | permalink to this entry | ]

Sat, 20 Jul 2013

Make Firefox warn you of specific types of links before you click

Sometimes when I middleclick on a Firefox link to open it in a new tab, I get an empty new tab. I hate that.

It happens most often on Javascript links. For instance, suppose a website offers a Help link next to the link I'm trying to use. I don't know what type of link it is; if it's a normal link, to an HTML page, then it may open in my current tab, overwriting the form I just spent five minutes filling out. So I want to middleclick it, so it will open in a new tab. On the other hand, if it's a Javascript link that pops up a new help window, middleclicking won't work at all; all it does is open an empty new tab, which I'll have to close.

A similar effect happens on PDF links; in that case, middleclicking gives me the "What do you want to do with this?" dialog but I also get a new tab that I have to close. (Though I'm not sure what happens with Firefox's new built-in PDF reader.)

Anyway, since there seems to be no way of making middleclick just do the sensible thing and open these links in a new tab like I asked, it, I can do something almost as good: a user stylesheet that warns me when I'm about to click on one of these special links. This rule changes the cursor to a crosshair, and turns the link bold with colors of red on yellow. Hard to miss!

I put this into userContent.css, inside the chrome directory inside my profile:

/*
 * Make it really obvious when links are javascript,
 * since middleclicking javascript links doesn't do anything
 * except open an empty new tab that then has to be closed.
 */
a:hover[href^="javascript"] {
  cursor: crosshair; font-weight: bold;
  text-decoration: blink;
  color: red; background-color: yellow
  !important
}

/*
 * And the same for PDFs, for the same reason.
 * Sadly, we can't catch all PDFs, just the ones where the actual
 * filename ends in .pdf.
 * Apparently there's no way to make a selector case insensitive,
 * so we have separate cases for .pdf and .PDFb
 */
a:hover[href$=".pdf"], a:hover[href$=".PDF"] {
  cursor: crosshair;
  color: red; background-color: yellow
  !important
}

In selectors, ^="javascript" means "starts with javascript", for links like javascript:do_something(). $=".pdf" means "ends with .pdf". If you want to match a string anywhere inside the href, *= means "contains".

What about that crosshair cursor? Here are some of the cursors you can use: Mozilla's cursor documentation page. Don't trust the images on that page -- hover over each cursor to see what your actual browser shows.

You can also warn about links that would open a new window or tab. If you prefer to keep control of that, rather than letting each web page designer decide for you where each link should open, you can control it with the browser.link.open newwindow preference. But whatever you do with that preference you can add a rule for a:hover[target="_blank"] to help you notice links that are likely to open in a new tab.

You can even make these special links blink, with text-decoration: blink. Assuming you're not a curmudgeon like I am who disables blinking entirely by setting the "browser.blink_allowed" preference to false.

Tags: , , , ,
[ 20:26 Jul 20, 2013    More tech/web | permalink to this entry | ]

Sun, 09 Jun 2013

Debugging a Firefox freeze on Ringtail and Sid

I recently went on an upgrading spree on my main computer. In the hope of getting more up-to-date libraries, I updated my Ubuntu to 13.04 "Raring Ringtail", and Debian to unstable "Sid". Most things went fine -- except for Firefox.

Under both Ringtail and Sid, Firefox became extremely unstable. I couldn't use it for more than about fifteen minutes before it would freeze while trying to access some web resource. The only cure when that happened was to kill it and start another Firefox. This was happening with the exact same Firefox -- a 21.0 build from mozilla.org -- that I was using without any problems on older versions of Debian and Ubuntu; and with the exact same profile. So it was clearly something that had changed about Debian and Ubuntu.

The first thing I do when I hit a Firefox bug is test with a fresh profile. I have all sorts of Firefox customizations, extensions and other hacks. In fact, the customizations are what keep me tied to Firefox rather than jumping to some other browser. But they do, too often, cause problems. I have a generic profile I keep around for testing, so I fired it up and used it for browsing for a day. Firefox still froze, but not as often.

Disabling Extensions

Was it one of my extensions? I went to the Tools->Add-ons to try disabling them all ... and Firefox froze. Bingo! That was actually good news. Problems like "Firefox freezes a lot" are hard to debug. "Firefox freezes every time I open Tools->Add-ons" are a whole lot easier. Now I needed to find some other way of disabling extensions to see if that helped.

I went to my Firefox profile directory and moved everything in the extensions directory into a new directory I made called extensions.sav. Then I started moving them back one by one, each time starting Firefox and calling up Tools->Add-ons. It turned out two extensions were causing the freeze: Open in Browser and Custom Tab Width. So I left those off for the time being.

Disabling Themes

Along the way, I discovered that clicking on Appearance in Tools->Add-ons would also cause a freeze, so my visual theme was also a problem. This wasn't something I cared about: some time back when Mozilla started trumpeting their themeability, I clicked around and picked up some theme involving stars and planets. I could live without that.

But how do you disable a theme? Especially if you can't go to Tools->Add-ons->Appearance?

Turns out everything written on the web on this is wrong. First, everything on themes on mozilla.org assumes you can get to that Appearance tab, and doesn't even consider the possibility that you might have to look in your profile and remove a file. Search further and you might find references to files named lightweighttheme-header and lightweighttheme-footer, neither of which existed in my profile.

But I did have a directory called lwtheme. So I removed that, plus four preferences in prefs.js that included the term "lightweightThemes". After a restart, my theme was gone, I was able to view that Appearance tab, and I was able to browse the web for nearly 4 hours before firefox hung again. Darn! That wasn't all of it.

Debugging the environment

But soon after that I had a breakthrough. I discovered a page on my bank's website that froze Firefox every time. But that was annoying for testing, since it required logging in then clicking through several other pages, and you never know what a bank website might decide to do if you start logging in over and over. I didn't want to get locked out.

But then I was checking an episode in one of the podcasts I listen to, which involved going to the link http://downloads.bbc.co.uk/podcasts/radio4/moreorless/rss.xml -- and Firefox froze, on a simple RSS link. I restarted and tried again -- another freeze. I'd finally found the Rosetta stone, something that hung Firefox every time. Now I could do some serious testing!

I'd had friends try this using the same version of Firefox and Ubuntu, without seeing a freeze. Was it something about my user environment? I created a new user, switched to another virtual console (Ctrl-Alt-F2) and logged in as my new user, then ran X. This was a handy way to test: I could get to my normal user's X session in Ctrl-Alt-F7, while the new user's X session was on Ctrl-Alt-F8. Since I don't have Gnome or KDE installed on this machine, the new user came up with a default Openbox session. It came up at the wrong resolution -- the X11 in the newest Linux distros apparently doesn't read the HDMI monitor properly -- but I wasn't worried about that.

And when I ran Firefox as the new user (letting it create a new profile) and middlemouse-pasted the BBC RSS URL, it loaded it, without freezing.

Now we're getting somewhere. Now I knew it was something about my user environment.

I tried copying all of ~/.config from my user to the new user. No hang. I tried various other configuration files. Still no hang.

The X initialization

I'll skip some steps here, and just mention that in trying to fix the resolution problem, so I didn't have to do all my debugging at 1024x768, I discovered that if I used my .xinitrc file to start X, I'd get a freezy Firefox. If I didn't use my .xinitrc, and defaulted to the system one, Firefox was fine. Even if I removed everything else from my .xinitrc, and simply ran openbox from it, that was enough to make Firefox hang.

Okay, what was the system doing? I poked around /etc/X11: it was running /etc/X11/Xsession. I copied that file to my .xinitrc and started X. No hang.

Xsession does a bunch of things, but one of the main things it does is run every script in the /etc/X11/Xsession.d directory. So I made a copy of that directory inside my home directory, and modified .xinitrc to execute those files instead. Then I started moving them aside to see which ones made a difference.

And I found it. /etc/X11/Xsession.d/75dbus_dbus-launch was the file that mattered.

75dbus_dbus-launch takes the name of the program that's going to be executed -- in this case that was x-session-manager, which links to /etc/alternatives/x-session-manager, which links to /usr/bin/openbox-session -- and instead runs /usr/bin/dbus-launch --exit-with-session x-session-manager.

Now that I knew that, I moved everything aside and made a little .xinitrc that ran /usr/bin/dbus-launch --exit-with-session openbox-session. And Firefox didn't crash.

Dbus

So it all comes down to dbus. I was already running dbus: ps shows /usr/bin/dbus-daemon --system running -- and that worked fine for everything dbussy I normally do, like run "gimp image.jpg" and have it open in my already running GIMP.

But on Ringtail and Sid, that isn't enough for Firefox. For some reason, on these newer systems, Firefox requires a second dbus daemon -- it shows up in ps as /usr/bin/dbus-daemon --fork --print-pid 5 --print-address 7 --session -- for the X session. If it doesn't have that, it's fine for a while, and then, hours later, it will mysteriously freeze while waiting for a network resource.

Why? I have no idea. No one I've asked seems to know anything about how dbus works, the difference between system and session dbus daemons, or why any of it it would have this effect on Firefox.

I filed a Firefox bug, Bug 881122, though I don't have much hope of anyone being interested in a bug that only affects Linux users using nonstandard X sessions. But maybe I'm not the only one. If your Firefox is hanging and you found your way here, I hope I've given you some ideas. And if anyone has a clue as to what's really happening and why dbus would have that effect, I'd love to hear from you.

Tags: , , , , , ,
[ 20:08 Jun 09, 2013    More linux | permalink to this entry | ]

Tue, 26 Mar 2013

Pasting the Primary X Selection into Firefox

Sometimes I need to take a URL from some text app -- like a shell window, or an IRC comment -- and open it in Firefox.

If it's a standard http://, that's trivial: I highlight the URL with my house (often a doubleclick will do it), go to my Firefox window and middleclick somewhere in the content area, anywhere that's not a link, and Firefox goes to the URL.

That works because selecting anything, in X, copies the selection to the Primary selection buffer. The Primary selection is different from the Clipboard selection that's used with Windows and Mac style Ctrl-X/Ctrl-C/Ctrl-V copy and paste; it's faster and doesn't require switching between keyboard and mouse. Since your hand is already on the mouse (from selecting the text), you don't have to move to the keyboard to type Ctrl-C, then back to the mouse to go to the Firefox window, then back to the keyboard to type Ctrl-V.

But it fails in some cases. Like when someone says in IRC, "There's a great example of that at coolhacks.org/greatexample". You can highlight coolhacks.org/greatexample and middleclick in Firefox all you want, but Firefox doesn't recognize it as a URL and won't go there. Or if I want to highlight a couple of search terms and pass them into a Google search.

(Rant: middlemouse used to work for these cases, but it was disabled -- without even an option for getting it back -- due to a lot of whining in bugzilla by people coming from Windows backgrounds who didn't like middleclick paste because they found it unexpected, yet who weren't willing to turn it off with the middlemouse.contentLoadURL pref).

So in those cases, what I've been doing is:

It works, but it's a lot more steps, and entails several switches between keyboard and mouse. Frustrating!

It would be a little less frustrating if I had a key binding in Firefox that said "Paste the current X primary selection." A web search shows that quite a few other people have been bothered by this problem -- for instance, here and here -- but without any solutions. Apparently in a lot of apps, Ctrl-Insert inserts the Primary X selection -- but in Firefox and a few others, it inserts the Clipboard instead, just like Ctrl-C.

I could write my own fix, by unzipping Firefox's omni.ja file and editing various .xul and .js files inside it. But if I were doing that, I could just as easily revert Firefox's original behavior of going to the link. Neither of these is difficult; the problem is that every time I Firefox updates (which is about twice a week these days), things break until I manually go in and unzip the jar and make my changes again. I used to do that, but I got tired of needing to do it so often. And I tried to do it via a Firefox extension, until Mozilla changed the Firefox extension API so that extensions couldn't modify key bindings any more.

Since Firefox changes so often, it's nicer to have a solution that's entirely outside of Firefox. And a comment in one of those discussion threads gave me an idea: make a key binding in my window manager that uses xset to copy the primary selection to the clipboard, then use my crikey program to insert a fake Ctrl-V that Firefox will see.

Here's a command to do that:

xsel -o -p | xsel -i -b; crikey -s 1 "^V"

xsel -o prints a current X selection, and -p specifies the Primary. xsel -i sets an X selection to whatever it gets on standard input (which in this case will be whatever was in the Primary selection), and -b tells it to set the Clipboard selection.

Then crikey -s 1 "^V" waits one second (I'll probably reduce this after more testing) and then generates an X event for a Ctrl-V.

I bound that command to Ctrl-Insert in my window manager, Openbox, like this:

<keybind key="C-Insert">
  <action name="Execute">
    <execute>/bin/sh -c 'xsel -o -p | xsel -i -b; crikey -s 1 "^V"'</execute>
  </action>
</keybind>
Openbox didn't seem happy with the pipe, so I wrapped the whole thing in a sh -c.

Now, whenever I type Ctrl-Insert, whatever program I'm in will do a Ctrl-V but insert the Primary selection rather than the Clipboard. It should work in other recalcitrant programs, like LibreOffice, as well. In Firefox, now, I just have to type Ctrl-L Ctrl-Insert Return.

Of course, it's easy enough to make a binding specific to Firefox that does the Ctrl-L and the Return automatically. I've bound that to Alt-Insert, and its execute line looks like this:

    <execute>/bin/sh -c 'xsel -o -p | xsel -i -b; crikey -s 1 "^L^V\\n"'</execute>

Fun with Linux! Now the only hard part will be remembering to use the bindings instead of doing things the hard way.

Tags: , , , ,
[ 20:35 Mar 26, 2013    More linux/cmdline | permalink to this entry | ]

Tue, 24 Apr 2012

Firefox stopped accepting remote commands

When I upgraded to Firefox 11 a month or so ago, I got a surprise: I couldn't invoke firefox from other applications any more. Clicking on a link in an app such as xchat just gave me the Firefox Profile Manager dialog, instead of opening the link in the browser I was already running.

I couldn't find anything written about it, so I've been putting up with it, copying each link then switching to the desktop where Firefox is running and middleclick-pasting it into the browser. But this morning, I did a new round of searching, and finally found the answer, in bug 716110. and its duplicate, 716361.

Quoting from bug 716110::

[The developers] changed the -no-remote flag's behavior in a
surprising, backward incompatible way. Before, it just meant "start a
new instance." Now, it also means "don't listen for remote commands."
Apparently the change went in for Firefox 9, because of bug 650078.

Indeed, that was the problem. I have multiple Firefox profiles, so I use -no-remote -P profilename when I start Firefox, so each profile doesn't conflict with one that might already be running.

But with Firefox 9 or later, you can't do that. Instead, run your first, primary profile without -no-remote; then if you start up other profiles later, run them with -no-remote so they don't conflict with the first one. That works okay for my typical usage, fortunately: I have a main Firefox window I run all day, and only start up other profiles for short periods.

But since not everyone uses this model, fortunately, some upcoming Firefox version will fix the problem by adding a new runtime flag, -new-instance, to do what -no-remote used to do: start up a window for a new profile, rather than talking to the running Firefox. Here's the new --help text:
-no-remote Do not accept or send remote commands; implies -new-instance.\n
-new-instance Open new instance, not a new window in running instance.\n
The web Command Line Options page doesn't seem to have been updated yet, but perhaps it will when the Firefox with the fix is released.

Of course, it would have been much simpler if Firefox just honored the -P flag and used whatever profile it was given, as suggested by a commenter in bug 650078. But bsmedberg replies that the complexity of the code makes that difficult.

The new arguments look more sensible than the old -no-remote, though it's frustrating that it was so hard to find information about changes like this. All three bugs are filled with comments from people who, like me, lost a lot of time trying to figure out what broke and how to launch URLs remotely after the change. Thanks to Ryan for clarifying the issue and filing the bug to fix the problem, and to Jed, who added the new flag with his first Mozilla patch. Hooray for open source!

Tags: ,
[ 11:26 Apr 24, 2012    More tech/web | permalink to this entry | ]

Tue, 03 Jan 2012

Open the X selection in a browser window, from any desktop

Like most Linux users, I use virtual desktops. Normally my browser window is on a desktop of its own.

Naturally, it often happens that I encounter a link I'd like to visit while I'm on a desktop where the browser isn't visible. From some apps, I can click on the link and have it show up. But sometimes, the link is just text, and I have to select it, change to the browser desktop, paste the link into firefox, then change desktops again to do something else while the link loads.

So I set up a way to load whatever's in the X selection in firefox no matter what desktop I'm on.

In most browsers, including firefox, you can tell your existing browser window to open a new link from the command line: firefox http://example.com/ opens that link in your existing browser window if you already have one up, rather than starting another browser. So the trick is to get the text you've selected.

At first, I used a program called xclip. You can run this command: firefox `xclip -o` to open the selection. That worked okay at first -- until I hit my first URL in weechat that was so long that it was wrapped to the next line. It turns out xclip does odd things with multi-line output; depending on whether it thinks the output is a terminal or not, it may replace the newline with a space, or delete whatever follows the newline. In any case, I couldn't find a way to make it work reliably when pasted into firefox.

After futzing with xclip for a little too long, trying to reverse-engineer its undocumented newline behavior, I decided it would be easier just to write my own X clipboard app in Python. I already knew how to do that, and it's super easy once you know the trick:

mport gtk
primary = gtk.clipboard_get(gtk.gdk.SELECTION_PRIMARY)
if primary.wait_is_text_available() :
    print primary.wait_for_text()

That just prints it directly, including any newlines or spaces. But as long as I was writing my own app, why not handle that too?

It's not entirely necessary on Firefox: on Linux, Firefox has some special code to deal with pasting multi-line URLs, so you can copy a URL that spans multiple lines, middleclick in the content area and things will work. On other platforms, that's disabled, and some Linux distros disable it as well; you can enable it by going to about:config and searching for single, then setting the preference editor.singlelinepaste.pasteNewlines to 2.

However, it was easy enough to make my Python clipboard app do the right thing so it would work in any browser. I used Python's re (regular expressions) module:

#!/usr/bin/env python

import gtk
import re

primary = gtk.clipboard_get(gtk.gdk.SELECTION_PRIMARY)

if not primary.wait_is_text_available() :
    sys.exit(0)
s = primary.wait_for_text()

# eliminate newlines, and any spaces immediately following a newline:
print re.sub(r'[\r\n]+ *', '', s)

That seemed to work fine, even on long URLs pasted from weechat with newlines and spaces, like that looked like

http://example.com/long-
    url.html

All that was left was binding it so I could access it from anywhere. Of course, that varies depending on your desktop/window manager. In Openbox, I added two items to my desktop menu in menu.xml:

  <item label="open selection in Firefox">
    <action name="Execute"><execute>sh -c 'firefox `xclip -o`'</execute></action>
  </item>
  <item label="open selection in new tab">
    <action name="Execute"><execute>sh -c 'firefox -new-tab `xclip -o`'</execute></action>
  </item>

I also added some code in rc.xml inside <context name="Desktop">, so I can middle-click or control-middle-click on the desktop to open a link in the browser:

      <mousebind button="Middle" action="Press">
        <action name="Execute">
          <execute>sh -c 'firefox `pyclip`'</execute>
        </action>
      </mousebind>
      <mousebind button="C-Middle" action="Press">
        <action name="Execute">
          <execute>sh -c -new-tab 'firefox `pyclip`'</execute>
        </action>
      </mousebind>

I set this up maybe two hours ago and I've probably used it ten or fifteen times already. This is something I should have done long ago!

Tags: , , ,
[ 22:37 Jan 03, 2012    More linux | permalink to this entry | ]

Sun, 09 Oct 2011

Disable Google's Instant mode, and Instant Previews

A group of us were commiserating about that widely-reviled feature, Google Instant. That's the thing that refreshes your Google search page while you're still typing, so you always feel like you have to type reallyreallyfasttofinishyourquerybeforeitupdates. Google lets you turn off Instant -- but only if you let them set and remember your cookies, meaning they can also track you across the web. Isn't there a more privacy-preserving way to get a simple Google page that doesn't constantly change as you change your search query?

Disable Instant

It turns out there is. Just add complete=0 to your search queries.

How do you do that? Well, in Firefox, I search in the normal URL bar. No need for a separate search field taking up space in the browser window; any time you type multiple terms (or a space followed by a single term) in Firefox's URLbar, it appends your terms to whatever you have set as the keyword.URL preference.

So go to about:config and search for keyword, then double-click on keyword.URL and make sure it's something like "http://www.google.com/search?complete=0&q=". Or if you want to make sure it won't be overridden, find your Firefox profile, edit user.js (create it if you don't have one already), and add a line like:

user_pref("keyword.URL", "http://www.google.com/search?complete=0&q=");

Show only pages matching the search terms

I use a slightly longer query, myself:

user_pref("keyword.URL", "http://www.google.com/search?complete=0&q=allintext%3A+"

Adding allintext: as the first word in any search query tells Google not to show pages that don't have the search terms as part of the page. You might think this would be the default ... but The Google Works in Mysterious Ways and it is Not Ours to Question.

Disable Instant Previews

Finally, just recently Google has changed their search page again to add a bunch of crap down the right side of the page which, if you accidentally mouse on it, loads a miniature preview of the page over on your sidebar. You have to be very careful with your mouse not to have stuff you might not be interested in popping up all the time.

A moment's work with Firebug gave me the CSS classes I needed to hide. Edit chrome/userContent.css in your Firefox profile (create it if you don't already have one) and add this rule:

/* Turn off the "instant preview" annoying buttons in google search results */
.vspib, .vspii { display: none !important; }

Really, it's a darn shame that Google has gone from its origins as a clean, simple website to something like Facebook with things popping up all over that users have to bend over backward to disable. But that seems to be the way of the web. Good thing browsers are configurable!

Tags: , , , , ,
[ 22:31 Oct 09, 2011    More tech/web | permalink to this entry | ]

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 | ]

Sun, 20 Jun 2010

Scaling HTML slides for different projectors with full-page zoom

Regular readers probably know that I use HTML for the slides in my talks, and I present them either with Firefox in fullscreen mode, or with my own Python preso tool based on webkit.

Most of the time it works great. But there's one situation that's always been hard to deal with: low-resolution projectors. Most modern projectors are 1024x768, and have been for quite a few years, so that's how I set up my slides. And then I get asked to give a talk at a school, or local astronomy club, or some other group that has a 10-year-old projector that can only handle 800x600. Of course, you never find out about this ahead of time, only when you plug in right before the talk. Disaster!

Wait -- before you object that HTML pages shouldn't use pixel values and should work regardless of the user's browser window size: I completely agree with you. I don't specify absolute font sizes or absolute positioning on web pages -- no one should. But presentation slides are different: they're designed for a controlled environment where everyone sees the same thing using the same software and hardware.

I can maintain a separate stylesheet -- that works for making the font size smaller but it doesn't address the problem of pictures too large to fit (and we all like to use lots of pictures in presentations, right?) I can maintain two separate copies of the slides for the two sizes, but that's a lot of extra work and they're bound to get out of sync.

Here's a solution I should have thought of years ago: full-page zoom. Most major browsers have offered that capability for years, so the only trick is figuring out how to specify it in the slides.

IE and the Webkit browsers (Safari, Konqueror, etc.) offer a wonderful CSS property called zoom. It works like this:

body {
  zoom: 78.125%;
}

78.125% is the ratio between an 800-pixel projector and a 1024-pixel one. Just add this line, and your whole page will be scaled down to the right size. Lovely!

Lovely, except it doesn't work on Firefox (bug 390936). Fortunately, Firefox has another solution: the more general and not yet standardized CSS transform, which Mozilla has implemented as the Mozilla-specific property -moz-transform. So add these lines:

body {
  position: absolute; left: 0px; top: 0px;
  -moz-transform: scale(.78125, .78125);
}

The position: absolute is needed because when Firefox scales with -moz-transform, it also centers whatever it scaled, so the slide ends up in the top center of the screen. On my laptop, at least, it's the upper left part of the screen that gets sent to the projector, so slides must start in the upper left corner.

The good news is that these directives don't conflict; you can put both zoom and -moz-transform in the same rule and things will work fine. So I've added this to the body rule in my slides.css:

  /* If you get stuck on an 800x600 projector, use these:
  zoom: 78.125%;
  position: absolute; left: 0px; top: 0px;
  -moz-transform: scale(.78125, .78125);
   */

Uncomment in case of emergency and all will be well. (Unless you use Opera, which doesn't seem to understand either version.)

Tags: , , , , ,
[ 12:14 Jun 20, 2010    More tech/web | permalink to this entry | ]

Fri, 19 Mar 2010

Firefox printer preferences: the novel

I discovered recently that 1067 lines in my Firefox preferences file (out of 1438 total) were devoted to duplicating default printer settings.

I got a new printer recently. I needed to set up a preference in user.js so I can switch temporarily to landscape mode printing without having landscape mode become permanent. So I checked in on prefs.js to see what Firefox called my new printer -- and, well, eek!

For every printer I've ever used on this machine, I had a set of options that looked like this:

user_pref("print.printer_Epson.print_bgcolor", false);
user_pref("print.printer_Epson.print_bgimages", false);
user_pref("print.printer_Epson.print_colorspace", "default");
user_pref("print.printer_Epson.print_command", "lpr ${MOZ_PRINTER_NAME:+-P\"$MOZ_PRINTER_NAME\"}");
user_pref("print.printer_Epson.print_margin_bottom", "0.500000012107193");
user_pref("print.printer_Epson.print_margin_left", "0.500000012107193");
and so on -- 41 lines, in the case of print.printer_Epson. But some printers had multiple sets of preferences -- here's the list of printer names, each of which had those 41 lines, more or less:

In case you're curious, this encompasses three physical printers I've used with Firefox: my old Epson C86, my new HP F4280, and Dave's Brother HL 2070N. None of these values is anything I've ever set myself; they're all default values.

Why Firefox feels the need to store them for all eternity is anybody's guess.

But wait, you say ... 41 lines times 9 printers is a lot, but it doesn't come close to equalling 1067 lines. What else is there?

Well, there are another 43 lines that repeat all those same defaults again but don't specify any particular printer, like user_pref("print.print_footerleft", "&PT");.

And then, oh wait, what's this? All the preceding prefs are duplicated all over again, with "tmp" added, like this:

user_pref("print.tmp.printerfeatures.Brother_HL-2070N_series.supports_paper_size
_change", true);
user_pref("print.tmp.printerfeatures.CUPS/Brother.orientation.count", 2);
and so on. 456 lines of that.

Unfortunately, I got a little over-zealous in deleting lines before I'd made a backup of the original file. So by the time it occurred to me to write this up, I'd destroyed some of the evidence and had to work from a backup, which "only" had 813 lines of print preferences. Part of that is that I didn't have the new printer yet (two entries times 41 lines times two) but that only gets me up to 977 lines. I'm not sure what the other 190 lines were.

How many printing preferences do you have? You can see them by going to about:config and typing print. Or on Linux, you can count them. First find your profile folder, where your prefs.js file lives, or search for prefs.js directly:

locate prefs.js | grep home

Then use wc on that prefs.js file to count your print preference lines:

grep print yourprofile/prefs.js | wc -l

As to why Firefox uses so many redundant lines in the preference file for settings that have never been changed from the defaults ... well, your guess is as good as mine.

Tags: , , ,
[ 19:59 Mar 19, 2010    More tech/web | permalink to this entry | ]

Tue, 01 Dec 2009

"Cookies are small text files" -- what?

"Cookies are small text files which websites place on a visitor's computer."

I've seen this exact phrase hundreds of times, most recently on a site that should know better, The Register. 1,750,000 hits for 'Cookies are small text files'

I'm dying to know who started this ridiculous non-explanation, and why they decided to explain cookies using an implementation detail from one browser -- at least, I'm guessing IE must implement cookies using separate small files, or must have done so at one point. Firefox stores them all in one file, previously a flat file and now an sqlite database.

How many users who don't know what a cookie is do know what a "text file" is? No, really, I'm serious. If you're a geek, go ask a few non-geeks what a text file is and how it differs from other files. Ask them what they'd use to view or edit a text file. Hint: if they say "Microsoft Word" or "Open Office", they don't know.

And what exactly makes a cookie file "text" anyway? In Firefox, cookies.sqlite is most definitely not a "text file" -- it's full of unprintable characters. But even if IE stores cookies using printable characters -- have you tried to read your cookies? I just went and looked at mine, and most of them looked something like this:

Name: __utma
Value: 76673194.4936867407419370000.1243964826.1243871526.1243872726.2

I don't know about you, but I don't spend a lot of time reading text that looks like that.

Why not skip the implementation details entirely, and just tell users what cookies are? Users don't care if they're stored in one file or many, or what character set is used. How about this?

Cookies are small pieces of data which your web browser stores at the request of certain web sites.

I don't know who started this meme or why people keep copying it without stopping to think. But I smell a Fox Terrier. That was Stephen Jay Gould's example, in his book Bully for Brontosaurus, of a factoid invented by one writer and blindly copied by all who come later. The fox terrier -- and no other breed -- was used universally for years to describe the size of Eohippus. At least it was reasonably close; Gould went on to describe many more examples where people copied the wrong information, each successive textbook copying the last with no one ever going back to the source to check the information. It's usually a sign that the writer doesn't really understand what they're writing. Surely copying the phrase everyone else uses must be safe!

Tags: , , , , , ,
[ 21:25 Dec 01, 2009    More tech/web | permalink to this entry | ]

Sat, 28 Nov 2009

Debug logging in Javascript under Firefox

While debugging Javascript, I've occasionally come across references to a useful function called console.log. Supposedly you can log errors with a line like:
  console.log(""key press, char code " + e.charCode);

Since the only native way of logging debug statements in Javascript is with a pop-up alert() box, having a less obtrusive way to print is something any JS programmer could use.

The catch? It didn't do anything -- except print console is not defined.

Today a friend was crowing about how wonderful Javascript debugging was in Google's Chrome browser -- because it has functions like console.log.

[Firebug console menu] After some searching and poking around, we determined that Firefox also has console.log -- it's just well hidden and a bit hard to get going.

First, you need the Firebug extension. If you're developing Javascript, you probably already have it. If not, you need it.

Run Firebug and click to the Console tab. Now click on the tiny arrow that shows up at the right edge of that tab, as shown. Turns out there's a whole menu of options under there -- one of which is Enabled.

But wait, that's not all. In my case, the console was already Enabled according to the menu. To get the console working, I had to

  1. Disable the console
  2. Re-enable it
  3. Shift-reload the page being debugged

My friend also said that if she didn't enable the console in Firebug, then her script died when she called console.log. That didn't happen for me -- all that happened was that I got error messages in the error console (the one accessed from Firefox's Tools menu, different from the Firebug console). But it's a good idea to check for its existence if you're going to use debugging statements in your code. Like this:

  if (typeof console != "undefined") {
    console.log( "key press, char code " + e.charCode
                + ", key code " + e.keyCode
                + ", " + e.ctrlKey + ", " + e.altKey
		+ ", " + e.metaKey );
  }

Here are some more things you can do with Firebug's console.

Tags: , , ,
[ 16:41 Nov 28, 2009    More tech/web | permalink to this entry | ]

Tue, 14 Jul 2009

Quick Firefox tip: Hide the "Additional plugins" bar

Dave just discovered a useful preference in Firefox.

Firefox 'additional plugins are needed to view this page' bar

So many pages give that annoying info bar at the top that says "Additional plugins are needed to view this page." It doesn't tell you which plugins, but for Linux users it's a safe bet that whatever they are, you can't get them. Why have the stupid nagbar taking up real estate on the page for something you can't do anything about?

Displaying the info bar is the right thing for Firefox to do, of course. Some users may love to go traipsing off installing random plugins to make sure they see every annoying bit of animation and sound on a page. But Dave's excellent discovery was that the rest of us can turn off that bar.

The preference is plugins.hide_infobar_for_missing_plugin and you can see it by going to about:config and typing missing. Then double-click the line, and you'll never see that nagbar again.

Tags: , , ,
[ 12:09 Jul 14, 2009    More tech/web | permalink to this entry | ]

Sun, 12 Jul 2009

Newbie Greasemonkey script writing

I was reading a terrific article on the New York Times about Watching Whales Watching Us. At least, I was trying to read it -- but the NYT website forces font faces and sizes that, on my system, end up giving me a tiny font that's too small to read. Of course I can increase font size with Ctrl-+ -- but it gets old having to do that every time I load a NYT page.

The first step was to get Greasemonkey working on Firefox 3.5. "Update scripts" doesn't find a new script, and if you go to Greasemonkey's home page, the last entry is from many months ago and announces Firefox 3.1 support. But curiously, if you go to the Greasemonkey page on the regular Mozilla add-ons site, it does support 3.5.

I've had Greasemonkey for quite some time, but every time I try to get started writing a script I have trouble getting started. There are dozens of Greasemonkey tutorials on the web, but most of them are oriented toward installing scripts and don't address "What do you type into the fields of the Greasemonkey New User Script dialog?"

Fortunately, I did find one that explained it: The beginner's guide to Greasemonkey scripting. I gave my script a name (NYT font) and a namespace (my own domain), added http://*nytimes.com/* for Includes, and nothing for Excludes.

Click OK, and Greasemonkey offers a "choose editor" dialog. I chose emacs, which mostly worked though the emacs window unaccountably came up with a split window that I had to dismiss with C-x 1.

Now what to type in the editor? Firebug came to the rescue here.

I went back to the NYT page with the too-small fonts and clicked on Firebug. The body style showed that they're setting

font-family: Georgia, serif
font-size: 84.5%

84.5%? Where does that come from? What happens if I change that to 100%? Fortunately, I can test that right there in the Firebug window. 100% made the fonts fairly huge, but 90% was about right.

I went back to greasemonkey's editor window and added:

document.body.style.fontSize = "90%";

Saved the file, and that was all I needed! Once I hit Reload on the NYT page I got a much more readable font size.

Tags: , , , ,
[ 12:30 Jul 12, 2009    More tech/web | permalink to this entry | ]

Mon, 13 Apr 2009

Setting "cursive" and "fantasy" in Firefox: two methods

I'm taking a CSS class, hoping to get a more solid understanding of these CSS parameters I tweak and why they do or don't work, and one of the exercises involved using the CSS font family "cursive". Which, on my Firefox, displayed in MS Comic Sans. That doesn't look very cursive to me!

To test what you're seeing now for cursive and fantasy, use the W3C font-family test page ... or these might work (though they might not survive RSS feeds to other sites):

This is a Cursive font ... ... This is a Fantasy font

Being a font junkie, I have plenty of nice cursive fonts installed. The question was how to tell Firefox about them, since its font dialog (unlike the old Seamonkey/Mozilla suite's) doesn't make any allowance for setting them, nor do the categories show up in about:config.

Method 1: Firefox prefs

The answer was in this Mozillazine thread. Edit user.js in your Firefox profile and add lines like:

// Set cursive and fantasy fonts
user_pref("font.name.cursive.x-western", "Allegro");
user_pref("font.name.fantasy.x-western", "Dragonwick");
(of course, use fonts you have installed, not necessarily Allegro and Dragonwick).

The bug (marked WONTFIX) requesting Firefox offer this in the Preferences window is bug 196405, and related bug 61883.

Method 2: fontconfig

But wait! Soon after I figured out how to set the font family for Firefox, I noticed that the font was still MS Comic Sans in other browsers -- konqueror, midori, opera. It occurred to me that that Comic Sans cursive was probably coming from fontconfig settings, and it should be possible to change fontconfig's defaults for these categories.

And indeed it was, and fairly simple, too. Just make a file named .fonts.conf in your home directory and add this to it:

<?xml version='1.0'?>
<!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
<fontconfig>
  <alias>
    <family>cursive</family>
    <prefer>
      <family>Allegro</family>
    </prefer>
  </alias>
  <alias>
    <family>fantasy</family>
    <prefer>
      <family>BoomerangItalic</family>
    </prefer>
  </alias>
</fontconfig>

Again, substitute your own fonts ... but beware. The hard part of this exercise turned out to be that some fonts worked and some didn't, following no rhyme or reason. My first five choices for a fantasy font weren't picked up by fontconfig, but finally I found a few that were. It isn't related to whether they have spaces in the font name; it isn't where they're installed (I was using only fonts in ~/.fonts); I have no idea why some fonts work in ~/.fonts.conf and others don't.

It's rather tedious to test, since the only way to test it is to exit and re-start firefox. I've never found a font viewer that will display the fonts visible to fontconfig or pango; you have to start up some full-fledged application like firefox or gimp, and gimp doesn't see categories like cursive or fantasy.

In the end I did find fonts that worked in firefox. But ironically, although the system-level fix seems like a better way to go, my font changes still don't show up in other browsers. In opera, cursive shows up in bold block letters, while its fantasy is MS Comic Sans. Konqeror and Midori don't handle cursive and fantasy at all, showing them as plain sans-serif. And in IE6 running under wine, cursive still shows up as MS Comic Sans ... while fantasy displays in Greek letters.

Tags: , , ,
[ 21:30 Apr 13, 2009    More tech/web | permalink to this entry | ]

Wed, 18 Mar 2009

Quick tip: When Firefox forgets bookmarks

Firefox started forgetting new bookmarks. I'd make a few bookmarks, filing them in the right place ... then the next time I started up, they wouldn't be there and I had to go find them again. I tested and verified that it wasn't that I was exiting Firefox uncleanly; even if I ran from the terminal, made a bookmark, and exited, nothing would be saved.

It took me forever to find anything on this with google, so I'm blogging it in the hope of making it easier for the next person to find. It turns out the Mozilla Knowledge Base has a terrific article called Bookmarks not saved that discusses lots of ways this can happen. Go through the list and you'll probably find a solution.

In my case it was the second item: "Places preferences - Firefox 3". It turned out that all three of my boolean browser.places preferences were set to non-default values -- not by me, since I'd never heard of any of the browser.places preferences before. After toggling all three of them by double-clicking, Firefox lost its anterograde amnesia and started remembering new bookmarks again.

Tags: , ,
[ 23:01 Mar 18, 2009    More tech/web | permalink to this entry | ]

Sun, 11 Jan 2009

Cleaning up Firefox "places" history

Update: For details on how to edit Firefox history rather than just delete it, see this later post: Removing Bad Autocompletes from Firefox's Location Bar.

Firefox decided, some time ago, that whenever I try to type in a local file pathname, as soon as I start typing /home/... I must be looking for one specific file: an article I wrote over two months ago and am long since done with. Usually it happens when I'm trying to preview a new article. I no longer have any interest in my local copy of that old article; it's not bookmarked or anything like that; I haven't viewed it in quite some time. But try to tell Firefox that. It's convinced that the old one (why that one, and not one of the more recent ones?) is what I want.

A recursive grep in ~/.mozilla/firefox showed that the only reference to the old unwanted file was in the binary file places.sqlite.

My places.sqlite was 11Mb. I look through the Prefs window showed that the default setting was to store history for minimum of 90 days. That seemed rather excessive, so I reduced it drastically. But that didn't reduce the size of the file any, nor did it banish the spurious URLbar suggestion when I typed /home/....

After some discussion with folks on IRC, it developed that Firefox may never actually reduce the size of the places.sqlite file at all. Even if it did reduce the amount of data in the file (which it's not clear it does), it never tells sqlite to compact the file to use less space. Apparently there was some work on that about a year ago, but it was slow and unreliable and they never got it working, and eventually gave up on it.

You can run an sqlite compaction by hand (make sure to exit your running firefox first!):

sqlite3 places.sqlite vacuum

But vacuuming really didn't help much. It reduced the size of the file from 11 to 8.8 Mb (after reducing the number of days firefox was supposed to store to less than a third of the original size) and it didn't get rid of that spurious suggestion.

So the only remaining option seemed to be to remove the file. It stores both history and bookmarks, so it's best to back up bookmarks before removing it. I backed up bookmarks to the .json format firefox likes to use for backups, and also exported them to a more human (and browser) readable bookmarks.html. Then I removed the places.sqlite file.

Success! The spurious recommendation was gone. Typing seems faster too (less of those freezes while the "awesomebar" searches through its list of recommendations).

So I guess firefox can't be trusted to clean up after itself, and users who care have to do that manually. It remains to be seen how much the file will grow now. I expect periodic vacuumings or removals will still be warranted if I don't want a huge file; but it's pretty easy to do, and firefox found the bookmarks backup and reloaded them without any extra work on my part.

In the meantime, I made a new bookmark -- hidden in my bookmarklets menu so it doesn't clutter the main bookmarks menu -- to the directory where I preview articles I'm writing. That ought to help a bit with future URLbar suggestions.

Tags: , ,
[ 12:00 Jan 11, 2009    More tech/web | permalink to this entry | ]

Thu, 20 Nov 2008

Handling Long URLs in Firefox

I have a new Firefox Tips article up on Linux Planet: The Plague of Ridiculously Long URLs (note I didn't choose the title). It discussees how to handle long URLs broken over several lines, of the sort we so often see in email messages.

Tags: , ,
[ 10:43 Nov 20, 2008    More writing | permalink to this entry | ]

Thu, 06 Nov 2008

Linux Planet: Why Firefox Rocks on Linux

My latest Linux Planet article, Why Firefox Rocks on Linux, discusses Linux-specific Firefox shortcuts involving the middle mouse button, the URLbar and the scrollbar. It's getting good Diggs, too, and comments from people who found the tips helpful, which is great. A lot of people don't know about some of these great Linux time-savers, but these are the sort of things that make me love Linux and stick with it even when it gets frustrating. I hate to think of people missing out just because there's no obvious way to discover some of the shortcuts!

Tags: , , ,
[ 21:44 Nov 06, 2008    More writing | permalink to this entry | ]

Mon, 03 Nov 2008

A word count bookmarklet

This posting ended up being published as a Linux Planet Quick Tip. You can read about my nifty word counting bookmarklet there: Quick Firefox Tip: Word Count Bookmarklet.

Tags: , , , ,
[ 23:41 Nov 03, 2008    More tech/web | permalink to this entry | ]

Sun, 26 Oct 2008

Two articles: Linux Bookmarklets

I've been writing a new series for Linux Planet, on Firefox Tricks. The first two articles cover bookmarklets, something I've mentioned a few times in this blog):

Simple Bookmarklets: The Power of the Command Line in your Browser
and
Roll Your Own Custom Bookmarklets In Firefox, part 2: Javascript Bookmarklets.

Tags: , , ,
[ 23:32 Oct 26, 2008    More writing | permalink to this entry | ]

Mon, 08 Sep 2008

Turning off Firefox 3's whizzy drag images

Among Firefox 3's whizzy new features, compared to Firefox 2, is the drag images. If you drag from anywhere in the browser, instead of getting the little cursor-sized drag image following the cursor, you get a preview -- sometimes even a full-sized copy -- of what you're dragging.

It's really startling and neat and whizzy looking. Except ... when you're dragging and you have this large very pretty, and very opaque, image under your mouse, you can no longer see whatever should be under the image -- like the tab where you're trying to drop it.

After two or three weeks of never being able to drag a URL to another tab to open it there (I kept guessing where the tab was, guessing wrong and having it open as a new tab) I went exploring.

Fortunately it turns out they've provided an easy way to turn it off. Go to about:config and search for "drop". Find the line for nglayout.enable_drag_images and double-click it. Or add this line to your user.js or prefs.js:
user_pref("nglayout.enable_drag_images", false);

Tags: , ,
[ 20:21 Sep 08, 2008    More tech/web | permalink to this entry | ]

Fri, 04 Jul 2008

Learning about Firefox 3 extensions

Oops! Right after I posted that last entry, I discovered that my little kitfox extension wasn't working as well as I'd thought. And the more I hacked it, the less well it worked, and the more I discovered was missing, like a chrome.manifest file (which firefox 2 hadn't seemed to need).

Eventually some very helpful folks on #extdev pointed me to Ted Mielczarek's excellent Extension Wizard. Give it some details about your extension (its name and version, your name, and a couple things you might want like a toolbar button, a prefs panel and a context menu) and it generates a zipped directory containing a bare bones extension, even including niceties like internationalized strings.

Even better, your new extension skeleton includes a readme that tells you how to leave the extension expanded while you work on it. That's quite a bit easier than building the XPI file and installing it each time.

So kitfox has a 0.3 version (in the unlikely event that anybody besides me wants it).

There's a project called fizzypop to develop and extend useful Mozilla dev tools like the Extension Wizard ... watch that space for more details.

Tags: , ,
[ 21:12 Jul 04, 2008    More tech/web | permalink to this entry | ]

Making Firefox 3 livable

I finally broke down and spent the time to get Firefox 3 working properly for me ... meaning, mostly, finding replacement extensions for the bare minimum of what I need in a browser: control over cookies (specifically, enabling/disabling them for specific sites), flashblock, and blocking of animated images. I'd downloaded extensions for all those a few weeks ago, but I found that although Firefox 3.0 said the FF3 extensions were active, and Firefox 2 said the old ones were, neither set actually worked.

I decided to start from scratch: remove all extensions -- rm -rf .mozilla/firefox/extensions/* .mozilla/firefox/extensions.* plus apt-get remove firefox-2-dom-inspector -- then install a new set of Firefox 3 add-ons.

After much hunting (I sure wish addons.mozilla.org would offer a way to limit the view to only extensions that work with Firefox 3! Combing through 15 pages of extensions looking for the handful that will actually install gets old fast) I found the replacements I needed: CS Lite for the cookie controls, a newer Flashblock, and Custom Toolbar Buttons as a stopgap for image animation (though I suspect updating anidisable will be a better solution in the long run). This time, with the old firefox 2 extensions purged, the new ones took hold and worked.

I also added a nice extension called OpenBook that fixes the horrible Firefox "Add bookmark" dialog. You know: the one that has two nearly identical dropdown category menus side by side, with the bigger one giving you only a tiny subset of your bookmark categories, and the smaller one being the real one. The one that doesn't offer a space for keyword, so to set up a bookmarklet you have to Add Bookmark, OK, Organize Bookmarks, find the bookmark you just added, Ctrl-I to get the Bookmark info dialog, and finally you can add your keyword. OpenBook gives you a dialog where you can set the keyword to begin with, and it only gives you one menu to list categories so you aren't constantly tempted to click on the wrong one.

Now for the urlbar -- that new firefox 3 "smarter" urlbar that slows down typing in the middle of a word so it can pop up a big fancy window full of guesses (all wrong) about where I might be trying to go. Actually, even if the guesses were right, it wouldn't help, because I'd have to stop typing, search the list visually, then if one of the suggestions was right, move my hand to the mouse or the arrow keys to choose that suggestion. That takes way longer than just typing the url.

But I guess I don't mind unhelpful suggestions popping up as long as it doesn't mess up focus (preventing me from clicking or tabbing to other apps on my screen) or slow down typing. Firefox 3 seems to be handling the focus issue better than firefox 2 did, but the slowdown was quite noticeable on the poor old laptop. So I wanted a way to disable the behavior. A little googling revealed that the Firefox crew immodestly calls their new urlbar the "awesomebar", which aside from giggle factor also proves quite useful in googling: a search on firefox disable awesomebar reveals that I'm not the only one who doesn't like it, and got me several preferences I could tweak in about:config plus a couple of extensions to turn it off entirely. I won't try to summarize, since the best settings depend on your machine's spec, plus personal preference.

Making progress! Now the only issue was getting my urlbar tweaks working, so that typing <Ctrl-Return> after typing a URL opened the URL in a new tab instead of tacking on various silly extensions (oh, yes, of course I wanted to go to http://www.firefox disable awesomebar.com rather than googling for those terms in a new tab). Fortunately, it turned out that the javascript that runs the urlbar has changed very little since firefox 2, and I hardly needed to change anything to get my kitfox extension (v. 0.2) working in Firefox 3.

Only one more issue: this blog. The CSS that handles the right sidebar wasn't displaying right. Seems that Firefox 2 has changed something about its interpretation of CSS, so it was floating the right sidebar way down to the bottom of the page below the last content line. Eventually (after adding firefox-3.0-dom-inspector, another extension that had stopped working in the transition) I discovered the problem: the #content was set to width: 77% while the #rightsidebar's left-margin was at 76%. Apparently Firefox 2 rounded up as needed, whereas Firefox 3 just ignores the left-margin if it would overlap the content, and then floats the sidebar anywhere it thinks it can fit it. Fixing those percentages helped quite a bit, and I added an overflow-x: hidden (on a tip from a helpful person in #firefox) so that wide calendar doesn't hurt layout for narrow windows. I think it's working now ... any readers having problems with the layout in any browser, by all means let me know.

Tags: , , , ,
[ 12:04 Jul 04, 2008    More tech/web | permalink to this entry | ]

Thu, 12 Jun 2008

Making Firefox default to Portrait printing

I discovered a handy tip for Linux Firefox' printing Page Setup today.

Normal web page printing uses "Portrait" mode: you read the page with the paper oriented so that it's taller than it is wide.

Once a week, I need to print a form from a club web site to bring to the meetings. It's a table that's much wider than it is tall, so I want to print it that way: in "Landscape" mode.

In Firefox 2 (at least on Linux), you can't do that from the Print dialog -- there's no Portrait/Landscape option. So you have to use a separate dialog, Page Setup, following these steps:

  1. Run Page Setup
  2. Change Portrait to Landscape
  3. Click OK
  4. Print (bring up the Print dialog and click OK)
  5. Run Page Setup
  6. Change Landscape to Portrait
  7. Click OK
Kind of a lot of steps just to print one landscape page! But if you forget, the next page you print from Firefox will be printed in Landscape mode and will take twice as many pages as it should (if you don't notice what's happening and dive for the printer's OFF switch in time, that being the only way to cancel a printing job once it hits the printer).

This morning, it finally occurred to me that Firefox was storing this setting somehow, most likely in prefs.js. If I could find the setting and force it in user.js (which takes precedence over prefs.js and is not updated by Firefox), I could make Firefox set itself back to Portrait every time it starts up. (prefs.js and user.js are both generally found in $HOME/.mozilla/firefox/).

Some greppery-pokery revealed the solution. I needed only to add a line in user.js that looks like this:

user_pref("print.printer_CUPS/Epson.print_orientation", 0);
and presto! my problem was solved.

Oddly, it's set separately for every printer you have defined, even though there's no way to set one printer to Landscape while another one is still on Portrait (the Page Setup dialog is global, and applies to every printer Firefox knows about). "Epson" is the CUPS name of my primary printer; replace that with your printer's name (as set in CUPS), and add a similar line for each printer you have. For the printers I've used, 0 is Portrait and 1 is Landscape, but you can verify that by typing:

grep orientation prefs.js | grep name

That command will also help you if you're not sure what printers you have defined, or you don't use CUPS but want to try this under a different print spooler. (Don't be misled by all the orientation prefs with "tmp" in the name.)

As a minor digression, there's actually a secret pref that's supposed to give another way around the problem:

user_pref("print.whileInPrintPreview", true);
This lets you do all your printing from the Print Preview window, which offers its own Portrait and Landscape buttons. That would be a nice solution. Alas, the Portrait and Landscape buttons in that dialog currently don't work, and since this preference is undocumented and unmaintained, filing more bugs isn't likely to help.

(I should mention that this all pertains to Firefox 2. I haven't switched to Firefox 3 yet, so I don't know the state of its printing UI, or whether this preference is either helpful or effective there.)

Tags: , , ,
[ 21:07 Jun 12, 2008    More tech/web | permalink to this entry | ]

Tue, 08 Apr 2008

Wrapping plaintext files in Firefox

A friend pointed me to a story she'd written. It was online as a .txt file. Unfortunately, it had no line breaks, and Firefox presented it with a horizontal scrollbar and no option to wrap the text to fit in the browser window.

But I was sure that was a long-solved problem -- surely there must be a userContent.css rule or a bookmarklet to handle text with long lines. The trick was to come up with the right Google query. Like this one: firefox OR mozilla wrap text userContent OR bookmarklet

I settled on the simple CSS rule from Tero Karvinen's page on Making preformated <pre> text wrap in CSS3, Mozilla, Opera and IE:

pre {
 white-space: -moz-pre-wrap !important;
}
Add it to chrome/userContent.css and you're done.

But some people might prefer not to apply the rule to all text. If you'd prefer a rule that can be applied at will, a bookmarklet would be better. Like the word wrap bookmarklet from Return of the Sasquatch or the one from Jesse Ruderman's Bookmarklets for Zapping Annoyances collection.

Tags: , , , , ,
[ 11:47 Apr 08, 2008    More tech/web | permalink to this entry | ]

Sat, 20 Oct 2007

Firefox, caching, and fast Back/Forward buttons

I remember a few years ago the Mozilla folks were making a lot of noise about the "blazingly fast Back/Forward" that was coming up in the (then) next version of Firefox. The idea was that the layout engine was going to remember how the page was laid out (technically, there would be a "frame cache" as opposed to the normal cache which only remembers the HTML of the page). So when you click the Back button, Firefox would remember everything it knew about that page -- it wouldn't have to parse the HTML again or figure out how to lay out all those tables and images, it would just instantly display what the page looked like last time.

Time passed ... and Back/Forward didn't get faster. In fact, they got a lot slower. The "Blazingly Fast Back" code did get checked in (here's how to enable it) but somehow it never seemed to make any difference.

The problem, it turns out, is that the landing of bug 101832 added code to respect a couple of HTTP Cache-Control header settings, no-store and no-cache. There's also a third cache control header, must-revalidate, which is similar (the difference among the three settings is fairly subtle, and Firefox seems to treat them pretty much the same way).

Translated, that means that web servers, when they send you a page, can send some information along with the page that asks the browser "Please don't keep a local copy of this page -- any time you want it again, go back to the web and get a new copy."

There are pages for which this makes sense. Consider a secure bank site. You log in, you do your banking, you view your balance and other details, you log out and go to lunch ... then someone else comes by and clicks Back on your browser and can now see all those bank pages you were just viewing. That's why banks like to set no-cache headers.

But those are secure pages (https, not http). There are probably reasons for some non-secure pages to use no-cache or no-store ... um ... I can't think of any offhand, but I'm sure there are some.

But for most pages it's just silly. If I click Back, why wouldn't I want to go back to the exact same page I was just looking at? Why would I want to wait for it to reload everything from the server?

The problem is that modern Content Management Systems (CMSes) almost always set one or more of these headers. Consider the Linux.conf.au site. Linx.conf.au is one of the most clueful, geeky conferences around. Yet the software running their site sets

  Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
  Pragma: no-cache
on every page. I'm sure this isn't intentional -- it makes no sense for a bunch of basically static pages showing information about a conference several months away. Drupal, the CMS used by LinuxChix sets Cache-Control: must-revalidate -- again, pointless. All it does is make you afraid to click on links because then if you want to go Back it'll take forever. (I asked some Drupal folks about this and they said it could be changed with drupal_set_header).

(By the way, you can check the http headers on any page with: wget -S -O /dev/null http://... or, if you have curl, curl --head http://...)

Here's an excellent summary of the options in an Opera developer's blog, explaining why the way Firefox handle caching is not only unfriendly to the user, but also wrong according to the specs. (Darn it, reading sensible articles like that make me wish I wasn't so deeply invested in Mozilla technology -- Opera cares so much more about the user experience.)

But, short of a switch to Opera, how could I fix it on my end? Google wasn't any help, but I figured that this must be a reported Mozilla bug, so I turned to Bugzilla and found quite a lot. Here's the scoop. First, the code to respect the cache settings (slowing down Back/Forward) was apparently added in response to bug 101832. People quickly noticed the performance problem, and filed 112564. (This was back in late 2001.) There was a long debate, but in the end, a fix was checked in which allowed no-cache http (non-secure) sites to cache and get a fast Back/Forward. This didn't help no-store and must-revalidate sites, which were still just as slow as ever.

Then a few months later, bug 135289 changed this code around quite a bit. I'm still getting my head around the code involved in the two bugs, but I think this update didn't change the basic rules governing which pages get revalidated.

(Warning: geekage alert for next two paragraphs. Use this fix at your own risk, etc.)

Unfortunately, it looks like the only way to fix this is in the C++ code. For folks not afraid of building Firefox, the code lives in nsDocShell::ShouldDiscardLayoutState and controls the no-cache and no-store directives. In nsDocShell::ShouldDiscardLayoutState (currently lie 8224, but don't count on it), the final line is:

    return (noStore || (noCache && securityInfo));
Change that to
    return ((noStore || noCache) && securityInfo);
and Back/Forward will get instantly faster, while still preserving security for https. (If you don't care about that security issue and want pages to cache no matter what, just replace the whole function with return PR_FALSE; )

The must-validate setting is handled in a completely different place, in nsHttpChannel. However, for some reason, fixing nsDocShell also fixes Drupal pages which set only must-validate. I don't quite understand why yet. More study required. (End geekage.)

Any Mozilla folks are welcome to tell me why I shouldn't be doing this, or if there's a better way (especially if it's possible in a way that would work from an extension or preference). I'd also be interested in from Drupal or other CMS folks defending why so many CMSes destroy the user experience like this. But please first read the Opera article referenced above, so that you understand why I and so many other users have complained about it. I'm happy to share any comments I receive (let me know if you want your comments to be public or not).

Tags: , , , ,
[ 20:32 Oct 20, 2007    More tech/web | permalink to this entry | ]

Wed, 04 Jul 2007

Make Amazon pages narrow enough to read

I like buying from Amazon, but it's gotten a lot more difficult since they changed their web page design to assume super-wide browser windows. On the browser sizes I tend to use, even if I scroll right I can't read the reviews of books, because the content itself is wider than my browser window. Really, what's up with the current craze of insisting that everyone upgrade their screen sizes then run browser windows maximized?

(I'd give a lot for a browser that had the concept of "just show me the page in the space I have". Opera has made some progress on this and if they got it really working it might even entice me away from Firefox, despite my preference for open source and my investment in Mozilla technology ... but so far it isn't better enough to justify a switch.)

I keep meaning to try the greasemonkey extension, but still haven't gotten around to it. Today, I had a little time, so I googled to see if anyone had already written a greasemonkey script to make Amazon readable. I couldn't find one, but I did find a page from last October trying to fix a similar problem on another website, which mentioned difficulties in keeping scripts working under greasemonkey, and offered a Javascript bookmarklet with similar functionality.

Now we're talking! A bookmarklet sounds a lot simpler and more secure than learning how to program Greasemonkey. So I grabbed the bookmarklet, a copy of an Amazon page, and my trusty DOM Inspector window and set about figuring out how to make Amazon fit in my window.

It didn't take long to realize that what I needed was CSS, not Javascript. Which is potentially a lot easier: "all" I needed to do was find the right CSS rules to put in userContent.css. "All" is in quotes because getting CSS to do anything is seldom a trivial task.

But after way too much fiddling, I did finally come up with a rule to get Amazon's Editorial Reviews to fit. Put this in chrome/userContent.css inside your Firefox profile directory (if you don't know where your profile directory is, search your disk for a file called prefs.js):

div#productDescription div.content { max-width: 90% !important; }

You can replace that 90% with a pixel measurement, like 770px, or with a different percentage.

I spent quite a long time trying to get the user reviews (a table with two columns) to fit as well, without success. I was trying things like:

#customerReviews > div.content > table > tbody > tr > td { max-width: 300px; min-width: 10px !important; }
div#customerReviews > div.content > table { margin-right: 110px !important; }
but nothing worked, and some of it (like the latter of those two lines) actually interfered with the div.content rule for reasons I still don't understand. (If any of you CSS gurus want to enlighten me, or suggest a better or more complete solution, or solutions that work with other web pages, I'm all ears!)

I'll try for a more complete solution some other time, but for now, I'm spending my July 4th celebrating my independance from Amazon's idea of the one true browser width.

Tags: , , , ,
[ 21:01 Jul 04, 2007    More tech/web | permalink to this entry | ]

Thu, 28 Jun 2007

A Quartet of Workarounds

I upgraded my laptop's Ubuntu partition from Edgy to Feisty. Debian Etch works well, but it's just too old and I can't build software like GIMP that insists on depending on cutting-edge libraries.

But Feisty is cutting edge in other ways, so it's been a week of workarounds, in two areas: Firefox and the kernel. I'll start with Firefox.

Firefox crashes playing flash

First, the way Ubuntu's Firefox crashes when running Flash. I run flashblock, fortunately, so I've been able to browse the web just fine as long as I don't click on a flashblock button. But I like being able to view the occasional youtube video, and flash 7 has worked fine for me on every distro except Ubuntu. I first saw the problem on Edgy, and upgrading to Feisty didn't cure the problem.

But it wasn't their Firefox build; my own "kitfox" firefox build crashed as well. And it wasn't their flash installation; I've never had any luck with either their adobe flash installer nor their opensource libswfdec, so I'm running the same old flash 7 plug-in that I've used all along for other distros.

To find out what was really happening, I ran Firefox from the commandline, then went to a flash page. It turned out it was triggering an X error:

The error was: 'BadMatch (invalid parameter attributes)'.
(Details: serial 104 error_code 8 request_code 145 minor_code 3)

That gave me something to search for. It turns out there's a longstanding Ubuntu bug, 14911 filed on this issue, with several workarounds. Setting the environment variable XLIB_SKIP_ARGB_VISUALS to 1 fixed the problem, but, reading farther in the bug, I saw that the real problem was that Ubuntu's installer had, for some strange reason, configured my X to use 16 bit color instead of 24. Apparently this is pretty common, and due to some bug involving X's and Mozilla's or Flash's handling of transparency, this causes flash to crash Mozilla.

So the solution is very simple. Edit /etc/X11/xorg.conf, look for the DefaultDepth line, and if it's 16, that's your problem. Change it to 24, restart X and see if flash works. It worked for me!

Eliminating Firefox's saved session pester dialog

While I was fiddling with Firefox, Dave started swearing. "Why does Firefox always make me go through this dialog about restoring the last session? Is there a way to turn that off?"

Sure enough, there's no exposed preference for this, so I poked around about:config, searched for browser and found browser.sessionstore.resume_from_crash. Doubleclick that line to change it to false and you'll have no more pesky dialog.

For more options related to session store, check the Mozillazine Session Restore page.

Kernel: runaway kacpid

Alas, having upgraded to Feisty expressly so that I could build cutting-edge programs like GIMP, I discovered that I couldn't build anything at all. Anything that uses heavy CPU for more than a minute or two triggers a kernel daemon, kacpid, to grab most of the CPU for itself. Being part of the kernel (even though it has a process ID), kacpi is unkillable, and prevents the machine from shutting down, so once this happens the only solution is to pull the power plug.

This has actually been a longstanding Ubuntu problem (bug 75174) but it used to be that disabling acpid would stop kacpid from running away, and with feisty, that no longer helps. The bug is also kernel.org bug 8274.

The Ubuntu bug suggested that disabling cpufreq solved it for one person. Apparently the only way to do that is to build a new kernel. There followed a long session of attempted kernel building. It was tricky because of course I couldn't build on the target machine (inability to build being the problem I was trying to solve), and even if I built on my desktop machine, a large rsync of the modules directory would trigger a runaway kacpi. In the end, building a standalone kernel with no modules was the only option.

But turning off cpufreq didn't help, nor did any of the other obvious acpi options. The only option which stops kacpid is to disable acpi altogether, and use apm. I'm sorry to lose hibernate, and temperature monitoring, but that appears to be my only option with modern kernels. Sigh.

Kernel: Hangs for 2 minutes at boot time initializing sound card

While Dave and I were madly trying to find a set of config options to build a 2.6.21 that would boot on a Vaio (he was helping out with his SR33 laptop, starting from a different set of config options) we both hit, at about the same time, an odd bug: partway through boot, the kernel would initialize the USB memory stick reader:

sd 0:0:0:0: Attached scsi removable disk sda
sd 0:0:0:0: Attached scsi generic sg0 type 0
and then it would hang, for a long time. Two minutes, as it turned out. And the messages after that were pretty random: sometimes related to the sound card, sometimes to the network, sometimes ... GConf?! (What on earth is GConf doing in a kernel boot sequence?) We tried disabling various options to try to pin down the culprit: what was causing that two minute hang?

We eventually narrowed the blame to the sound card (which is a Yamaha, using the ymfpci driver). And that was enough information for google to find this Linux Kernel Mailing List thread. Apparently the sound maintainer decided, for some reason, to make the ymfpci driver depend on an external firmware file ... and then didn't include the firmware file, nor is it included in the alsa-firmware package he references in that message. Lovely. I'm still a little puzzled about the timeout: the post does not explain why, if a firmware file isn't found on the disk, waiting for two minutes is likely to make one magically appear.

Apparently it will be fixed in 2.6.22, which isn't much help for anyone who's trying to run a kernel on any of the 2.6.21.* series in the meantime. (Isn't it a serious enough regression to fix in 2.6.21.*?) And he didn't suggest a workaround, except that alsa-firmware package which doesn't actually contain the firmware for that card. Looks like it's left to the user to make things work.

So here's what to do: it turns out that if you take a 2.6.21 kernel, and substitute the whole sound/pci/ymfpci directory from a 2.6.20 kernel source tree, it builds and boots just fine. And I'm off and running with a standalone apm kernel with no acpi; sound works, and I can finally build GIMP again.

So it's been quite a week of workarounds. You know, I used to argue with all those annoying "Linux is not ready for the desktop" people. But sometimes I feel like Linux usability is moving in the wrong direction. I try to imagine explaining to my mac-using friends why they should have to edit /etc/X11/xorg.conf because their distro set up a configuration that makes Firefox crash, or why they need to build a new kernel because the distributed ones all crash or hang ... I love Linux and don't regret using it, but I seem to need workarounds like this more often now than I did a few years ago. Sometimes it really does seem like the open source world is moving backward, not forward.

Tags: , , , , ,
[ 23:24 Jun 28, 2007    More linux | permalink to this entry | ]

Sun, 27 May 2007

A Kitfox Extension

For a bit over a year I've been running a patched version of Firefox, which I call Kitfox, as my main browser. I patch it because there are a few really important features that the old Mozilla suite had which Firefox removed; for a long time this kept me from using Firefox (and I'm not the only one who feels that way), but when the Mozilla Foundation stopped supporting the suite and made Firefox the only supported option, I knew my only choice was to make Firefox do what I needed. The patches were pretty simple, but they meant that I've been building my own Firefox all this time.

Since all my changes were in JavaScript code, not C++, I knew this was probably all achievable with a Firefox extension. But never around to it; building the Mozilla source isn't that big a deal to me. I did it as part of my job for quite a few years, and my desktop machine is fast enough that it doesn't take that long to update and rebuild, then copy the result to my laptop.

But when I installed the latest Debian, "Etch", on the laptop, things got more complicated. It turns out Etch is about a year behind in its libraries. Programs built on any other system won't run on Etch. So I'd either have to build Mozilla on my laptop (a daunting prospect, with builds probably in the 4-hour range) or keep another system around for the purpose of building software for Etch. Not worth it. It was time to learn to build an extension.

There are an amazing number of good tutorials on the web for writing Firefox extensions (I won't even bother to link to any; just google firefox extension and make your own choices). They're all organized as step by step examples with sample code. That's great (my favorite type of tutorial) but it left my real question unanswered: what can you do in an extension? The tutorial examples all do simple things like add a new menu or toolbar button. None of them override existing Javascript, as I needed to do.

Canonical URL to the rescue. It's an extension that overrides one of the very behaviors I wanted to override: that of adding "www." to the beginning and ".com" or ".org" to the end of whatever's in the URLbar when you ctrl-click. (The Mozilla suite behaved much more usefully: ctrl-click opened the URL in a new tab, just like ctrl-clicking on a link. You never need to add www. and .com or .org explicitly because the URL loading code will do that for you if the initial name doesn't resolve by itself.) Canonical URL showed me that all you need to do is make an overlay containing your new version of the JavaScript method you want to override. Easy!

So now I have a tiny Kitfox extension that I can use on the laptop or anywhere else. Whee!

Since extensions are kind of a pain to unpack, I also made a source tarball which includes a simple Makefile: kitfox-0.1.tar.gz.

Tags: , , , ,
[ 11:59 May 27, 2007    More tech/web | permalink to this entry | ]

Sat, 05 May 2007

The Pesky "Unresponsive Script" Dialog

For quite some time, I've been seeing all too frequently the dialog in Firefox which says:
A script on this page may be busy, or it may have stopped responding. You can stop the script now, or continue to see if the script will complete.
[Continue] [Stop script]

Googling found lots of pages offering advice on how to increase the timeout for scripts from the default of 5 seconds to 20 or more (change the preference dom.max_script_run_time in about:config. But that seemed wrong. I was seeing the dialog on lots of pages where other people didn't see it, even on my desktop machine, which, while it isn't the absolute latest and greatest in supercomputing, still is plenty fast for basic web tasks.

The kicker came when I found the latest page that triggers this dialog: Firefox' own cache viewer. Go to about:cache and click on "List Cache Entries" under Disk cache device. After six or seven seconds I got an Unresponsive script dialog every time. So obviously this wasn't a problem with the web sites I was visiting.

Someone on #mozillazine pointed me to Mozillazine's page discussing this dialog, but it's not very useful. For instance, it includes advice like

To determine what script is running too long, open the Error Console and tell it to stop the script. The Error Console should identify the script causing the problem.
Error console? What's that? I have a JavaScript Console, but it doesn't offer any way to stop scripts. No one on #mozillazine seemed to have any idea where I might find this elusive Error console either. Later Update: turns out this is new with Firefox 2.0. I've edited the Mozillazine page to say so. Funny that no one on IRC knew about it.

But there's a long and interesting MozillaZine discussion of the problem in which it's clear that it's often caused by extensions (which the Mozillazine page had also suggested). I checked the suggested list of Problematic extensions, but I didn't see anything that looked likely.

So I backed up my Firefox profile and set to work, disabling my extensions one at a time. First was Adblock, since it appeared in the Problematic list, but removing it didn't help: I still got the Unresponsive script when viewing my cache.

The next try was Media Player Connectivity. Bingo! No more Unresponsive dialog. That was easy.

Media Player Connectivity never worked right for me anyway. It's supposed to help with pages that offer videos not as a simple video link, like movie.mpeg or movie.mov or whatever, but as an embedded object in the page which insists on a specific browser plug-in (like Apples's QuickTime or Microsoft's Windows Media Player).

Playing these videos in Firefox is a huge pain in the keister -- you have to View Source and crawl through the HTML trying to find the URL for the actual video. Media Player Connectivity is supposed to help by doing the crawl for you and presenting you with video links for any embedded video it finds. But it typically doesn't find anything, and its user interface is so inconsistent and complicated that it's hard to figure out what it's telling you. It also can't follow the playlists and .SMIL files that so many sites use now. So I end up having to crawl through HTML source anyway.

Too bad! Maybe some day someone will find a way to make it easier to view video on Linux Firefox. But at least I seem to have gotten rid of those Unresponsive Script errors. That should make for nicer browsing!

Tags: , , ,
[ 13:07 May 05, 2007    More tech/web | permalink to this entry | ]

Fri, 04 Aug 2006

Disabling mailto links

Every time I click on a mailto link, Firefox wants to bring up Evolution. That's a fairly reasonable behavior (I'm sure Evolution is configured as the default mailer somewhere on my system even though I've never used it) but it's not what I want, since I have mutt running through a remote connection to another machine and that's where I'd want to send mail. Dismissing the dialog is an annoyance that I keep meaning to find a way around.

But I just learned about two excellent solutions:

First: network.protocol-handler.warn-external.mailto
Set this preference to TRUE (either by going to about:config and searching for mailto, then doubleclicking on the line for this preference, or by editing the config.js or user.js file in your firefox profile) and the next time you click on a mailto link, you'll get a confirmation dialog asking whether you really want to launch an external mailer.

"Ew! Cancelling a dialog every time is nearly as bad as cancelling the Evolution launch!" Never fear: this dialog has a "Don't show me this again" checkbox, so check it and click Cancel and Firefox will remember. From then on, clicks on mailto links will be treated as no-ops.

"But wait! It's going to be confusing having links that do nothing when clicked on. I'm not going to know why that happened!" Happily, there's a solution to that, too: you can set up a custom user style (in your chrome/userContent.css directory) to show a custom icon when you mouse over any mailto link. Shiny!

Tags: , , ,
[ 21:19 Aug 04, 2006    More tech/web | permalink to this entry | ]

Tue, 25 Apr 2006

Firefox for Presentations: Hiding the URLbar

I've long been an advocate of making presentations in HTML rather than using more complex presentation software such as PowerPoint, Open Office Presenter, etc. For one thing, those presentation apps are rather heavyweight for my poor slow laptop. For another, you can put an HTML presentation on the web and everyone can see it right away, without needing to download the whole presentation and fire up extra software to see it.

The problem is that Mozilla's fullscreen mode doesn't give you an easy way to get rid of the URL/navigation bar, so your presentations look like you're showing web pages in a browser. That's fine for some audiences, but in some cases it looks a bit unpolished.

In the old Mozilla suite, I solved the problem by having a separate profile which I used only for presentations, in which I customized my browser to show no urlbar. But having separate profiles means you always have to specify one when you start up, and you can't quickly switch into presentation mode from a running browser. Surely there was a better way.

After some fruitless poking in the source, I decided to ask around on IRC, and Derek Pomery (nemo) came up with a wonderful CSS hack to do it. Just add one line to your chrome/userChrome.css file.

In Firefox:

#toolbar-menubar[moz-collapsed=true] + #nav-bar { display: none !important; }

In Seamonkey:

#main-menubar[moz-collapsed=true] + #nav-bar { display: none !important; }

This uses a nice CSS trick I hadn't seen before, adjacent sibling selectors, to set the visibility of one item based on the state of a sibling which appears earlier in the DOM tree.

(A tip for using the DOM Inspector to find out the names of items in fullscreen mode: since the menus are no longer visible, use Ctrl-Shift-I to bring up the DOM Inspector window. Then File->Inspect a Window and select the main content window, which gets you the chrome of the window, not just the content. Then you can explore the XUL hierarchy.)

This one-line CSS hack turns either Firefox or Seamonkey into an excellent presentation tool. If you haven't tried using HTML for presentations, I encourage you to try it. You may find that it has a lot of advantages over dedicated presentation software.

Addendum: I probably should have mentioned that View->Toolbars->Navigation Controls turns off the toolbar if you just need it for a one-time presentation or can't modify userChrome.css. You have to do it before you flip to fullscreen, of course, since the menus won't be there afterward, and then again when you flip back. I wasn't happy with this solution myself because of the two extra steps required every time, particularly because the steps are awkward since they require using the laptop's trackpad.

Tags: , , ,
[ 17:59 Apr 25, 2006    More tech/web | permalink to this entry | ]

Mon, 10 Oct 2005

How to Search Your Mozilla Cache

Ever want to look for something in your browser cache, but when you go there, it's just a mass of oddly named files and you can't figure out how to find anything?

(Sure, for whole pages you can use the History window, but what if you just want to find an image you saw this morning that isn't there any more?)

Here's a handy trick.

First, change directory to your cache directory (e.g. $HOME/.mozilla/firefox/blahblah/Cache).

Next, list the files of the type you're looking for, in the order in which they were last modified, and save that list to a file. Like this:

% file `ls -1t` | grep JPEG | sed 's/: .*//' > /tmp/foo

In English: ls -t lists in order of modification date, and -1 ensures that the files will be listed one per line. Pass that through grep for the right pattern (do a file * to see what sorts of patterns get spit out), then pass that through sed to get rid of everything but the filename. Save the result to a temporary file.

The temp file now contains the list of cache files of the type you want, ordered with the most recent first. You can now search through them to find what you want. For example, I viewed them with Pho:

pho `cat /tmp/foo`
For images, use whatever image viewer you normally use; if you're looking for text, you can use grep or whatever search you lke. Alternately, you could ls -lt `cat foo` to see what was modified when and cut down your search a bit further, or any other additional paring you need.

Of course, you don't have to use the temp file at all. I could have said simply:

pho `ls -1t` | grep JPEG | sed 's/: .*//'`
Making the temp file is merely for your convenience if you think you might need to do several types of searches before you find what you're looking for.

Tags: , , , , , , ,
[ 22:40 Oct 10, 2005    More tech/web | permalink to this entry | ]

Tue, 04 Oct 2005

Hacking Mozilla Extension Versions

Mozilla Firefox's model has always been to dumb down the basic app to keep it simple, and require everything else to be implemented as separately-installed extensions.

There's a lot to be said for this model, but aside from security (the need to download extensions of questionable parentage from unfamiliar sites) there's another significant down side: every time you upgrade your browser, all your extensions become disabled, and it may be months before they're updated to support the new Firefox version (if indeed they're ever updated).

When you need extensions for basic functionality, like controlling cookies, or basic sanity, like blocking flash, the intervening months of partial functionality can be painful, especially when there's no reason for it (the plug-in API usually hasn't changed, merely the version string).

It turns out it's very easy to tweak your installed plug-ins to run under your current Firefox version.

  1. Locate your profile directory (e.g. $HOME/firefox/blah.blah for Firefox on Linux).
  2. Edit profiledirectory/extensions/*/install.rdf
  3. Search for maxVersion.
  4. Update it to your current version (as shown in the Tools->Extensions dialog).
  5. Restart the browser.

Disclaimer: Obviously, if the Firefox API really has changed in a way that makes it incompatible with your installed extensions, this won't be enough. Your extensions may fail to work, crash your browser, delete all your files, or cause a massive meteorite to strike the earth causing global extinction. Consider this a temporary solution; do check periodically to see if there's a real extension update available.

More information on extension versioning (may be out of date).

Tags: , , ,
[ 19:47 Oct 04, 2005    More tech/web | permalink to this entry | ]

Mon, 27 Jun 2005

Catching Up on Firefox Regressions

I spent a little time this afternoon chasing down a couple of recent Firefox regressions that have been annoying me.

First, the business where, if you type a url into the urlbar and hit alt-Enter (ctrl-Enter in my Kitfox variant) to open a new tab, if you go back to the old tab you still see the new url in the urlbar, which doesn't match the page being displayed there.

That turns out to be bug 227826, which was fixed a week and a half ago. Hooray!

Reading that bug yielded a nice Mozilla tip I hadn't previously known: hitting ESC when focus is in the urlbar will revert the urlbar to what it should be, without needing to Reload.

The other annoyance I wanted to chase down is the new failure of firefox -remote to handle URLs with commas in them (as so many news stories have these days); quoting the url is no help, because it no longer handles quotes either. That means that trying to call a browser from another program such as an IRC client is doomed to fail for any complex url.

That turns out to be a side effect of the check-in for bug 280725, which had something to do with handling non-ASCII URLs on Windows. I've filed bug 298960 to cover the regression.

That leaves only one (much more minor) annoyance: the way the selection color has changed, and quite often seems to give me white text on a dingy mustard yellow background. I think that's because of bug 56314, which apparently makes it choose a background color that's the reverse of the page's background, but which then doesn't seem to choose a contrasting foreground color.

It turns out you can override this if you don't mind specifying a single fixed set of selection colors (instead of having them change with the colors of every page). In userChrome.css (for the urlbar) and userContent.css (for page content):

::-moz-selection {
  background-color: magenta;
  color: white;
}
(obviously, pick any pair of colors which strikes your fancy).

Tags: , , ,
[ 21:45 Jun 27, 2005    More tech/web | permalink to this entry | ]

Mon, 17 Jan 2005

Mozilla tip: highlight links that would open a new window

Investigating some of the disappointing recent regressions in Mozilla (in particular in handling links that would open new windows, bug 278429), I stumbled upon this useful little tidbit from manko, in the old bug 78037:

You can use CSS to make your browser give different highlighting for links that would open in a different window.

Put something like this in your [moz_profile_dir]/chrome/userContent.css:

a[target="_blank"] {
  -moz-outline: 1px dashed invert !important;
  /* links to open in new window */
}

a:hover[target="_blank"] {
  cursor: crosshair; text-decoration: blink;
  color: red; background-color: yellow
  !important
}

a[href^="http://"] {
  -moz-outline: 1px dashed #FFCC00 !important;
  /* links outside from current site */
}

a[href^="http://"][target="_blank"] {
  -moz-outline: 1px dashed #FF0000 !important;
  /* combination */
}

I questioned the use of outlines rather than colors, but then realized why manko uses outlines instead: it's better to preserve the existing colors used by each page, so that link colors go along with the page's background color.

I tried adding a text-decoration: blink; to the a:hover style, but it didn't work. I don't know whether mozilla ignores blink, or if it's being overridden by the line I already had in userContent.css,

blink { text-decoration: none ! important; }
though I doubt that, since that should apply to the blink tag, not blink styles on other tags. In any case, the crosshair cursor should make new-window links sufficiently obvious, and I expect the blinking (even only on hover) would have gotten on my nerves before long.

Incidentally, for any web designers reading this (and who isn't, these days?), links that try to open new browser windows are a longstanding item on usability guru Jakob Neilsen's Top Ten Mistakes in Web Design, and he has a good explanation why. I'm clearly not the only one who hates them.

For a few other mozilla hacks, see my current userChrome.css and userContent.css.

Tags: , , ,
[ 14:03 Jan 17, 2005    More tech/web | permalink to this entry | ]