First mockups and todosOverlay

June 30th, 2009

The first two iterations of the management interface have been uploaded to the project homepage: todoso.org

This is the page that users will be facing once they are logged in: their most recent presentations are displayed and a search-box allows to search for other documents just like in gmail. It will be possible to filter the documents by tag, date or title. For example the query

date last month

will display all documents that have been created during the previous month. I’m going to try to leverage Ubiquity’s fantastic natural language parser in this project and I hope to make this omnipotent search-box a first class citizen of the interface of the whole application.

When selecting a presentation, different icons appear for different actions that are yet to be determined (I was thinking about play, share, tag and use as a starting point for a new document).

I’ve also started to use the css framework oocss from stubornella. This is a really easy way to make a first step into the world of css frameworks and the focus on performance of this project doesn’t let you any reason not to try it.

Finally, facing the lack of an elegant and light-weight image overlay solution (commonly known as lightbox), I’ve started my own which is really simple but not yet really flexible: todosOverlay. It’s simplicity is a direct consequence of the exclusion of IE6. I’m pretty sure we could enter into a virtuous cycle with this browser:

The less support we provide, the more users are facing broken Web sites, the more likely they are to figure out that their is something wrong, and they’ll be in turn more eager to switch to a better browser, the less we’ll need to care about providing support!

So, what is great about this “yet another overlay plugin”?

  1. it requires only four files:
  2. which have altogether a really small file size
  3. it looks beautiful in the latest versions of Firefox, Safari and Chrome thanks to the border-radius and box-shadow CSS3 properties, it looks Ok in Opera, IE7 and IE8.
  4. just like the rest of this project, it is Free Software and all the SVG sources are included. Therefore you can really adapt it to suit your needs and desires (changing the color of the close image for example).

What might not please you in its current state:

  1. the overlay doesn’t scroll with the page,
  2. the overlay has a fixed size and the inner image is scaled,
  3. you cannot add text to the overlay,
  4. you cannot switch to the next/previous directly from the overlay like you can do with jQuery lightBox
  5. there can be only one overlay at a time on the page

How does that work?

// The plugins has to be set on thumbnail container
$("#myThumbnailContainer").todosOverlay();

It is currently possible to change the size of the overlay (its width, the height is calculated according to the thumbnail dimensions) and to change the regex used to find the full size image based on the thumbnail’s url. If the thumbnail is:

http://www.example.com/images_200px/myImage.png

and the full size image is:

http://www.example.com/images_500px/myImage.png

you can use the following options:

$("#myThumbnailContainer").todosOverlay({
width: 500,
regex: /_200px/,
replace: "_500px"
});

By default the plugin will search for any “_thumbnail”, “thumbnail_” or “_thumbnail_” string in the url and remove it.

By the way, I tried to use picasa as a CDN for the pictures on this site, and it turns out that it is not possible. For some reasons, the pictures sometime refuse to load: the address is correct, the thumbnail even appears in firebug but the load event never triggers… I just gave up. If you want to give it a try, the options for picasa are:

{
regex: /\/s\d+\//,
replace: "/"
}

Announcing ToDoSo

June 27th, 2009

This project has officialy a new name and a Web page: ToDoSo.org (I know, it’s a shame not to use @font-face, SVG and other wonderful modern Web technologies).

You can expect to see the first mockups of the user interface on this page in the next few days. I’m going to post about it of course.

Next Wednesday (1st of July) I’m going back to France for one week of holiday, I hope to find a nicer weather over there. Otherwise I’ll go to Spain!

Specification of the project

June 23rd, 2009

Finally, here they are! The .pdf version of the specification is already available while a link to the .lyx source will be provided soon.

It took longer than I thought but I’m proud of the result. This is a rather long document (3300 words) so I’m only going to reproduce the conclusion on this blog and hope it will pique your curiosity:

The previous state of the art allows to pinpoint three characteristics of existing presentation software:

  1. they are now very rich applications, allowing for the production of highly customizable and visually appealing documents in which multimedia assets can be embedded. The Web enabled a further leap in feature richness, offering a better availability of documents, new possibilities of collaboration and distribution.
  2. if most of them have significant original features that differentiates them from their competitors, there are only slight variations in their GUI that has evolved only minimally over a ten year period.
  3. there are no presentations on the Web that are able to both reproduce their information as a whole through assistive technologies and allow the navigation of slides with a keyboard.

From these observations it it possible to infer three directions for an innovative and valuable presentation software as a Web application:

  1. Trying to compete in term of feature richness with existing solutions is not a reasonable aim for a single developer. In fact, this project could not be completed without the help of external contributors. The first aim of this project will be to encourage individuals to participate in this project and mainly in its implementation phase.
  2. All presentation software use a GUI that is described as an Overview+Detail interface by Andy Cockburn. But other concepts of GUI such as Zooming and Focus+Context are to be found on the Web (Cockburn 2008). The second aim of this project is to assess alternative concepts of interface for presentation software. The ideal would be to build an interface that would give a strong identity to the application and be more intuitive than the traditional one.
  3. It appears that there is a large space for improvement in the accessibility of presentations on the Web. The third objective of this project will be to allow authors to produce accessible presentations with an application that has a graphical user interface.

