The Lurker

Latest posts | Archive

posted by ajf on 2002-09-24 at 04:45 am

This Mozilla screenshot is funny. Getting the content area down to about 15% of the browser window is quite an achievement.

Yesterday I managed to create a XUL template which actually generated content. (Practically all my past efforts have resulted in tree widgets with no content, and for some reason XUL template errors are sent to the logger — which is disabled in non-debug Mozilla builds, and therefore unavailable to normal content developers — rather than somewhere useful, like the Javascript console.) I noticed there was a full moon last night, though, so it probably won't work next week.

Anyway, a few notes to myself in case I ever want to try this again:

I was looking for a way to make the cookie permission dialog come up a bit faster. I have a little over 1500 domains listed in cookperm.txt (because I habitually deny cookies to every site I visit, unless it turns out they're needed), and it takes several seconds of heavy CPU use between clicking the menu item to open the window and having it actually appear. Unfortunately it turned out that most of the time was spent iterating through the nsIPermissionManager's list of permissions. I also hoped to be able to display the window before the permissions were loaded, and to display a progress meter while you wait, but the permission manager doesn't expose the number of permissions that exist, throwing that idea out the window (and I don't think it would update the display until loading was completed anyway).

I was also surprised when I noticed that the code which checks for a stored permission runs through that entire permission list linearly for each cookie check. It's getting late, so I may have read the code wrong, but I think it does that multiple times (for host.blah.example.com, then blah.example.com, and so on) for each cookie. Maybe they didn't expect cookie blacklists to get too long, or maybe with today's CPU speeds a naive algorithm is good enough.

Anyway, back to RDF. Since I had a reasonably large pile of data, I thought it would be useful to finally try to get my head around XUL templates. Mozilla's cookie manager doesn't use XUL templates — it provides an implementation of nsITreeView instead, which I'll get back to in a minute. Mozilla is pretty easy to develop for — in just a few lines of code I could run through the permission manager's enumerator and create an in-memory RDF datasource from it. After a few false starts, and with the help of the W3C's RDF Validator to get my head around what RDF looks like again, I managed to populate a XUL tree with permissions. Of course, this was no better than Mozilla's existing cookie permission dialog, but I was pretty pleased to have finally got a XUL template to work.

I mentioned earlier that occasionally I deny cookies to a site, then discover that the site does not function without cookies. (In the worst cases, some sites check for cookie support by setting a cookie and redirecting to the same page — causing an infinite redirection loop if the browser rejects cookies.) The Cookie Manager menu includes a "Unblock cookies from this site" item, but it only unblocks the domain the page was served from (which may not be the exact same domain the denied cookie was intended for). In these cases, I need to go to the cookie manager dialog and find the other domains. Unfortunately the domains are displayed in alphabetical order, so www.example.com and example.com aren't really that close to each other.

So the feature I really wanted to implement, the reason I got started on this in the first place, is a simple filter (that is, a text box that says "only show domains matching this string"). To do this with a template, I needed to have an assertion in the datasource on all permissions which matched the filter. Unfortunately, my RDF implementation (which added and removed a hell of a lot of assertions when the filter string is changed) was terribly slow. Perhaps it would have been more efficient to generate the filter assertions on-the-fly rather than adding them to the in-memory datasource, but that looked like a lot more work than going back to the nsITreeView implementation.

Adding the filter to the tree view took perhaps twenty lines of code and less than an hour; the RDF implementation would have taken much longer, required considerably more code, and been more error-prone. And the filter now works almost instantaneously.

(Another undocumented quirk I discovered reading the source: when calling the tree object model's rowCountChanged() method, the count value is positive when notifying the tree that rows have been added, and negative when rows have been deleted.)

So after spending about a day and a half playing with the code, I successfully created a XUL template, I proved to myself that a feature I find useful was easy to implement, and I found myself left with a desire to rewrite the permission manager service from scratch. Two out of three ain't bad.

Related topics: Web

All timestamps are Melbourne time.