Some of the worst code I’ve had the misfortune of touching in the Mozilla codebase is code related to the handling of prompts. Specifically, the prompts involved with following interfaces: nsIPromptService, nsIAuthPrompt, nsIPromptFactory, nsIAuthPromptProvider, nsIPromptService2, nsIAuthPromptAdapterFactory.idl, etc. Just the plethora of confusing interfaces (for what is a fairly basic feature) is the first sign that something is amiss, and if you look at the actual methods on these interfaces you’ll quickly become lost in a maze of twisty little passages, all alike.
0) We begin our adventure in nsGlobalWindow::Alert().
1) Obtain an nsIPrompt via a do_GetInterface call on the docshell.
2) Ah, docshell doesn’t implement any of that, it just delegates to an nsIPrompt that it obtains from nsIWindowWatcher’s GetNewPrompter().
3) But GetNewPrompter() is actually just a one line function that calls NS_NewPrompter().
4) That’s over in nsPrompt.cpp, a short function that creates a
new nsPrompt and initializes it.
5) Ok, now that we have an nsIPrompt (back from step 1), we can set up some strings and call its Alert() method.
6) …which doesn’t actually do anything, except to hand-off to nsIPromptService’s Alert().
7) This Alert() does some basic string twiddling, and next we end up in…
8) DoDialog(), which does more more twiddling, and FINALLY calls…
9) nsIWindowWatcher’s OpenWindow(), which opens a XUL window containing commonDialog.xul to do the prompt.
This is a little silly. And for outright insane, try tracing through the sequence of functions performed for showing an HTTP authentication prompt.
The good news is that I’ve been working on a large patch to simplify all this, and pave the way for some other interesting changes. More on this next time. 🙂