There is also an interesting part about the nature of information in presentations illustrated by the following document:

A special thank goes to Sébastien Delorme from tentatives-accessibles.eu [fr] for his precious help on the accessibility evaluation of current solutions.

The next steps are the analysis and design of the application. I’ve already posted about solutions for vector graphics in the browser but I should post about the rationals behind my technological choice (Open Web of course) and about my first ideas for the Graphical User Interface. The next weeks are definitely going to be busy!

The state of cross-browser vector graphics

June 17th, 2009

Vector graphics have for long been the preserve of Flash on the Web as browser vendors never agreed on “one standard to rule them all”. But intrepid newcomers relying on browsers’ native features might well change this situation…

A bit of History

Microsoft first proposed their own standard to the w3c, VML, which was later merged with Adobe’s PGML to give birth to the SVG recommendation.

However, Microsoft chose to support vector graphics in their browser before the corresponding working group of the w3c had a chance to publish their first recommendation: VML was implemented in IE5, released in March 1999 while SVG1.0 was only published as a recommendation two years and a half later in September 2001. On the other hand, partial support of SVG was not to be found before Firefox1.5, released in 2005.

Even though VML was the first technology of its kind to be natively supported in a browser and although this browser could have taken pride of its monopolistic usage share for several years (above 90% between 2001 and 2005 according to different sources), it remains unclear why this technology never really took off… On the contrary, the fate of SVG, never supported by the dominant browser is much easier to understand.

A bit of Technic

From a Web developer perspective, it is arguable that the main advantage of VML lies in its deep integration in HTML:  it is possible to nest HTML elements in VML ones and vice versa. SVG was meant to be an independent specification, the result is that it has to be used in a specific namespace in HTML documents, and HTML can only be used in SVG when nested in a <foreignObject>, an element poorly supported in the earliest implementations.

However, SVG reveal all its power when it comes to transformations: rotations, translations, skewing and other scaling can be nested in any ways where different attributes, filters and computations have to be used in VML.

A bit of hope…

Meanwhile, Adobe’s claim of a 99% browser penetration of its proprietary but nonetheless fully vector based Flash technology obviously succeed to seduce a significantly larger number of developers. Nevertheless, two projects saw the light of day with the promise of providing a cross-browser vector graphic API relying on an abstraction layer above VML and SVG:

  • Dojox.gfx, an integral part of the dojo toolkit specialized in 2d graphics. Its main advantage is that it does provide “one API to rule them all“: its set of shapes, paths and transformations can be rendered either to VML, SVG, canvas (the scriptable raster graphic element of HTML5) or Silverlight (details follow). It is shipped with helpers to make elements movable and to render vector fonts, although its supposed negative impact on performance makes it only suitable for a limited amount of text (see the Caveats section of the page).
  • Raphael, a library agnostic (i.e. autonomous) library which offers a clean API mimicking jQuery’s one. It provides the same basic features as dojox.gfx together with animation, color manipulation, event handling, and vector fonts (as of version 0.8) right out of the box (animation and color manipulation are integrated in other parts of the dojo toolkit).

Both libraries can be used in a similar way: first, the area where the drawing will be possible is defined. In Raphael it is called the paper, in dojo.gfx it is the surface. The function that build this area returns a reference not on the physical DOM element that has just been created but on a more abstract JavaScript object that offers methods independent of the browser. The following kind of code is always to be found at the beginning of a script using on of those library:

var area = createArea( positionOrParentElement, dimensions);

Using this reference, any shape or path can be created, once again those functions return an abstract reference on the created shape:

var rectangle = area.createRect( position, dimensions);

And this reference can in turn be used to dynamically modify the attributes of the element, to animate it or to delete it:

rectangle.setAttribute("fill", "red");

This kind of code should look familiar for any developer used to JavaScript libraries such as jQuery, prototype and of course dojo. There is however an important difference: in the latter libraries, it is possible to find an existing element in the DOM and use it to build an abstract object:

var existingElement = library.domQuery("#myDiv");
existingElement.animate({'opacity': 0.5});

Using vector graphics, this abstract object is only created when the associated physical element is inserted in the DOM. The reference that is returned must be conserved as long as the element needs to be modified. This fact turns out to be important when doing event delegation. With a traditional library, modifying the opacity of all list-items of a list on mouse click could be achieved with the following code.

// A function will be executed every time the user clicks on the list
library.domQuery("#myList").onClick(function(event) {

// The event object references the physical element that has been clicked
var physicalListItem = event.target;

// The library can build an abstract object from this existing element
var abstractListItem = library.abstract(physicalListItem);

// This object can then be used to modify the properties of this element no matter the browser
abstractListItem.animate({'opacity': 0.5});
});

Unfortunately there is no such thing as

vectorLibrary.abstract(physicalShape);

But this can be easily circumnavigated by keeping a record of all abstract object associated in hash table with the id of the element:

