The Deep End

go to! email!

Tuesday, June 07, 2005

Thunderbird: DOMming Around

First, get the DOM Inspector for Thunderbird. Because the DOM Inspector, apparently, was included in Thunderbird for a little while but discontinued, it's a little weird to install, but there are detailed instructions--basically, you just have to delete a few files. There may be a version 0.0.2, but I got 0.0.1 from here and I have no complaints.

After you get the DOM Inspector, everything will be great. Want to get the body of that message, but don't feel like downloading it? Headers starting to bore you? Well, just
get the selected message
var view = GetDBView();
var hdr = view.hdrForFirstSelectedMessage;
then get the Message Pane (that preview window at the bottom, if you have 3-pane Thunderbird)
var messagePane = document.getElementById("messagepane");
and then...get really complicated:
var msgPaneDocChildren = messagePane.contentDocument.childNodes;

var ndHTML = msgPaneDocChildren.item(0);

var ndHead = ndHTML.childNodes.item(0);
var ndBODY = ndHTML.childNodes.item(2);
var ndDIV = ndBODY.childNodes.item(1);

var domBody = "";

//now find the a tags, if any
var htmlPre = ndDIV.childNodes.item(0);
var htmlPreText = htmlPre.childNodes.item(0);
domBody = htmlPreText.nodeValue;
for(var i = 0; i < dombody =" domBody" dombody =" domBody+htmlPre.childNodes.item(i);" nddivtext =" ndDIV.childNodes.item(0);" dombody =" ndDivText.nodeValue;">
ok: messagePane itself is a browser object. You can find it via the DOM Inspector by:
(1) file --> Inspect A Window --> Inbox
(2) Search --> Find Nodes
(3) Search by Tag Name for browser
messagePane has an attribute called contentDocument which will show up in the DOM Inspector as #document (and purple).
Going deeper into the DOM Tree--or DOM Hell; whatever--the childNodes of messagePane.contentDocument will be a single Node whose nodeName (nodeName is a property) is "HTML." As you can see, this is where I got var ndHTML = msgPaneDocChildren.item(0); "Open this up"--ndHTML.childNodes--and you'll get three children this time with nodeNames "HEAD," "#text," and "BODY." As you'll see from the DOM Inspector, #text is basically an empty string. What is represented in the DOM Inspector as "#text" is really a nsIDOMText node. However, since the body of the message is a text node like this, to get the string out of a node that shows up #text in the DOM Inspector, use node.nodeValue.

Ok so anyways, if we're getting the body of the selected message, we want the child of ndHTML called "BODY."
var ndBODY = ndHTML.childNodes.item(2);
Now, child 1 is a text node, but child 2 is a "DIV" element. Open that (var ndDIV = ndBODY.childNodes.item(1);), and things get a little strange again:

You will either have (the easy case) a "#text" node which contains the body--nodeValue that and you're done!

The more difficult case is if you have, instead of a #text node, an HTML Pre Element. In the code above, this would be that large try/catch block. Use QueryInterface to see if the node really is an HTMLPreElement--if not, then it's probably a #text node.

If it is a PRE Element,
var htmlPre = ndDIV.childNodes.item(0);
var htmlPreText = htmlPre.childNodes.item(0);
the childNodes of htmlPre will be, hopefully, some #text nodes and possibly, if there are any links in the email message, some A tags, which you will have to open up and get their #text nodes, depending on how many A tags there are. Basically, use the DOM Inspector to find out which cases you'll have to handle, and just get to the #text nodes. Once you've gotten to a text node, you're done--just use .nodeValue to get the text.

The code above should work. I think I've handled all the cases. The only thing I can think of is if there's another html element in the email message like strong or something--the best way is probably to recurse until you get all the #text nodes.

Hopefully, even if you weren't looking for another way to get the body of an email message, this post will still be useful because it provides a basis for getting anything you can see in Thunderbird--just find the right window, and explore around with the DOM Inspector until you have it.

Want to get the date of a selected message?
function elt_getDate(){
var dateBox = document.getElementById("collapseddateValue");
return dateBox.inputField.value;
&c, &c.


  • At Friday, June 23, 2006 9:49:00 AM, Anonymous Anonymous said…

    Fruitful blog indeed. Thanks for your straightforward solutions your deadpan confessions of confusion about Mozilla extension development. From a non-extension developer, I favor your site.


Post a Comment

<< Home