JavaScript and Dates #

Heh, looks like I'm spending more time on the project than any of my other ones, and technically it's not even a programming class one (it's for InfoTech). But I guess this is mainly because it's something I use myself (the whole checking mail through a proxy/at school thing), so if it's an unstable/unusable state I feel it immediately. I've also noticed that the closer I get to making Grendel similar to the Netscape mail client, the less reluctant I get to download the mail locally and read it there. The current situation is that I read about half of my mail with Grendel, and then when I download I quickly page through it since I've seen it before. When I add the MIME parsing (for things like HTML mail and attachments) it'll prolly be even more tempting. However, even if I were to add things like local message storage (as in, getting the mail from the POP server and storing it somewhere in the cgi-bin directory) with message filtering, etc. I'm not so sure I want to use it as my primary email client. The perfect situation would be if the Netscape mail reader were to observe that certain messages were already marked as read on the server, so it shouldn't flag them as being new when downloading them.

The main thing that I've done with Grendel was do implement the hybrid JavaScript/Perl system. When getting the messages from the server, the script generates a JavaScript which creates new JavaScript objects like this:

print <<EOF
messages[$messageNo] = new Message($messageNo,

which results in JavaScript code like this:

messages[2] = new Message(2,
                          "Re: 10,000 Triangles, 18 msec",
                          "", "Herv� BERRIOT",
                          "Sun, 12 Dec 1999 04:56:36 GMT-0800");

Then I have a local (on the user's side) array of JavaScript objects (the Message object is defined by me, JavaScript is object oriented, and close enough to C++ that learning it isn't very hard) which store all the messages (well, not quite, I don't have the message body too, that's only requested when the user asks for a message to read). To display them, I simply loop over them and call their Display method. The idea here is that if I want to change the sorting method (not implemented yet, but soon will be, after I learn how QuickSort works), I can do all of it locally, instead of having to go through the server. Things like deleting messages are faster too. Instead of having to get the new message list from the server, I can delete the specified array memeber locally, and then tell the server which messages has been deleted, and update the message view page with the next one.

I wasn't quite sure where to store all these JavaScript objects. I couldn't put them in the list frame, since that gets cleared when refreshing the message list. At first I thought I should put them in an invisible frame, and the things like rechecking the mail would simply reload that list. The main problem was that the invisible frame wasn't quite so invisible, since the border would still show. Then, when I was making a simple change and saving it to the server, the FTP process screwed up, and the local app crashed (this was on a PC). The end result was that the copy on the server was completely empty, and I had no loal copy (the text editor I was using supported direct save to FTP). The good thing was that I had saved a backup copy before doing the hybrid system, so I got to start again. This time I decided that I should store the objects in the buttons frame, since it didn't get reloaded or cleared.

The other big thing I did this week was to add parsing of the message timestamps. Now they are converted to the local user's time, whatever it might be. This is done with JavaScript, since it has a built-in date string parsing function (whereas Perl requires a third-party module, and I want Grendel to be as self-contained as possible), and Perl wouldn't have been able to do the automatic local time conversion anyway, since it's executed on the server. In the end, things worked pretty well, I added special cases for dates that were on the same day as today, the day before, and within the past week. My main problem now is that Netscape and Internet Explorer seem to behave differently when handling dates, that is Netscape seems to shift everything back by one (since I first implemented this at school, where I use IE, I'm assuming that Netscape is wrong). I'm not quite sure, the simple fix would be of course to add a an if statement to increase the date by one if netscape is detected, but I was hoping for a universal script, especially since JavaScript is supposed to be standardized.

I have a few of simpler things planned for Grendel, before I decide if I want to implement the local message storage or move on to something else. First of all, I want to add cookie support, so that it can remember the login/password combo for me at home. To edit that setting, I'll have to add a user settings page, where users can also change their POP server, password, etc. On the topic of passwords, Grendel as a whole isn't very secure yet. If someone were to go through the history at school and get the address for my message list, they could access it (my username and password (in a mangled form so that it's not immediately readable) are in the address string). Right now I'm thinking of using temporary cookies (which expire when the user quits the browser) to set when the user logs in, and the username/password validation would also check for the presence of those cookies. Another thing which I want to add is automatic mail checking. I can see how I could use a small toolbar/scrollbar/statusbar-less window which refreshes itself automatically every minute (or whatever the user prefers) and checks to see if there's new mail. If there is, it can play a sound, bring up an alert, or just start flashing, and when the user clicks on it grendel is brought to the foreground or started up if not alreay there. There's also the MIME parsing that I mentioned earlier, ideally with in-line viewing for images or things which the browser has plug-ins for. Finally, I want to add another column to the message view listing the message size, but so far that doesn't seem to be in the headers, and I don't want to download a whole message just to get its size, so I'll have to see about that.

Post a Comment