var abstractRect = area.createRect( position, dimension );
// Make sure the shape has an id
abstractRect.setAttribute(id, "myId");
// Store this reference associated with the id
var hash = { "myId": abstractRect };

area.onClick(function(event) {

// Event gives access to the id of the clicked shape
var shapeId = event.target.id;

// Which can in turn be used to recover the abstract shape
var abstractShape = hash[shapeId];
});

The impact of such hash map on memory footprint is discussed in the paragraph about performances.

… and delusion

With the release of the 8th version of its Internet Explorer, Microsoft dealt VML a severe blow: several features appear to be broken, the most serious one being the possibility to use percentage units… What are vector graphics when the drawing cannot scale? It remains unclear whether those issues have been introduced unintentionally, what is certain is that it will help Microsoft to impose its new technology with vector graphics possibilities: Silverlight, a concurrent to Adobe’s Flash/Flex/Air Framwork also relying on a multi-browser plugin.

This inexplicable coincidence  leaves unfortunately only few hope for an happy ending to the epic battle of native vector graphics.

State of the art

Nevertheless, the baby should not be thrown out when Microsoft siphon off the bath water. It remains possible to use vector graphics in the browser as IE8 can be turned in compatibility mode to act just like the good ol’ IE7 used to. The two aforementioned vector graphic libraries still have to be compared… So be it:

Features

In terms of feature richness, the advantage seems to be for dojox.gfx: As far as as shapes, paths and transformations are concerned, the two APIs are equivalent. Both libraries offer animations, color manipulations and event handling, although this is lies in a lower level part of dojo. However, the alternative technologies that dojo can use to render the graphics might give it a real benefit: Silverlight makes it a more future proof solution and canvas even allows a server-side rendering into raster graphics. Moreover, Raphael does not allow to use other units than pixels, this one being hard coded in the library.

File size

In term of file size however, analyzing the loading process of the two solutions with Firebug yields a size of approximately 22kB for Raphael (once minified and Gziped) and a cumulative 40kB for dojo (when loaded from AOL’s CDN). In one single file, Raphael ships all its utilities and both SVG and VML rendering code, whereas the utilities of dojox.gfx adopt a lazy loading approach with its utilities spread throughout inter-dependent files and a single rendering code being loaded according to the browser capabilities. Even with lazy loading, dojo is almost twice as big… This can be an important criteria for developers who do not intend to use the full capabilities of dojo or who have chosen another JavaScript toolkit. In the latter case, it can be noted that even Raphael will be duplicating some features commonly found in JavaScript libraries: animations, color manipulation and event handling.

Performances

In order to evaluate the impact of storing all references on abstract shapes, two tests were built: a thousand rectangles were created in a page and then in one case all the references were kept in a table to change the color of the rectangles, whereas in the other case no references were kept. It appears that storing the references has a negligible impact on memory footprint in Firefox3. However, in Internet Explorer 8, it turned out that Raphael systematically caused the browser to freeze. The test would complete only when it was limited to 500 shapes, but after 30 seconds of delay. The profiler shipped with IE8 revealed that the lag was mostly caused by the internal setBox method of Raphael that is specific to the VML code.

It should also be noted that Raphael does not offer event handling at the paper level. Event delegation is thus impossible when the library is used in standalone despite the benefit of this method on performances (even listeners are set only once on a container instead of being set for each elements).

Documentation

Last but not least, the quality of the documentation can in many cases tip the scales.

Raphael offers a documentation of its API which includes useful code snippets, however some utilities for color manipulation such as Raphael.hsb2rgb(), Raphael.rgb2hsb() or Raphael.getRGB() are not yet documented. On the projects’ home page, numerous visually appealing and inspiring examples can be found such as a dynamic graph, a start point for a mind map and a demo of the vector fonts. It can be argued that an example with detailed code comments is lacking.

Dojo offers a complete and up to date reference of its API where the documentation of dojox.gfx can be found. However, developer not familiar with the dojo toolkit should read Dojo, Now With Drawing Tools to get started. This article also provide more advanced examples with appropriate comments.

Choice is yours

Dojox.gfx is a natural choice for any developers working with dojo while Raphael is more suitable as a standalone library thanks to its smaller file size. When a large number of shapes have to be created at once, the performances of Raphael should however be evaluated in Internet Explorer. The ability of dojox.gfx to render graphics using Silverlight or canvas can prove to be useful in some case.

For developers already using a JavaScript library other than dojo, it should be noted that in both cases, there will be some code redundancy. Moreover, if performances are critical, the file size of dojo and the problem of Raphael might even prevent to choose any of those…

Project Renaissance: about OpenOffice.org and usability

June 6th, 2009

I’m still working on formal specification for my project but I can post about interesting things I’ve discovered along the way: Project Renaissance.

In brief, project Renaissance aims at improving the user experience with OpenOffice.org products, which is well summarized by the project’s motto:

“Create a User Interface so that OpenOffice.org becomes the users’ choice not only out of need, but also out of desire”

