Freedom in he cloud

July 1st, 2008

Richard Stallman, the founder of the Free Software Foundation, launched a call for action concerning freedom and privacy in the cloud.

"This is a post about freedom. The freedom to keep your data for yourself and the freedom to run free software. You should be able to reclaim and enjoy these freedoms also when using web applications.", he claims. Stallman goes on promoting the Affero GPL, the exact license we are using to release the code behind MyOwnDB!

We believe MyOwnDB is ready to join AGPL suite of web applications that provide tools for the most common needs.

Stay tuned!

Slow Awakening

June 3rd, 2008

Hi all!

Yes! MyOwnDB is not dead. It doesn’t even smell funny. While it has been quiet here for some time, in the background a lot of work has been done by an expanded development team. Two important milestones will be reached soon

  1. Dedomenon, the core of MyOwnDB, gets a complete REST API making it the easiest web database to use in your mashups
  2. we are so proud of our code that in a couple of weeks we will release it in it’s full glory under the Affero GPLv3 license. Now you can be absolutely sure your data will never be captured.

Enjoy!

YUI-ext grid and context menus

February 26th, 2007

I recently had the opportunity to use YUI-Ext for a little application. I’ll focus on the creation of the context menus for the grid. If you’re discovering YUI-Ext’s layout approach, more information is available from Jack Slockum’s blog in Exploring Cross-browser Web 2.0 Layouts with Yahoo! UI and Cross-browser Web 2.0 Layouts (Part 2) and Ajax Feed Viewer 2.0.

I’ll illustrate what I learned with a little useless app (code is in javascript.js), which lets you rate fries for different countries. As belgian fries can only be good, the context menu will only propose to rate them as good. However, for other countries, you can rate fries as bad. (Yes, this example is that useless…).
I’m working with a grid whose data comes from an XML file. This XML file contains a list of countries in this format:


1
Belgium
http://www.belgium.be

Which result in this datamodel definition:

dataModel = new YAHOO.ext.grid.XMLDataModel({
                            tagName: 'item',
                            id: 'id',
                            fields: ['country', 'url']
                            });

and this column model:

var colModel = new YAHOO.ext.grid.DefaultColumnModel([
      {header: "Country", width: 100, sortable: true},
      {header: "URL", width: 250, sortable: true, renderer: formatURL},
]);

The URL column has a renderer set: this is a function which allows you to format the data in the column. Here’s the URL renderer:

