Wanted at OSCON: Wrapping GNU software into XPCOM

I’m taking next week off to attend the Open Source Convention 2009 in San Jose, CA. It’ll be a chance for me to get back to my cutting-edge (not quite bleeding-edge), unmanaged, free-to-foul-it-all-up-or-to-do-something-original mode.

Or to learn something. Like how to take a bunch of C code and create a XPCOM wrapper for it. I’ve talked about including diffutils as part of Verbosio before. I think I’d like to have someone actually help me do that. Likewise, I started looking at findutils as a possible angle for bug 421029 (file search in XPCOM/NSPR), though I’m not as certain about that.

So if there’s anyone else here attending OSCON (or free the preceding two days) and wants to hunker down for something different in Mozilla hacking, let me know through the comments. I’m also pretty good at writing stuff down, so sheppy & the DevMo crew might get a nice article out of it.

(P.S. Thank you, Gerv, for the discount code. I’m paying for this out of my own pocket.)

Skyfire 1.0 Has Arrived

We did it. We released Skyfire 1.0 this morning.

We’ve got a really great team of people here, and we’ve been pushing very hard to make this happen. For me, it’s particularly nice – this has happened just after I’ve been here two years.

I expected I’d be jumping off the walls in joy when we reached this point. Instead, I find myself with a quiet, professional satisfaction. I’m reminded of a couple lines from Star Trek: Deep Space Nine.

OBRIEN:  You look good in red.
WORF: It feels good.

For the web developer community, a note: We have not forgotten about you. We have some documentation in the works, talking about best practices in supporting Skyfire users. It’s not ready yet, but we’re working on it. Stay tuned!

JavaScript modules for web pages (think Yahoo UI widgets)?

This is just a wild idea I had, and I don’t have time to adequately explore it right now. So I’m throwing it out here to see what you think.

Mozilla Firefox 3.0 introduced several new ideas, including these two:

I love the concept of JavaScript modules (sharing common code) so much, I started thinking: wouldn’t it be nice to provide the same for web pages – a common location to load files that several websites might want available?

Of course, it’s a really bad idea to expose chrome JavaScript to content – scripts that won’t work, at least, and security holes at worst (if you’re considering passing objects from chrome to content, as I’ve been known to do). But that’s not what I have in mind.

Yahoo UI widgets are a library of fairly complex, JavaScript-driven user interface classes. They’re actually pretty useful. However, a site using them must provide bandwidth to download them for every page view that references them. That can add up quickly, which is one reason scripts like it are often minified. With a resource:// URI, you could take it further (no downloads at all, it’s already on the user’s machine!) – but how do you ensure that URI exists?

Build a Firefox add-on.

Imagine an extension’s chrome.manifest like this:

# Library for Yahoo UI widgets
resource library:yahoo-ui res/yahoo-ui

That’s all. Then you’d need a res/yahoo-ui folder in the extension which would hold the Yahoo UI widgets library.

A colleague last night correctly pointed out this doesn’t factor in versioning of Yahoo libraries. Plus, you’d probably need a generic loading library which would look for the resource://library:yahoo-ui/whatever.js file first, and go download the YUI files from the website if it isn’t there.

Another downside is that this really abuses the resource: URI protocol. I’d feel better implementing another protocol that would be more flexible and still web-safe.

On the plus side, the scripts in the library wouldn’t have to be minified anymore. From the perspective of debugging with Venkman, it is a royal pain in the butt to figure out why a YUI widget doesn’t work…

Personally, I’d rather not stop there. I’d rather make whole extensions that were restricted to content – specifying in their install.rdf manifest that they weren’t chrome extensions and that their packages lived in the browser’s sandbox for web pages. You could then specify global objects that would trigger exceptions if they tried to do anything outside what a webpage could do. (I keep thinking XPathGenerator could really have used that, just to assure everyone it was safe for 1.9.1.)
GreaseMonkey makes an attempt at this (a good one). I’m wondering if it’s worth promoting that capability into the main Firefox build.

Anyway, that’s enough white-boarding for the moment. I’m really sorry I don’t have time to delve any deeper, but work plus my own Verbosio project keep me too busy. Comments are open – feel free to tell me I’m crazy or that the Web doesn’t need this.

No Shaving In… April?

All right, folks, I’ve had it. I’ve really, really had it. Bad enough you insist on my fuzzy logic face after a week… but you want me to be scruffy on my birthday? You want me shaggy at Christmas? Forget it! No way. It isn’t going to happen.

Shame on you parents who went No Shaving In December. Your babies don’t need to grow up thinking it’s cool to be Cro-Magnon. It’s because of you that Geico makes all their money: first, you make the Gecko cooler, then you take a whole fifteen minutes to save money on your car insurance. Most people take twelve minutes, tops.

Therefore, I must break my months-long silence and say Nay! There shall not be No Shaving In December! (I love the double negative. Don’t you?) Instead, by decree of a member of the Dogbert’s New Ruling Class, there shall be… No Shaving In April! Let us imitate our Glorious Leader’s furriness at a time when it’s not so cold outside! (Or so hot in Antarctica.) Let us itch baldly where no itch has been scratched before, leading up to the release of Star Trek Eleven: The Search For Shaving Cream!

Continue reading No Shaving In… April?

A Scrollable Grid With Headers, part 1

Recently, I discovered XUL trees will let you select individual
cells with a single attribute, seltype="cell":

treecell-select.png

This gave me a few ideas – most notably about my regular expression grid,
which takes up an awful lot of space on the screen. If I could use the tree
to simulate a smaller grid, preferably with scrollbars, I could use much less
real estate. After a quick newsgroup posting, Mark Finkle and Neil Deakin
set me straight – the grid was probably better and more flexible.