From my point of view it seems like a good start! Even though the project’s homepage show already some flows, such as the Project Charter being spread across different pages when one would have been much more effective… Let’s not be picky and see what is going on:

The first phases of the project consist of surveys to better understand the needs and desires of the users and involving the community with a call for mockups for the future Impress (which is an application that appears to be important for users and where there is obviously a lot of space for improvements). Those mockups can be reviewed in slides 21 to 34 of this presentation. I don’t really like any of them : / But remember that they are only ideas of interested contributors, they are just personal contributions to a greater goal: making Impress better for everyone.

There is also a Blog for this project that gives a better idea of the progress being made. It is just a shame that it gets so little visibility… or is it just an impression? Anyway, the first benefits of renaissance are expected to make their way into OpenOffice.org’s products for the version 3.2 which is expected… when it is ready probably. I’ll be happy to see what this great project come up with, I’m sure that my application will be very different but only the future will tell which approach is the best.

At the same time I discovered about another interesting and Open project: Interaction-Design.org and particularily its encyclopaedia available under a Creative Commons ShareAlike license. The quality of the content seems satisfying, I’m sure everybody could learn something. In the article about Mockups, I really liked the following idea:

“Mock-ups incite criticism from users because they are low-cost (can be made of cardboard) and low-fidelity. If a user is presented with an early version of a system that has required substantial work, he/she is likely to be more reluctant (as well as able) to criticize it.”

I’m personnaly always trying to create visually appealing mockups because I am afraid that the very first impression might have a bad influence on the user’s general opinion. My perfectionism is once again playing a trick on me…

Teesside’s summer of code

May 27th, 2009

I’m now done with all the projects of my different modules and I’m expecting the pass mark in all of them (and hopefully more than that in some of them).
Starting this week I’m going to be working on my Master’s project: a project that is not only the masterpiece of this year, but that is also going to be the only worthy project of my portfolio when searching for a job next year. This project is of a paramount importance for myself but I also want to make it valuable for more people than only me.

Creating a leading office application

As a strong supporter of Free Software, I always thought that the most important entrance barrier to GNU/Linux was it’s office suite. How many people do you know that prefer OpenOffice.org over Microsoft Office? To reach a larger audience (and it deserves to), Linux doesn’t need “acceptable alternatives considering that it’s free”. Open Source and Free software need to lead, following the great success of Firefox and other software that the FOSS community can be proud of: Songbird, Inkscape, Aptana, Azureus, Miro, VLC, Pidgin, name your favorite.

I also know that the best way to have people migrating to GNU/Linux is to bring to their current Operating System great applications which, added to one another, will create a familiar digital environment that would be possible to find on any other OS. I believe that the Web now is not only a valid platform to build applications, but that it is also the best one for cross-platform applications and the best one to bring innovations that can really benefit to the users.

Using the Web as a vector of innovation

I could have started to build the online word-processor of my dreams but last year, on the occasion of my final year project, I have been asked to work on a presentation tool à la Microsoft PowerPoint. It was a great opportunity for me to gain a deep understanding of the Web technologies and standards and of the user interfaces of such applications. The purpose of this first project was to create an online alternative to Microsoft PowerPoint but their haven’t been any notable work on innovations, in short, the final product was an “acceptable alternative considering that it has been developed by undergraduate students”, which  is not acceptable from an end-user point of view (for example it lacked an undo/redo feature). When I first discovered 280slides I was really disappointed: it was exactly what we were aiming for, but usable. The only advantage of our application was the possibility to add animations to the slides but that was so poorly integrated in the whole application that it was almost useless.

Fortunately, during this year of master I have been able to mature the idea of this application, to discover new Web technologies (canvas and SVG) and to strengthen my skills. I feel now ready to give it a second try.

Where to start?

My first task will be to write the specifications of this application. I have to explain why there is a need for an online presentation application (my aforementioned commitment to Free Software explains my personal motivation for this project, but it doesn’t make it a valid piece of research). To this end I am going to evaluate the current solutions that have a common purpose (from PowerPoint to JessyInk, without forgetting about 280slides or Google Document) and I am going to present the “contribution to the body of knowledge”: what innovations will this application introduce as well as the expected findings that should come out along the process of creation.

I am going to blog as often as possible about the progress of this project since I need to keep a written track of my progress (to help me for the 12 000 words report) and to try to attract some people’s attention because I NEED feedback from potential users at all stages of the development. I am already searching for a name for this application. I own the domain slide.me, but I am a little bit worried about its potential suggestive meaning. What would you suggest?

Back from Morocco

May 2nd, 2009

This is the first serie of the pictures from our April trip to Morocco. I’m a bit lazy and I have a lot of work these days, so I’m posting the only few that are already worth looking at.

I know, I still have some progress to do on colour balancing, but my crappy reddish screen doesn’t help…

And the bonus:

Creative Commons License
Morocco by lrbabe is licensed under a Creative Commons Attribution-Share Alike 2.0 France License.
Based on a work at www.lrbabe.com.
Permissions beyond the scope of this license may be available at public@lrbabe.com.