function formatURL(val) { return '‘+val+’‘;}

A renderer can also be used to display fixed content. Eg, if you want to display the text “Delete” in a column, you can simply use this renderer:

function deleteText(val) { return 'Delete';}

For this example I store the list’s items in the file items.xml, so here’s how I load the data:

dataModel.load('items.xml');

Now we can create the grid:

var grid = new YAHOO.ext.grid.Grid('my-grid', dataModel, colModel);

I created a function onContextMenu which is set as listener to the “rowcontextmenu” event:

grid.addListener('rowcontextmenu', onContextMenu);

This method prevents the default behaviour:

e.preventDefault();

If you don’t, you get the browser’s default context menu. Even with this call, Firefox 1.5 displays its own context menu.

As the context menu to display depends on the content of the first column, it then extracts this value. The best way I found to do this is:

grid.getSelectedRows()[0].childNodes[0].childNodes[0].innerHTML;

(In my app, I could not base the decision on the row’s id, which could be the better choice if possible)

According to the value extracted, the context menu to display is retrieved, its position is set, and it is shown:

this.context_menu = this.belgium_menu;
YAHOO.util.Dom.setXY(YAHOO.util.Dom.get('belgiummenu'), e.getXY());
this.context_menu.show();

Both context menus are built similarly, at the start of the onContextMenu function, and stored in a member variable so that the next time is it called, it can reuse the menu built eaarlier. Here’s how the menu is defined for rows with ‘Belgium’ in the first column:

if (!this.belgium_menu)
{
        var aMenuItems = [
                { text: "Rate Belgian Fries as Excellent" },
                { text: "Rate Belgian Fries as Excellent" },
        ];
        this.belgium_menu =new YAHOO.widget.ContextMenu(’belgiummenu’,
                {
                        itemdata: aMenuItems
                }
        );
        this.belgium_menu.clickEvent.subscribe(onBelgiumSelect, this.belgium_menu, true);
        this.belgium_menu.render(document.body);
}

The menu is constructed by settings the items it should display, and then we subscribe a method to its click event. In this listener taking 3 arguments, you can simply have a switch statement to act differently depending on which menu entry was clicked:

                  function onMenuChoice(type, args, menu)
                  {
                              switch(args[1].index){
                                        case 0: //First entry
                                                break;
                                        case 1: //Second Entry
                                }
                  }

Accessing temlpate variables in tests

February 18th, 2007

In your tests, you can easily access variables defined in your templates as:

@response.template_objects["key"]

and here’s a concrete example:

assert(@response.template_objects["user"].errors.invalid?(”password”)

Upgrade to Rails 1.2 notes

February 13th, 2007

As I was looking to upgrade applications to rails 1.2, I wrote down all changes I had to do, and post those here in the hope it can be useful to anyone. I have skipped rails 1.1 for some apps and upgraded from rails 1.0, so some (all?) of the points could be from differences between rails 1.0 and 1.1.

The first thing is that apparently the name of model classes have to be named very precisely, and there’s now a check to see the class was loaded correctly. This caused a problem for the class I had defined in the file app/model/user2address.rb. I (or the generator?) had named the class User2Address, and rails 1.2 checks if the class User2address was loaded (note the capitalisation difference of the a of address). This problem was corrected by simply adding one line:

User2address = User2Address

I’m using the tablefunc contrib of Postgresql, and this requires to define some functions (implemented in a C library) in the database. For the tests to run fine, and have the necessary functions available, I needed to run rake db:test:clone_structure to prepare before running the tests.

I had to delete and reinstall the seleniun on rails plugins.

rm -r vendor/plugins/selenium*
script/plugin install http://svn.openqa.org/svn/selenium-on-rails/selenium-on-rails

I used the String.random method from the nano, now facets library. This seems to not be available in the facets gem I installed, so I reimplemented it myself.

I had to replace some assert_tag tests conditions from a string to a regular expression. Seems it was checking on substrings, but doesn’t anymore.

I had a boolean attribute of a model I used as o.boolean? and I’ve had to adapt it as o.boolean!=’f’ (as I’m using Postgresql)

The image_tag helper now adds an asset_id at the end of the src, resulting in something like

. This can be found at action_view/helpers/asset_tag_helper.rb line 214 (for the whole call stack, in order: lines 185, 155, 200, 212). I guess this is done to avoid caching problems. The part added is either the environment variable ENV["RAILS_ASSET_ID"] or the File.mtime result. This change made that I had to adapt some tests to make it work fine again. I had tests that included the src of the image tag generated. I adapted the tests to work with regexps on the src check:

 :src => Regexp.new("/images/icon/big/use.png(\\?\\d+)?")

That’s it, all tests pass again. I hope this can help some people out there encountering the same problems

Understanding javascript’s prototype member

February 6th, 2007

After looking Douglas Crockford’s talks about javascript, I started experimenting to really understand javascript’s prototype. If you have downloaded the presentation’s slides, this is an illustration of slide 27. I’ve worked with the javascript interpreter included in the JDK6, based on Rhino. If you do this, just run $JAVA_HOME/bin/jrunscript and you get a prompt of the javascript interpreter.

Each javascript function is given a prototype member when it is created. It is through this member that you can easily extend all objects of the same kind at once. For example you can easily extend every string object like this:

String.prototype.myNewMethod = function() { .... }

What intrigued me in the presentation is that you can assign a new object to the prototype member of an existing object. To illustrate this, let’s work with the Gizmo and Hoozit from Douglas’ presentation;

function Gizmo(id) { this.id= id; }
Gizmo.prototype.toString = function () { return ('gizmo ' + this.id); }

function Hoozit(id) { this.id = id };
Hoozit.prototype.toString = function () { return ('hoozit ' + this.id); }

First let’s create a Hoozit instance, and identify its toString method:

Hoozit.prototype.toString  //sun.org.mozilla.javascript.internal.InterpretedFunction@1201a25
my_hoozit = new Hoozit(1);
my_hoozit.toString();     //returns "hoozit 1" as expected
my_hoozit.toString;       //sun.org.mozilla.javascript.internal.InterpretedFunction@1201a25
my_hoozit.constructor;  //sun.org.mozilla.javascript.internal.InterpretedFunction@85af80

When accessing a function without calling it, the JDK6 javascript interpreter will display its id.
Here we can see that my_hoozit.toString == Hoozit.prototype.toString, and if we update the toString method of the prototype, it impacts the already created instance:

Hoozit.prototype.toString = function () { return ('updated hoozit ' + this.id); }
Hoozit.prototype.toString  //sun.org.mozilla.javascript.internal.InterpretedFunction@c51355
my_hoozit.toString();        // returns 'updated hoozit 1'
my_hoozit.toString           //sun.org.mozilla.javascript.internal.InterpretedFunction@c51355
my_hoozit.constructor     //sun.org.mozilla.javascript.internal.InterpretedFunction@85af80

We see here that if we update the method in the prototype, each instance has the method updated.

Now on to the strange part: as the prototype is a reference to an abject, you can assign an instance of another object to the prototype:

Hoozit.prototype = new Gizmo();
Hoozit.prototype.toString  //sun.org.mozilla.javascript.internal.InterpretedFunction@fa9cf
my_hoozit.toString(); //returns "updated hoozit 1"

How comes that although the method of the prototype has been changed, the call on the existing object hasn’t been adapted? The thing is that when my_hoozit was created, it has been assigned a prototype member that is a pointed the Hoozit.prototype. When we assigned an instance of a Gizmo to Hoozit.prototype, it didn’t change the pointer of the already instanciated Hoozit, which still points to the initial Hoozit.prototype object. We can see it like this:

my_hoozit.toString       //sun.org.mozilla.javascript.internal.InterpretedFunction@c51355
my_hoozit.constructor  //sun.org.mozilla.javascript.internal.InterpretedFunction@85af80

You can see that my_hoozit.toString still is the method with “id” c51355.

Now if we instanciate a new Hoozit, its prototype member will point to the current Hoozit.prototype:

second_hoozit = new Hoozit(2);
second_hoozit.toString(); //returns "gizmo 2"
second_hoozit.toString    //sun.org.mozilla.javascript.internal.InterpretedFunction@fa9cf

If I adapt the Hoozit.prototype, it will only affect the second_hoozit, and not my_hoozit:

Hoozit.prototype.toString = function () { return ('again updated hoozit ' + this.id); }
Hoozit.prototype.toString  //sun.org.mozilla.javascript.internal.InterpretedFunction@a3bcc1

my_hoozit.toString();         // returns "updated hoozit 1"
my_hoozit.toString            //sun.org.mozilla.javascript.internal.InterpretedFunction@c51355

second_hoozit.toString()   //again updated hoozit 2
second_hoozit.toString     //sun.org.mozilla.javascript.internal.InterpretedFunction@a3bcc1

Now, if you had a toString method to the second_hoozit, it is added to the object itself:

second_hoozit.toString=function(){ return "my second_hoozit method"}
second_hoozit.toString      //sun.org.mozilla.javascript.internal.InterpretedFunction@1bd4722
Hoozit.prototype.toString  //sun.org.mozilla.javascript.internal.InterpretedFunction@a3bcc1

In standard javascript you don’t have access to an instance’s prototype, though with mozilla you can access it through the __proto__ member. This lets us illustrate further:

second_hoozit.toString                //sun.org.mozilla.javascript.internal.InterpretedFunction@1bd4722
second_hoozit.__proto__.toString //sun.org.mozilla.javascript.internal.InterpretedFunction@a3bcc1
Hoozit.prototype.toString            //sun.org.mozilla.javascript.internal.InterpretedFunction@a3bcc1
my_hoozit.__proto__.toString     //sun.org.mozilla.javascript.internal.InterpretedFunction@c51355

I hope this helped you understand the mechanism behind javascript’s prototype.

PS: Special thanks go to Richard Cornford and Isaac Schlueter for their answers in com.lang.javascript!

Enhance your javascript knowledge online!

February 3rd, 2007

Until now I’ve been using javascript as a simple language to get Ajax features, but as I used it I discovered interesting features and got really interested to know more. As the JDK 6 has rhino included, you can also use javascript and get access too all Java libraries, which makes javascript knowledge even more interesting.

A really great resource to know more about the power of javascript and how to use it effectively is the series of presentations by Douglas Crockford made available online by Yahoo. There are 3 presentations splitted in 3 or 4 videos each:

  • The javascript programming language is a presentation of the origin of the language, how it evolved, and explains some design errors in the language and why they’re in the standard
  • An Inconvenient API: The Theory of the Dom was the presentation that captivated me the least, though you’ll get some interesting info out of it.
  • Advanced javascript is really very interesting and not to be missed if you want to know how to exploit the language’s power. The second video has a part about debugging, and explains how to get the Microsoft Office javascript debugger which seems to be the best solution to debug in IE, although you’ll see it’s not easy to find. The third video talks about performance, minification, JSON.

It’s really great to have this available online for free. You get access to a javascript training of high quality. Well done Yahoo!

Javascript closures illustration

September 30th, 2006

Jack Slocum mentioned in a comment the problem comes from the creation of a global variable. When you create a local variable, you don’t get the problematic behaviour. Thanks Jack for taking the time to correct me.

Intro

Here is the illustration of a bug that was present in version 0.1 of the yui slideshow. If you don’t know what closures are, you should take a look at the Javascript closures for dummies which is really a great resource.

The problem

Here is a class that is plagued with the same problem as v0.1 of the yui slideshow:

var test = function(name)
{
        this.name = name;
}

test.prototype= {
        setInitial:  function( b )
        {
                name=this.name;
                if (b)
               {
                         this.callback = {
                         initial: function(){return name[0];}
                         }
                }
                else
                {
                        this.initial=name[0];
                }
        },
        getInitial:  function()
        {
                if (this.callback)
                        return this.callback.initial();
                else
                        return this.initial;
        }
}

An instance of this class is initialised with a name. On this instance, we can call the setInitial method which prepares everything so that getInitial can correctly return the first letter of the name. As you can see, there are two ways to set the initial: either directly to a member variable, or through an object callback. This reflects the code in the yui slideshow component: the next frame can either be present in the page (and as a member variable), or it has to be loaded remotely and can only be handled by a callback function once the XMLHTTP request has completed.

To see what’s wrong with this code, here is some code setting the stage:

r= new test('raphael');
c= new test('cathy');
r.setInitial(true);
c.setInitial();

This code creates 2 instances r and c, then call setInitial the callback way on r, and then calls setInitial the member variable way.

Now, if you call r.getInitial you get…. ‘c’. How comes?

When you create the callback object, you have an anonymous function (closure) referencing the “name” variable (the “name” having the value “raphael”). However, by the time the function is run, the “name” variable is pointing to ‘cathy’ as the setInitial method is last run for the ‘c’ instance. This is equivalent to Example 5 of the Javascript closures for dummies page.

The solution

So, how can we correct the problem? As the problem is coming from closures, let’s not reference the “name” variable from inside the anonymous function, and let’s add a member variable arg to the callback object, which references the “name” variable:

setInitial:  function( b )
        {
                name=this.name;
                if (b)
                {
                         this.callback = {
                         initial: function(){return this.arg[0];},
                         arg: name
                         }
                }
                else
                {
                        this.initial=name[0];
                }
        }

With this code, r.getInitial() return “r” as expected.

See by yourself

I set up two page, one with the problem, the other with working code. Visit these pages and you’ll see the results described.

YUI based slideshow

September 30th, 2006

As I wanted to add a slideshow on the MyOwnDB homepage, I started looking for a ready made solution, but as I didn’t find exactly what I wanted, but also because I was curious of how it could be done, I started coding one based on YUI. I wanted a slideshow that enabled me to:

  • load slides on demand, so not all slides had to be embedded in the page
  • choose the effect used during the slides transitions
  • have pictures as well as HTML slides

After some tweaking and searching, I have been able to publish it, with a demonstration page also available. Most of the time I lost was due to IE not treating the opacity CSS property correctly. I was setting the opacity like

el.style.opacity=1.0;

The solution is provided by with the setStyle method:

YAHOO.util.Dom.setStyle(el, 'opacity', '1');

which handles all cross browsers differences, including IE’s lack of opacity support. This is the kind of details that makes it enjoyable to develop with YUI.

Another positive point for YUI was its Connection Manager which made the addition of remote on demand slides a breeze to implement. The possibility to pass an argument to the callback methods was very useful in the 0.2 release which has been released to correct a bug encountered when several slideshows are present on one page, and at least one of them has slides to load on demand.

Remember to reset the YUI listeners on updated content

September 1st, 2006

I had event listeners set on elements added dynamically to the page not working:

my original content Click here to replace content

When you click on the test_link, the content of the div is updated with a undo_link, for which we have a click event listener to redisplay the original content. Note how the event listener for the undo_link is set before this link is present in the page.

The simple solution is to set the event listener in the change_content function after the undo_link has been added to the document.

Testing onavailable

Writing this blog post, I wondered if I could use the onavailable method to set the listener once the test_link or undo_link are included in the document. Two problems seem to invalidate this approach:

  • the onavailable method is executed only the first time the element is inserted in the document. If it is removed and re-added, the method is not executed.
  • the onavailable method seems meant to accelerate javascript actions at page load time, so action can be taken immediately after the element is available. This is also shown by the fact that the polling of the element is not continuous, but only happens during a configurable time span (by default 10 seconds).

I’ve put a little demo page illustrating this.