My Favorite Noteworthy Webmail Feature

I use Noteworthy Webmail all day, every day. Yes I work for Mailtrust. Yes I coded on the Webmail team for a while. But that doesn’t change the fact I love the webmail interface.

Yesterday, I got back to my desk after a meeting and started attacking the 30 emails that had accumulated during that time. After reading through them, the next step was deleting because I use my Inbox like a task list. While doing this, something dawned on me. My favorite webmail feature is the one I don’t think about. It is the one I use every day. Check-Drag.

Check-Drag is the ability to click on a checkbox, hold the mouse button down, and select other checkboxes by dragging the mouse over them. Hopefully the video below illustrates how this works. Using it has become second nature, so the only time I notice it is when I am using a different application that doesn’t support it.

(Either JavaScript is not active or you are using an old version of Adobe Flash Player. Please install the newest Flash Player.)

Webmail still supports shift-click and ctrl-click, but check-drag is just easier to use in my opinion.

As a side note, this is my first screencast Feel free to mock and heckle me. Also, tell me if you think it is stupid, or good. If it could be better, tell me how. I hate watching it because I hate the sound of my voice. At this point in my life, I believe I am ready to take the criticism that my peers might have :)

Safari Textarea bug

Well, I came across another Safari bug dealing with forms today. Unfortunately, I discovered this problem months ago and compeltely forgot it. So I figured I should document the issue so when it arises again, I won’t waste any time searching for the solution.

Basically, like most other issues with forms on IE and Safari, this issue deals with setting values of elements before they are on the document. Before today, I thought that checkboxes and radios in IE were the main problem, but textareas also have issues.

Here is the hack I did to solve the problem:

1
2
3
4
5
6
7
8
9
10
//While populating the form
var form = Element.createHtml('<form><textarea name="some_textarea"/></form>');
form.some_textarea.value =
    form.some_textarea._value = 'Hello world';
 
//When appending the form to the document
document.body.appendChild(form);
 
//Safari fix
form.some_textarea.value = form.some_textarea._value;

If I am feeling chipper, I may even search through WebKit’s huge list of bugs to see if it needs to be reported. Hope this helps someone out there.

Dynamic form issues in IE and Safari

In the world of rich web applications, browser bugs and incompatibilities are the number one killer of productivity, next to YouTube, Facebook, and Myspace. Like most web developers, I have come to realize most of those issues arise from IE and Safari. Today I stumbled upon another interesting problem when trying to implement some dynamic forms.

Take for instance the following code snippet:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//Create form elements
var form1 = Element.create('form', {name: 'test_form'});
var input1 = Element.create('input', {type: 'text'});
var input2 = Element.create('input', {type: 'text', name: 'input2'});
 
//Append inputs to form
form1.appendChild(input1);
form1.appendChild(input2);
 
//Append form to document
document.body.appendChild(form1);
 
//Set input1's name
input1.name = "input1";
 
//Check if form picked up on name change
alert(form1.input1);
alert(form1.input2);

If you aren’t familiar with Prototype, this may be a bit hard to understand, but here is what is going on. I am creating a form with two inputs. Both inputs’ names are set in Javascript, but one is set before the form is appended to the document body, and the other is set after.

This code works fine in Firefox, but IE and Safari fail to note the name change, and don’t add the element’s property to the form element.

I created a workaround for a different Safari issue a few months ago, but it works well for this issue as well. The only requirement is your application must be using Prototype.

1
2
3
4
5
6
7
8
9
    Form.prepare = function(form){
        var elements = Form.getElements(form);
        for(var i=0, ii=elements.length; i++){
            var elm = elements[i];
            if(elm.name &amp;&amp; !form[elm.name]){
                form[elm.name] = elm;
            }
        }
    }

In the above example, this would be called before we wished to access the form elements, alert(form1.input1).

Prototype and speed

Since Mike doesn’t really blog anymore, I figured I would steal his thunder and discuss some of his findings the past week.