Unit testing with QUnit

April 23rd, 2009

What does reliability means for a computer program?
It means that it has to behave exactly as its designers expect it to.
One way to achieve it is to test every part of the program with a given input, against the expected results. Those tests should be automated and run regularly during the development process to make sure that no regression is introduced (what works today doesn’t break tomorrow). The rule is to break down the program into simple units and test them separately in order to identify precisely the source of a problem.
This technique is called unit testing and most languages are offering a framework to write, run and produce a visual feedback for the test (green for pass and red for fail).

Consider a function myCamelCase( sentence ) designed to turn any given string into my very own kind of camel case word. To make sure that this function is reliable, we need to be able to assert that, for each potential type of input string, its actual output will match the expected result:

input string expected output
“word” “Word”
“WORD” “Word”
“two words” “TwoWords”
“A single letter” “aSingleLetter”
“this is a letter” “ThisIsAletter”
“remove+special_chars!” “RemoveSpecialChars”
“save 123 numbers” “Save123numbers”
“+ trim me _” “TrimMe”
” + _ ! “ false

Using QUnit

The unit test framework of choice for a jQuery related piece of code is QUnit. It offers a reduced number of assertion methods, allows to group them in tests and modules and display verbose feedback in HTML.

The assertions

QUnit offers three basic assertion functions: ok, equals, same

ok( state, message );

Should be used to assert a Boolean output for a function.

test("'ok' is not only meant to be used for Boolean values", function() {
    ok(123, "123 is ok");
    ok("abc", "Any string is ok");
    ok([], "An empty array is ok");
    ok(!"", "An empty string is not ok");
    ok(!0, "0 is not ok");
    ok(!null, "null is not ok");
    ok(!undefined, "undefined is not ok");
});
equals( actual, expected, message );

Should be used for a comparison assertion.

test("Cases where 'equals' passes for two values not strictly identical", function() {
    equals(1, true, "1 equals true");
    equals([1], true, "An array with a single 1 value equals true");
    equals("1", true, "A string with only the number 1 equals true");
    equals(0, false, "0 equals false");
    equals([0], false, "An array with a single 0 value equals false");
    equals("0", false, "A string with only the number 0 equals false");
    equals("012.345", 12.345, "A number and this number turned into a string are equal");
});
same( actual, expected, message );

Should be used for strict comparison assertion, works recursively on arrays and objects.

test("The actual and expected values have to be strictly identical", function() {
    same([{a: 2}, false, null], [{a: 2}, false, null], "Same is recursive");
});

Writing tests and modules

A test is composed of an homogeneous set of assertions for one unit of the program: In our example, we should write one assertion for each potential type of input string. The first line of a test state the number of assertions that are expected to pass, it’s optional.


test("Test that each type of input string produces the expected output", function() {
    expect(9);

    equals( camelCase("word"), "Word", "First letter of a word is capitalized");
    equals( camelCase("WORD"), "Word", "Other letters are lower-case");
    equals( camelCase("two words"), "TwoWords", "Spaces between two words are removed");
    equals( camelCase("A single letter"), "aSingleLetter", "If the first letter is a single letter, it is turned to lower-case");
    equals( camelCase("this is a letter"), "ThisIsAletter", "If there is a single letter in the middle of a sentence, the following letter is turned to lower-case);
    equals( camelCase("remove+special_chars!"), "RemoveSpecialChars", "Special characters are removed");
    equals( camelCase("save 123 numbers"), "Save123numbers", "Numbers are saved and the following letter is turned to lower-case");
    equals( camelCase("+ trim me _"), "TrimMe", "Trailing spaces are always removed");
    ok( !camelCase(" + _ ! "), "Return false instead of an empty camel case word");
});

QUnit offers the module method to help you visually identify related tests:

module("Camel Case");

Every test following this module will be prefixed by the module name.

synchronizing tests

QUnit offers two other methods to pause the tests for example when an Ajax call was made and the client is waiting for the answer. It is possible to make a pause in the sequence using the stop() and the start() methods.

Making your life easier.

If you happen to write a long batch of tests, you’re likely to realise that you often write similar lines. Being, like the vast majority of us, a lazy developer, you may start copy/paste large amount of code and write additional logic in order to factorise your test code. By doing this way, you might end up chasing bug that are not in the code you are testing, but right in your tests!

On the other hand, there are several ways to write DRY tests safely.

In-line function

If your function accept a second parameter that is not supposed to change the output of the function, it’s possible to create an additional set of test with few lines of code by using an in-line function. Imagine that we add a second Boolean parameter to make the camel case algorithm go faster (I’d love to see such parameter for every algorithm): myCamelCase( sentence, faster). The code would be:

var camelCaseTest = function(faster) {
    expect(9);

    equals( camelCase("word", faster), "Word", "First letter of a word is capitalized");
    equals( camelCase("WORD", faster), "Word", "Other letters are lower-case");
    equals( camelCase("two words", faster), "TwoWords", "Spaces between two words are removed");
    ...
});