Still, trees do one thing grids don’t – they have a fixed header
row. You can scroll the main body all you want – the header row will stay
where it is. Doing the same for a grid was impossible – but if I combined
three grids into a single XBL binding…

grid-navigable.png

Note this demo won’t fully work without Mozilla Firefox 3.1 beta 2. (It
might work on earlier 3.1 builds, but this was the base.) I combined the
scrollable content object model with a healthy dose of CSS styling and new
bindings. In Firefox 3.0.6, it will partially render, but the headers won’t appear.

This opens up a number of possibilities for new widgets. From the
newsgroup:

  • Menulist editor: Label, value, description
  • Entity localizations: Entity name, English, other language
  • Regular Expression testing grid
  • A menu list containing namespace URI-prefix pairs
  • A spreadsheet with header rows & columns
  • Logic grid puzzles

With all this said, I think I need your help. Although I wrote this as a general-purpose binding, I hardly think it’s ready for adding to the XUL toolkit. This is proof of concept code, and it has a few shortcomings:

  • Navigation by cells – not by rows or by columns. (Suppose you want to select a whole row? I didn’t implement that.)
  • No specification. No rules on how it’s supposed to behave other than, “Does it look right when I move it?”
  • No tests. I wouldn’t want to check this into Mozilla without some regression tests to make sure it works.
  • Performance. In loading the test page, I noticed today that my more recent changes causes the CPU to spike for a couple seconds. That’s bad, and I don’t know where the bug is.
  • The accessibility people will probably want to add some useful support roles.
  • Selecting a cell throws off the header rows’ & columns’ scrolling.
  • A really bad binding name: gridbox. It was the best I could come up with.

I filed bug 477446 for this. I’d like to see if anyone’s interested in working on this binding, cleaning it up, writing tests for it, and generally making it Toolkit-ready. I think it’s potentially very useful.

Comments are open!

I have a scrollable content object model… too late

Several years ago, I griped (unsuccessfully) about the need for a scrollable content object model. I remember someone mentioning on planet.mozilla.org that this would not be a problem going forward, but I couldn’t find the entry. So today, I was exploring another user-interface concept, and it led me back again to scrollable content. (As you read this, my context is the XULRunner 1.9.0.x code base.)

Ahh, I remember the frustrations well. It took me several hours (and a few blind alleys), but I actually hit on a really simple way to tell where a XUL box with scrollbars has scrolled to. Though the XUL box itself has to use my particular XBL binding and CSS styling, it’s still a nice starting point.

Here’s the binding, stylesheet, and a demonstration all in one. Note that it’s a lot cleaner than my previous attempt, and it works.

I realize the scrollX and scrollY properties are read-only. I don’t see a way around that for this approach. If you really want it, you’ll probably have to implement a native-code, C++-based component.

Or, you could wait for Firefox 3.1 / XULRunner 1.9.1, which now has scrollLeft and scrollTop for all DOM elements – and it’s settable there, too. (This makes the third big improvement I’m looking for in XR 1.9.1 that isn’t in 1.9.0.x, which means it’s time to seriously think about moving forward… The other two are new drag and drop features, and a DOM Range fix I pulled in from very early in the 1.9.1 cycle.)

Note I groaned very audibly when I was writing this article and decided to check what 1.9.1 has. Talk about a feeling of a wasted day!

Twenty minutes a day

Sometimes, that’s all it really takes, when you’re hacking code. You know how I know? I tried it last week without even intending to.

In my case, I commute from San Jose to Mountain View every day. On the CalTrain, that takes twenty minutes. I also commute back on the CalTrain – another twenty minutes. That’s enough time to pick up where I left off, fix a little bug in my code, rerun the test, try to fix another little bug, and power down the laptop. I’m just fixing bugs at the lowest level of complexity – one component, one interface, one test case. For a twenty-minute session, that’s about all I need to think about debugging.

Now, of course, I spend a lot more than twenty minutes a day working on projects for the office. I’m also (I hope!) more efficient with my time at work – I can juggle a lot more files in my head at the same time when I have more time. For the really small stuff, you can achieve a lot in twenty minutes a day.

One other benefit, and I believe I’ve said this before: When you’re working with test cases, those test cases later become examples you can reuse in your actual production code. More importantly, they should produce code you can cut-and-paste into your real program, with only variable name changes. That greatly increases the chances your code will work as you intend it to – if you test code one way and it passes, use that way to implement your real work. (Or, just write your test to emulate how you’d really use your component.)

JavaScript components should avoid nsIPropertyBag like the plague

I’ve been bitten by this a dozen times over the years. I try to find a simple data interface for getting a bunch of strings out, and I see nsIPropertyBag. I think to myself, “Hmm. That’s a pretty good choice.” Then I implement it, watch it QueryInterface for my component, and then watch it not call my getProperty() method. Why? XPConnect returns its own nsIPropertyBag object first when I try to call getProperty(). So my call goes to a different object than the one I intended.

I never, ever learn.

Arrays of strings in XPCOM

In my XPCOM Cheat Sheet (which I really should look at updating), I wrote:

As a rule of thumb, use XPIDL-based arrays for arrays of a single
primitive type, in or out (not inout). For anything else, use nsIArray or
nsIMutableArray.

Unfortunately, that doesn’t work with native string types like DOMString:

interface nsIFooArray : nsISupports
{
void setArray(in PRUint32 count,
[array, size_is(count)]
in DOMString strings);
};
Error: [domstring], [utf8string], [cstring], [astring] types cannot be used in array parameters

To which I say, “Well, that sucks.” Read on in the extended entry for more details.

Continue reading Arrays of strings in XPCOM

Alex Vincent's ramblings about Mozilla technology, authoring, and whatever he feels like.