For those of you that haven’t used Prototype before, it is a Javascript library which we use fairly heavily at webmail.  It has served us well for a while now …..

But version 1.5 is becoming too slow to be used in webmail. Being a very large web application, we don’t always have the luxury of elegant code, especially in javascript. Sometimes, we just have to do what works fastest and looks the ugliest. This past week Mike made some interesting findings, singling out some of the major performance culprits in Prototype.

Enumerable.each()

We have known this function is slow and have tried to avoid using it, but Prototype itself uses it on some very common functions such as:

  • Element.addClassName()
  • Element.removeClassName()
  • Enumerable.* (Basically all of them use each() somewhere)

Mike overrode the first two functions to use a regular loop instead of each() and saw a 200ms login improvement! That is a pretty large improvement, nearly 14% of the total javascript rendering time on login.

Element.update()

For a long time, I thought Element.update() just abstracted element.innerHTML. I was wrong. It calls stripScripts() and evalScripts(). Since we never pass in text containing script tags, we overwrote this function to just use element.innerHTML. Again, another huge performance enhancement.

Unnecessary abstractions

Prototype has added some great functionality to javascript, but sometimes they take it a little too far with their abstractions. Some functions serve very little purpose other than to add an extra function call.

  • Element.update() – Since we have taken out the stripScripts()/evalScripts(), there is really no reason to use this function
  • Element.setStyle() – As long as you don’t set opacity or float styles, don’t use this function.
  • Element.addClassName() – If you know an element doesn’t have the class name already, just call element.className += ‘ foobar’.

A better web framework – Part 1

As I have mentioned before, design patterns are one of my favorite areas of computer science. Well, design patterns have a close association with web frameworks, so web frameworks are definitely another favorite area of mine. They both help speed up the development process by providing a structure for applications. Since Ruby on Rails took off a couple years ago, other web frameworks have sprung up in many other languages. None of these have met my needs at Webmail.us.

The webmail application I work on is very different than many other Web 2.0 applications, which is why most of the existing frameworks don’t work for us.

  • There are no page refreshes and therefore:
    • Most drawing is done by Javascript
    • All data transfered is JSON encoded
  • Email, Calendar, Tasks, Contacts, Settings are all combined into 1 application which means:
    • Large memory footprint
    • Javascript performance very important
    • On the fly loading of HTML, Javascript, and CSS is a must

For the past few months, I have been thinking about what I really need in a web framework. Just like Rails, an MVC framework would need to be the base. In Part 1, I will just talk about the MVC foundation for this framework.

Model

An ActiveRecord type object would provide the MySQL data abstraction. I have mentioned that I have been working on my own implementation for a while, so I won’t go into too much detail on this. Basically, for a complicated web application, most existing model abstractions don’t work very well. With complicated JOIN’s, WHERE’s, and subquerys, something different must be used.

View

A templating mechanism must exist to have a complete web framework. Current view abstractions won’t work in webmail. Since webmail never refreshes, going to the server every time we need to populate a template is troublesome. The templating mechanism in the better web framework would allow a template to be used in PHP or in Javascript.

If a template is used in Javascript, once it is downloaded once, it wouldn’t have to be downloaded again. The hard part about a Javascript template is the inability to have loops and the need for slow regular expression parsing.

If a template request in Javascript has to make a server request every time a template needs to be populated, speed becomes an issue. This is fine for large templates, but what about small widget templates? Making a server request for a small element increases 1. latency and 2. server load which in turn increases latency even more.

Controller

Controllers are the backbone of a web framework. I like how Rail works with a controller class where each data request is mapped to a function call. This seems effective to me and needs little modification.

Conclusion

I know what you must be thinking: Your MVC design isn’t that much different than Rails. Well, that’s true, but remember this is part 1. The MVC design is just the foundation of a better web framework. Rails is popular because it is useful, so it is definitely a good starting point for developing a new framework.

Shout out to Mike for his work on Javascript templates.