test("Test that each type of input string produces slowly the expected output", function() {
    camelCaseTest(false);
});

test("Test that each type of input string produces quickly the expected output", function() {
    camelCaseTest(true);
});

We’ve just written two tests for the same price!

Setup and Teardown

module() also offers a second parameter to register a setup and teardown callback: pieces of code that will be called respectively before and after each test of this module. For example if you want to reset a number of variables that have been modified during the test:

module("Test camel case", {
    teardown: function() {
        a = b = c = d = undefined;
    }
});

Breaking the rule

The main rule in unit testing is to test your units of code separately. The smaller the units, the easier it will be to locate the source of an assertion failure. It is actually possible to break this rule and test multiple units at the same time ONCE those units have been tested enough to appear reliable.

Limit of unit tests

The first limit of unit testing is… the writer himself. If you don’t cause any failure just by writing tests, then I’m afraid you haven’t written enough tests. The second limit of unit tests in JavaScript is the number of configuration and what is actually testable.

This has been explained in details by John Resig in JavaScript Testing Does Not Scale. In brief, there is too much browsers and OS and it’s not possible to use unit testing to check the visual appearance of a page, or the correct behaviour of an animation for example.

Going further

During this post I have written a complete test for myCamelCase(), a method that I haven’t actually implemented. The test that I’ve written can actually be seen as a specification of this method, and I will only be able to claim that its implementation is complete once it successfully pass those tests. This software design method is called Test-driven Development and is one of the best way to write code that is reliable from the very beginning throughout the entire life cycle of the project.

You know everything about cookies, don’t you ?

April 3rd, 2009

Cookies are used on the Web for almost 15 years now, and despite their numerous flows and the emerging alternatives brought by HTML5, developers still resort to them, mainly for their ease of use and consistent implementation across browsers. For example, as you might have noticed, the background colour of this page changes over the time. To keep the colour up to date across the different pages, the colour value is stored in a cookie. When a user is offered controls to increase or decrease the font sit on a site directly from a Web page, the same mechanism is used.

So far, the best technical documentation about cookies available on the Web was the one found on QuirksMode. It still appears as the number 1 result on google for the query: cookie Javascript. The related page on Wikipedia is a good source of information concerning all the drawbacks and the alternative to cookies. Although there are suitable alternatives when it comes identifying a client from a server, there is no widespread solutions working purely on the client-side (but I urge you to use a modern web browser and the gears plugin to get yourself ready for the next generation of Web applications). Anyway this documentation and the proposed algorithms are quite old, and the purpose of this post is to give the small update it deserves, and it will stick to client side use of cookies.

Writing a cookie

Cookies are just little text files managed by the browser that can be used to store key/value pairs. The maximum size of a cookie file for a given website is 4ko, preventing it to be used for anything else than small strings (a colour code, a font-size, a preferred language are perfectly fine). And this is the basic code to write your first cookie:

var cookie = "fontsize=19px";
document.cookie = cookie;

You just append a string composed of a key and a value separated by an “=” sign to the cookie property of the document.

By default, this cookie will be stored only as long as your browser remains opened and it will be available only on the same path of the same domain. If the address of the page is http://en.wikipedia.org/wiki/HTTP_cookie for example, cookies written from this page will be only available on pages with addresses beginning by en.wikipedia.org/wiki/, everything before the first “/” being the domain, and the rest being the path.

By the way, during the celebration of the 20th anniversary of the World Wide Web, Tim Berners-Lee admitted that he regretted the way Web addresses were constructed, and that the domain should start with the more general elements. Applied to the previous example, this would have lead to: /org/wikipedia/en/wiki/… (bringing the folder/sub-folder metaphor to the Web).

It is possible to change those defaults by adding parameters at the end of your cookie String.

Expiry date

It is possible to specify explicitly the date when the cookie will be trashed by the browser, using the expires parameter and a Date object serialized by the Date.toUTCString() method (and not the deprecated toGMTString one):

var day = new Date(),
expiryDate = "expires=" + day.toUTCString();

In modern browsers, it is alternatively possible to set the max-age of a cookie in seconds, but this parameter is unfortunately unavailable in Internet Explorer (just like so many other things that would make the Web developer’s life easier).

Path and domain

It’s a good practice to set the path to the highest level:

var path = "path=/";

I can’t foresee any serious security issue resulting from this practice (considering that cookies should never be used to store critical data). And on the other hands you are likely to be unable to erase a particular cookie written by a script not specifying any path.

If there is no sub-domains for your website, the domain parameter is not useful. But in the Wikipedia example, the domain should be set as follows to be able to use the cookies across sub-domains:

var domain = "domain=wikipedia.org";

All-together

Writing a cookie with those parameters can be achieved with the following code:

var day = new Date();
document.cookie = "fontsize=19px" +";"+
"expires=" + day.toUTCString() +";"+
"domain=wikipedia.org +";"+
"path=/";

As you can notice, parameters should be separated by a “;”. Note that so far the Date used is a new, unmodified date, which represent the current date. Setting a expiry date to the current date is not gonna make your cookie last long. The solution will be provided in the scripts.

It is not possible to write two cookies at a time.

document.cookie = "fontsize=19px; fontcolor=#0000FF";

This code would actually write only the first key/value pair. You have to write the second cookie on a separated line beginning with document.cookie. Considering the parameters string to add to each cookie, the need of code factorisation is easy to understand.

Reading a cookie

Reading a particular cookie value can be achieved by reading the cookie string of the website and extracting a single value pair using a regular expression based on a key.

result = new RegExp("(?:^|; )" +key+ "=([^;]*)”).exec(document.cookie);
var value = result[1];

Special characters

In order to be able to read and write values potentially containing special characters (such as a “;” that would split your value), the value should be encoded before being written and decoded after being read.

document.cookie = encodeURIComponent("special=abc;def");
result = new RegExp("(?:^|; )" +"special"+ "=([^;]*)”).exec(document.cookie);
var value = decodeURIComponent(result[1]);

Overwrite and delete cookies

To overwrite a cookie simply write a new cookie with the same key.

document.cookie = "key=firstValue";
document.cookie = "key=secondValue";
// When reading "key", you'll find "secondValue"

The best way to erase a cookie is to overwrite it with an empty value and a past expiry date

var day = new Date();
// set the date to yesterday
day.setDate(day.getDate() -1);
document.cookie = "key=" +";"+
"expires=" + day.toUTCString();

The scripts

Using the previous pieces of code, it is possible to create a small cookie library that will handle writing/reading/erasing a cookie with a single function.

function cookieLib(key, value, expiryDay) {
  // If there is not just a key, the function is used to write a cookie
  if(arguments.length >1) {
    // But if the value is null, the function is used to erase a cookie
    if (value === null) {
      value = '';
      expiryDay = -1;
    }
    // If the date parameter is a number,
    // create a date from today + this number of days
    if (typeof expiryDay == "number") {
      var day = new Date();
      day.setDate(day.getDate() + expiryDay);
      expiryDay = day;
    }
    // Create the cookie string
    document.cookie = [
      key , '=' , encodeURIComponent(value),
      '; expires=' , expiryDay.toUTCString(),
      '; path=/'
    ].join("");
  // If there was only a key, the function is used to read a value
  } else if(result = new RegExp("(?:^|; )" +key+ "=([^;]*)")
           .exec(document.cookie))
    return decodeURIComponent(result[1]);
  return false;
};

Remember that cookies are only meant to store string values. If you want to write a number, remember to parse it back to a number after reading it.

I’ve also turned this cookie library in a plugin for the famous jQuery library, check the code of jquery.cookie on github.

Changes in VML for IE8, or “what feature can the IE dev team break for you today?”

March 30th, 2009

The final version of Internet Explorer 8 has been released by Microsoft on the 20th of March. It’s packed with a fully CSS2.1 compliant rendering engine, separate process per tab (just like in Google Chrome, good for stability, bad for memory consumption), performances are claimed to have improve, it introduces new features that will benefit the user such as Accelerators and Web Slices (available in Firefox with the WebChunks addon), as well as interesting features that will benefit the developer, such as a debug tool inspired by Firebug, the onhashchange event and some other interesting things. What as not been included in Internet Explorer 8? The list is unfortunately too long:

  • A Javascript Virtual Machine that could compete with the ones shipped by other browser vendors. The performances of Safari (squirrelfish extreme), Chrome (V8), Firefox (Tracemonkey) and Opera (Carakan) are still far better. But why would Microsoft create a Web browser shaped for the next generation of Web Applications? They are actively promoting their Software As A Service platform and Silverlight, their own Rich Internet Application framework because they can make much more money by forcing developers to adopt their technologies than by making any contribution to the Open Web.
  • <canvas>, <svg> or <video> are missing, and again, this isn’t a big surprise. There is everything you need in Silverlight for vector graphics, audio and video , would the salesman say.
  • Only little support of CSS3. Considering the credit crunch this can actually be seen as an advantage. How would the developers justify their pay if they could use border-radius, border-image, text-shadow and such, straight away, without spending countless hours working around Internet Explorer weaknesses?

Now it’s time to get onto what they managed to break without telling anyone: VML. VML stands for Vector Markup Language, an XML based language aimed at describing vector graphics. It has been submitted to the w3c in 1998 and begins with the following status:

This document is a submission to the World Wide Web Consortium.  It is the initial draft of the specification of VML.  It is intended for review and comment by W3C members and is subject to change.

At the same time, Adobe proposed to the w3c a language with similar purposes: PGML. Eventually, the two standards were merged into what is now SVG… But Microsoft made the choice to ignore this standard and to implement only their original proposition into their browser. Considering the market share of Internet Explorer at that time (around 95%), was there any reason to bother about Web standards? The legacy of this regretted market share is that developers now have to deal with two standards when it comes to vector graphics on the Web, since SVG is the one used in every other browser. Fortunately, there are abstraction layers that allow Web developers to use such features with a lowest common denominator approach such as Dojo.gfx or raphaeljs. But sometime you need to get your hands dirty and to use directly VML for performance or technical reason. This is the case in my border-image script where I’m using only one VML element: image. This was before the first Internet Explorer 8 beta came out…

Although the VML specification hasn’t undergone any improvements or modifications since its publication back in 1998, Microsft development team felt like considerably changing the way their own standard should be handled:

  • The namespace declaration has to take a second argument to be functional:
    document.namespaces.add('v', 'urn:schemas-microsoft-com:vml', "#default#VML");
    instead of simply:
    document.namespaces.add('v', 'urn:schemas-microsoft-com:vml');
  • The selector for the behaviour rules needs to be slightly modified (more information follows).
  • For a standard compliance purpose, when setting dimensions or position of an element, the unit no longer defaults to ‘px’. It has to be explicitly specified
  • It is no longer possible to create a VML element outside of the DOM:
    var myFragment = document.createDocumentFragment();
    myFragment.insertAdjacentHTML('beforeEnd',
    '<v:rect id="myRect" fillcolor="blue" style="top:10px;left:15px;width:50px;height:30px;position:absolute;"></biv:rect>'
    );
    document.body.appendChild(myFragment);

    This rect element will not be displayed! And don’t try to modify its CSS properties with the developer tool, you are likely to crash the tab or even the browser, if you’re lucky. Fortunately, there is an easy fix for this bug: you just have to copy the outerHTML of the element into itself:
    var myRect = document.getElementById('myRect');
    myRect.outerHTML = myRect.outerHTML;
  • It’s no more possible to use % unit! This one is my favourite. The advantage of vector graphics is that they can be scaled without quality loss. Now tell me how you scale a graphic from which all components dimensions and position are set in pixels! You have to resort to using the onpropertychange event to recalculate one after the other those values each time you want to resize your graphic. But there is a lot of case where you simply can’t fix this bug. For example, if you had an rectangle in a div: the div has no dimensions and scales with its content, and you want the height of your rectangle to scale with the div. There was a time when it was possible to simply set the height of the rectangle to 100% (providing the position of the div is relative, of course). But it was probably too easy after all.
  • It’s no more possible to use the getAttribute method to access the values of a particular attribute of your element.
    var myRect = document.getElementById('myRect');
    // Not working in IE8
    myRect.setAttribute('fillcolor', 'green');
    // Still working everywhere
    myRect.fillcolor = 'green';

Remarkably, none of this change has been announced by the IE dev team, as far as I know. The only announcement made about VML can be found on a blog post:

Generic CSS prefix selectors are no longer supported in IE8 Standards Mode in order to provide standards-compliant CSS parsing. Most often, this affects pages trying to use CSS to attach behaviors to VML elements. This can cause a script error if set dynamically, or a silent failure when hard-coded into the CSS of a page. Ultimately the rule is not applied, leading to effects such as VML not displaying on a page.

v\:* {
behavior: url(#default#VML);
}

SOLUTION: Explicitly specify each tag name you want to match when using CSS prefix selectors.

v\: polyline
v\: line {
behavior: url(#default#VML);
}

Can you spot the problem? There is actually nothing wrong with the * selector in CSS from a standard compliance point of view, to prevent the script from crashing if you set it dynamically, you simply have to put a space between the “v\:” and the * (you need two backslashes in javascript):

v\: * {
behavior: url(#default#VML);
}

I don’t really know what to think about that. On one hand it seems that some of this changes are just bugs (elements are still appearing in the developer tool with correct dimensions and position, they are simply not rendered), on the other hand, if they wanted to finish off VML and force developers to work with Silverlight, they couldn’t do it any better…

Just for fun, take a look at the VML documentation on MSDN, here is what you can still read:

  • About the height property:
    Units: A number with an absolute units designator (cm, mm, in, pt, pc, or px) or a relative units designator (em or ex). If no units are given, pixels (px) is assumed.
    Percentage: Value expressed as a percentage of the parent object’s height.
  • About the last parameter of the namespaces.add method:
    sUrl: Optional. String that specifies the URL of the element behavior to import into the namespace. Specifying this parameter is the same as calling the doImport method.

I learned about this namespace change in an obscure bug report in Microsoft connect. I had to figure out the rest by myself. I’m just afraid that I discovered those bugs too late. Now that Internet Explorer 8 has been made publicly available, there is only few chances for any change to be introduced in the rendering engine…

Update: Following the related post on ajaxian, Christian Effenberger pointed out that the setAttribute no longer work. I also want to state that the most obvious and easy way to fix all those bugs at once is to use the IE7 meta-tag:

<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />

IE7 is still the most common Web browser according to its market shares, so you have to make your website compatible with it (still painful, but nothing compared to its predecessor). Once your website is compatible with IE7, add this meta-tag and you will have compatibility with IE8 for the same price, with good ol’ VML implementation. Disclaimer: I do not recommand browser sniffing or browser hacks and should not be held responsible for bad use of the previous advice, period.

Update2: Changed the IE7 meta-tag and the link to the announcement on the IEBlog, thanks to dflock.