Archive for the ‘Web2.0’ Category

* Asymmetric Follow In Pictures

Posted on December 12th, 2008 by Dave Johnson. Filed under Web2.0.

With James as my inspiration, I have been thinking more about asymmetric follow and how it applies to the web. I decided to make up some simple pictures to describe my thoughts on it.

Movie and music stars are really the definition of asymmetric follow. You buy their records, watch their movies, send in fan mail but you will probably never be acknowledged by the star nor will what you have communicated probably even be read by them or impact them. All follow no follow back. Purely asymmetrical. The stars don’t follow anyone else and everyone follows them. The number of people involved in these systems is very large - i.e. one star might have millions of fans.

Radio also has a huge audience and most people just sit there and listen so the right side is pretty high again. On the other hand some shows do allow people to call in or often talk to notable people in the field so there is, though relatively small, some follow back going on.

Email of course has become an important communication medium. With email you can receive it from anyone from close family or peers to random people and spammers. This picture I am least confident about but certainly some people get lots of unsolicited email while also having many people that they would consider to be “following”.

Finally, we have Twitter or other Web 2.0 social networks (like dopplr that James posted data from) where “friending” is not reciprocal by design. With things like Twitter we are approaching something symmetrical despite the fact that reciprocity is not enforced and I think there are few reasons for this that JP also touched on. The main idea being that Twitter reduces the barrier for people to engage in conversations.

Twitter actually increases the symmetry of traditional asymmetrical follow primarily by the fact that it is a smaller community than pop-culture at large and therefore the signal to noise ratio is considerably higher in general. This is helped further by the fact that interactions have to, by design, be succinct. At 140 characters there is only so much you can say and it is easier for other people to comprehend. Twitter is also very temporal in that if you are not around to get them you are generally fine to ignore them unless they are replies or direct messages. Finally, Twitter is public which helps to keep people and their conversations honest.

Asymmetrical follow is clearly a prominent pattern across all media, and maybe something that is being reduced through tools like Twitter, are there other patterns that while prominant in more traditional forms of media are somehow reduced in a Web 2.0 world?

Tags: , , .

* Sponsoring MerbCamp!

Posted on September 25th, 2008 by Dave Johnson. Filed under Web2.0.

It looks like we be sponsoring MerbCamp this year! I think that there will be a good group from Nitobi going on down to sunny San Diego for this event and hopefully even making some presentations.

Tags: , , .

* PhoneGap: It’s Like AIR for the IPhone

Posted on September 18th, 2008 by Dave Johnson. Filed under Web, Web2.0, adobeair, mobile.

A few weeks back Brock and Rob from here at Nitobi built an amazing IPhone framework down at IPhoneDevCamp that we have named PhoneGap. While I have attributed the injustice of us not winning any of the competition categories of IPhoneDevCamp to the completely jaw dropping achievement of our team, in just two days of development (with most of the competition winners having developed their apps weeks or months before IPhoneDevCamp) it does not take away from the excitement I have for our PhoneGap framework. And there is lots of excitement around PhoneGap with some blogs about it, lots of activity over at GitHub, and 60 people signed up to the PhoneGap Google Group in just a few short weeks!

While some may not have realized the impact of PhoneGap (including the judges at IPhoneDevCamp), we here at Nitobi think that PhoneGap is the Adobe AIR of the IPhone (not to mention Blackberry, Android, Symbian and Windows Mobile). Just like Adobe AIR enables web developers to build Windows and OS X applications using the HTML and CSS skills that they know and love, PhoneGap allows web developers to build applications for the IPhone with web technologies while taking advantage of the native IPhone APIs like GPS, the camera, SQLite, contacts and more!

Using PhoneGap, a developer need not write any Objective-C code and yet they can still have a proper app installed on an IPhone that is essentially a slightly customized PhoneGap application that sports a custom icon and a certain URL where application lives online (very much like AIR). When a user starts PhoneGap it essentially creates a headless (ie no address bar) browser on the IPhone and navigates to the specified URL where the author of the web page can access IPhone APIs through JavaScript like this:


//GAP will invoke this function once it has the location
function gotLocation(lat,lon){
    $('lat').innerHTML = "latitude: " + lat;
    $('lon').innerHTML = "longitude: " + lon;

Or access the accelerometer data like this:

function updateAccel(){
    $('accel').innerHTML = "accel:"+accelX + " "+accelY+" "+accelZ;

Someone has even tried to get a PhoneGap on the App Store - however, has had little success so far.

The aim of PhoneGap is to bring mobile phone development to web developers just as AIR has brought desktop application development to the web community. One of the next steps will be packaging _all_ the HTML, JavaScript and CSS into the application that goes on the IPhone so that the application can even run offline much like AIR does.

There is still lots to be done!

Image by

Tags: .

* What is RIA?

Posted on August 12th, 2008 by Dave Johnson. Filed under AJAX, Conference, RIA, Web2.0.

Way back in May of this year (I have been thinking about this post for a while now!) Andre and I were down at JavaOne to give a presentation and also had the chance to take part in the always interesting (at least two years in a row now) RedMonk CommunityOne session. It was good to take part in the cloud computing, twitter and open source discussions - one great take away was “don’t drink and tweet”. I digress.

Of most interest to me was the round table discussion about “what is an RIA?“. There were various opinions on this that I will not repeat here and let you read over on RedMonk.

What didn’t come through on the RedMonk review was what I thought, arrived at through the great discussion, was really the defining characteristic of Rich Internet Applications. In the end it was not about flashy graphics or animations. The one defining characteristic of an RIA is that there is no page refresh.

That’s it. That is all there is to RIA. If you have an application running over the network that does not have a page refresh then that is an RIA - be it using Flash, Ajax or a Java Applet. The discussion went back and forth until Jeremiah Stone from SAP finally talked some sense (afterwards we had a very interesting discussion and I really need to follow up with him) saying that good design is dependent on the context of the problem being solved. Now this is a really important idea since if you are used to working with a keyboard accessible green screen application, a visual mouse driven GUI will probably be far less usable. It is all context dependent. I may take longer to learn the green screen application but it will likely pay dividends in productivity down the road.

At any rate, long story short, the one common theme that people presented was that an RIA is defined by an application that has no page refresh, whether it is made for a user of a terminal or a new web 2.0 application.

I had my epiphany at the very end of the session and was pretty much lost on deaf ears of people who were about ready for a cold one (aside from Duane who was thoroughly liquored already ;)) . However, I felt somewhat vindicated when I was reading James’ post about the session when I noticed that there was a comment from David Mendels of Adobe, who was possibly responsible for defining the term while at Macromedia in the early 2000’s. Indeed David suggested that the original definition of an RIA was an application with no page refresh.

Based on that I think that the case of the meaning of RIA can be considered closed.

RIA == No page refresh


Tags: , , , , , .

* Analytics Benchmarking

Posted on June 28th, 2008 by Dave Johnson. Filed under Web2.0, analytics, robotreplay.

I just saw an advert for Google Analytics in my GMail the other day that mentioned something about a new industry benchmarking feature. I knew immediately what it was.

The idea is that you take the analytics information from all the sites using Google Analytics and generate some benchmarking data by industry and apply it to your stats. That way people who use Google Analytics can see if they have an unusually high bounce rate compared to their peers or if they have a really low pages per visit stat. Right now when people look at their Google Analytics information - aside from their past experiences - they haven’t really got much to go on in terms of what a good bounce rate or pages per visit value might be. This way one can actually compare with others and then prioritize what needs to get fixed based on what is most out of whack compared to others in their industry.

In the case of Google Analytics, I think that this sort of feature could really change analytics from being a private sort of thing to becoming something that, dare I say, a social network could build around - who wouldn’t want to be featured on the Google Analytics homepage for having the best web stats?

I had this idea a while back and I think it can be applied to a lot of different industries outside of web analytics - sort of like PayScale is doing with salary reporting - but of course an idea is nothing unless you can execute :)
Hopefully we can apply the same sort of idea to RobotReplay in the future.

Tags: , , , , .

* Alwees Froosh

Posted on October 28th, 2007 by Dave Johnson. Filed under AJAX, JavaScript, Nitobi, Web2.0, adobe, adobeair, air, hackday.

That is the name of the application that Jake, Chris and I made for the inaugural Nitobi Hack Day last Saturday.

Yes, we may have had the biggest team and yes some teams didn’t even stick around until the sweet, sweet beer but we came within a whisker of winning it all! Of course, how you split up a single iPod Nano amongst three people is anyone’s guess.

The idea behind the application was that we wanted a desktop app that would be running all the time and would bring in information from many different sources about music artists / bands that you like. In particular, I never know when new albums come out from bands that I like. The trick is that we use, in this case, your top tracks XML listing from to determine what you like - ie what you listen to most is what you like. Then we use that info to look up different information about the bands. At the time of building the application we decided on two things to bring in; new releases and events. The original reason that we went with the AIR application was because I wanted to use my iTunes XML file. We found a problem with that early on - my iTunes XML files is >7MB and AIR has a tough time opening it. That is when we decided to go with

I will release the app shortly once I get some time to fix it up.

We were able to deal with the new AIR security model pretty easily and of course chromeless windows and all the great CSS3 support was much appreciated!


* How Do You Jiibe?

Posted on October 16th, 2007 by Dave Johnson. Filed under Nitobi, Web2.0.

We have recently been working hard on a new “Web 2.0 social networking” application and are finally ready to release the beta to the world.

Say hello to Jiibe.

The problem that Jiibe is trying to address - as if being a social networking application wasn’t enough - is to help people think about the culture at their place of work and how well that culture jives with what they would find ideal. By answering a few quick questions about their workplace culture the user creates their own personal Jiibe and at the same time contributes to the overall Jiibe culture signature for the company they are currently working at. It is a great way for people to figure out what they like and don’t like about their company culture and also to help them find companies that have a culture they would mesh well with.

One of the other cool features is that people can ask questions to everyone at a company which can generate discussions around certain topics at a company. If only Joe had Jiibe to ask people who actually worked at EA what it was actually like to work there!

I would definitely encourage people to go and check out Jiibe and answer some questions for their current and / or former employers to help people make more informed decisions about where they want to work. As with any Web 2.0 application Jiibe is currently in Beta so things will still be changing as we work more on the application and add features that users demand.

Tags: , .

* AIR Application

Posted on July 18th, 2007 by Dave Johnson. Filed under AJAX, Nitobi, Web2.0, air, completeui, onairbustour, salesforce.

Since Andre was invited to go on the Adobe AIR bus tour we decided to build a cool sample application that would exhibit some of the cool features of AIR and our components. Since we like to focus on the “business case” for our Ajax components and our custom development, we built an AIR application that integrated with the API. Being the RIA nutters that we are and knowing that most people would be building Flex based applications - which we are currently building a few of for various customers - we decided to build an HTML / Ajax based application instead.

The cool AIR features that we wanted to show off were things like

      1. custom chrome to make things look hawt
      2. drag and drop from the desktop for vcard integration
      3. file system integration for taking things offline

Since we had a pretty tight timeline we went fairly simple and built the application in about three person weeks. The idea was centered around a mobile sales person being able to have access to their Salesforce Account and Contact data while online or offline. Of course, being an Ajax application it should also prove to be a much nicer interface than the current Web 1.0 based Salesforce user interface - man would I like to be able to redesign the Salesforce UI!

Custom Chrome

The most important part of the application was to make it look hawt. This involved a bit of design assistance from Alexei and the creation of some JavaScript and text based activity indicators since animated gifs don’t work in the current AIR beta :( What we did use a lot though was the CSS3 border-image style. It doesn’t seem to work quite right but if you just go with it you can make something that looks half decent.

So on the outer window we applied a style like this:
-webkit-border-image:url(../images/app-border.png) 18 18 18 18 stretch stretch; border: 18px;

Where the app-border.png looks like this:

As well as looking great the chrome needs to be functional. It needs to have minimize, maximize, restore and close buttons. It needs to be resizable and draggable. Maximize, minimize, restore and close are easy - for example:


All of those methods (restore, close, minimize, maximize) are created on the nitobi.air.Window JavaScript class. To enable draggability we attach an HTML event handler to the our main window DIV element like this:

nitobi.html.attachEvent($(”main_window”), “mousedown”, handleMove, this);

The handleMove method is shown below where we just do a quick check first to see if the element that the user is trying to drag has the chrome class on it - this lets us make the window draggable from various points like the header and around the edges. Once they get the chrome we just call startMove() like this:

nitobi.air.Window.prototype.handleMove = function(evt)
if (nitobi.html.Css.hasClass(evt.srcElement, “chrome”))

Desktop Integration

The other cool thing about using AIR is that rather than having some ridiculous multi file upload utility written in Java or Flash, with AIR we can just take files from the desktop and drag them onto the application. What this means is that we can take things like VCards or CSV files full of contact information and have them automagically entered into Salesforce. If offline they get saved as updategrams and get uploaded once the computer is back online. The events for the drag and drop are Flex events on the AIR htmlControl but they connect to JavaScript methods as handlers.

nitobi.lang.close(this, doEnter));
nitobi.lang.close(this, doDrop));

When the drag operation enters the AIR window we call the acceptDragDrop method with the htmlControl as the only argument. This will enable dropping onto our HTML application.

nitobi.air.Window.prototype.doEnter = function( e )
if(e.transferable.hasFormat(air.TransferableFormats.FILE_LIST_FORMAT ) ) {

Now that we have enabled dropping on our HTML app we can actually process the information when it is dropped by accessing the transferred data like this:

nitobi.air.Window.prototype.doDrop = function( e )
var files = e.transferable.dataForFormat(
air.TransferableTransferMode.CLONE_PREFERRED );
for( var f = 0; f < files.length; f++ ) {

In this case we specify that the drop should be a list of files and we are able to iterate over that list to add each of the VCards to Salesforce.

Offline Operation

Finally, we did some filesystem integration for working offline and that was pretty cool. Rather than using the SQL-Lite database that comes with AIR, we wanted a solution that would be more conducive to a web way of working - ie something that will essentially queue HTTP POSTs and subsequently POST them when a network connection is present. Because frankly, unless you have A LOT of data on the client and interfacing to a SQL-Lite database is generally going to be overkill and make a lot more work for the developer since they will have to write not one backend in their server language of choice but also a client side backend in JavaScript. Anyhow, in the Nitobi CompleteUI framework, all changes on the client are stored as XML “updategrams”. So it was a pretty easy task to put a layer between the client side JavaScript DataTable and the XMLHttpRequest that sends data to the server when it is “saved”. Instead of the data being sent to the server with an XHR, if the client is offline the updategram is just persisted to disk. Even when online, the data is continually saved to the disk for offline use at any time. All this took very little extra coding since we just serialized the server messages rather than actually transforming them into SQL statements that would store the data in SQL-Lite.

For all of this to work we needed to be notified when the computer is connected to the network. This is done in the nitobi.air.Window class by using the AIR service monitor. This has the additional requirement of having the servicemonitor.swf library in the web page by using a script tag with the src as servicemonitor.swf. To create the service monitor we do something like this:

var req = new air.URLRequest(’’);
this.monitor = new;
air.StatusEvent.STATUS, handleStatusChange

Where the handleStatusChange method will notify any objects that are connected to the the onOnline and onOffline events of the nitobi.air.Window class.

nitobi.air.Window.prototype.handleStatusChange = function(evt) {
// Fire the event for online / offline notification
if (evt.code == “Service.unavailable”)

For writing the data to disk we use the AIR filesystem integration and wrap it all in two IO methods for reading and writing. The air.File.applicationStorageDirectory is (on Windows) in c:\documents and settings\username\application data\Application-Name folder.

[code] = function(filename) {
var file = air.File.applicationStorageDirectory.resolve(filename);
var stream = new air.FileStream();, air.FileMode.READ);
var str = stream.readMultiByte(file.size, air.File.systemCharset);
return nitobi.xml.createXmlDoc(str);
} = function(xmlDoc, filename) {
if (typeof xmlDoc != ’string’) xmlDoc = nitobi.xml.serialize(xmlDoc);
var file = air.File.applicationStorageDirectory.resolve(filename);
var stream = new air.FileStream();, air.FileMode.WRITE);
var str = stream.writeMultiByte(xmlDoc, air.File.systemCharset);

I think that those were definitely the coolest parts of the application and made for a a pretty sweet little app for managing Salesforce Contacts and Accounts. There is still a little more work that I would like to do in the coming weeks like allowing adding and saving of both Contacts and Accounts without VCards as well as some other searching features. Alas, this will have to do for now :) Also, when Adobe gets XSLT support in there it will be even more awesome!

You can check out the half baked source code here and get the AIR application for installation here. I am working on a version of the AIR app that will allow the user to enter their credentials and actually see their data - and there will be a HUGE disclaimer that you use at your own risk :D
Update: I just found out that the Mac version of AIR does not have XPathResult (!!!) so selectNodes doesn’t work … sorry Mac users but it should be fixed soon.


* Declarative Ajax and Flex Interop

Posted on July 3rd, 2007 by Dave Johnson. Filed under AJAX, Components, Declarative Programming, FABridge, Flash, Flex, Grid, RIA, Web2.0, XSLT.

This is some code that I wrote about a year ago at the Flex Component Developers Summit (and more recently presented at XTech) to show how declarative Ajax and Flex can work together to create dynamic, rich and compelling Internet applications.

The idea is simple. Take a single declaration - in this case XHTML - of some user-interface component and then use it to build a UI using either Ajax or Flex. All this from just one declaration.

What happens is that we take a single declarative data grid and converts it using XSLT on the client (so it only works Firefox, IE and soon Safari) into a declarative Nitobi Ajax Grid and to a Flex declarative MXML DataGrid. I use the FABridge to get the string of MXML generated from the XSL transformation into a stub Flex application where a Flex DataGrid is instantiated (deserialized) from the MXML declaration. It can an be seen live here (note: create the Flex grid first then the Ajax one - something funny that I can’t be bothered to fix ;)) and the code can be downloaded from here.

So by using a declarative approach and a little XSLT on the client we were able to quickly choose between using a Flex DataGrid or a Nitobi Ajax Grid to display our tabular data in!

Really the most interesting part is the MXML deserialization stuff. The only contents of the Flex application are two functions for performing the deserialization. I have listed the main part of the code that takes an XML document of an MXML DataGrid declaration and actually instantiates a DataGrid according to that declaration. It’s pretty quick and dirty but at least gets the right thing out! Essentially it just looks at each XML element and creates an Object out of it and sets all the properties on it from the XML element attributes and then recurses through the child elements doing the same. There are some special attributes though like datasources that need a little more care.

public function initGrid(html) {
  // setup a tagname to datatype hash - maybe this already exists somewhere
  controls['DataGrid'] = ‘mx.controls.DataGrid’;
  controls['ArrayCollection'] = ‘mx.collections.ArrayCollection’;
  controls['Object'] = ‘Object’;
  controls['columns'] = ‘Array’;
  controls['DataGridColumn'] = ‘mx.controls.dataGridClasses.DataGridColumn’;

  // load the HTML into XML DOM
  var mxml:XML = new XML(’<root>’+html+’</root>’);

  parseXml(AjaxBox, mxml);

public function parseXml(parent, mxml) {
  var item:String;
  // get all the elements in our XML doc - this should of course walk the xml tree recursively
  var itemList:XMLList = mxml.elements(’*');

  for (item in itemList) {
    // get the tag name of the XML node
    var tagName:String = itemList[item].localName();

    // get the class by using getDefinitionByName() method
    var ClassReference:Class = Class(getDefinitionByName(controls[tagName]));

    // create an instance of the class
    var myObject:Object = new ClassReference();

    // get all the attributes and set the properties
    var attrList:XMLList = XML(itemList[item]).attributes();
    for (var attr:String in attrList) {
      myObject[attrList[attr].localName()] = attrList[attr].toString();

    // now parse the children of this node
    parseXml(myObject, itemList[item]);

    if (parent.hasOwnProperty(tagName)) {
      parent[tagName] = myObject;
    } else if (parent.hasOwnProperty(”length”)) {
      if (parent.hasOwnProperty(”source”)) {
      } else {
    } else if (parent.hasOwnProperty(”dataProvider”) && tagName == “ArrayCollection”) {
      // This means we need to create a datasource for the Grid
      parent.dataProvider = myObject;
    } else {


* RobotReplay Beta is Live

Posted on April 15th, 2007 by Dave Johnson. Filed under AJAX, Web2.0, analytics, robotreplay.

We have finally released the public Beta of our RobotReplay service. What RobotReplay does is it records the mouse movements, clicks, and key presses and allows you to play them back. The service is completely Ajax based with no special plugins. Right now we don’t have much in the way of features but we are going to be constantly adding more and listening to our users about what they want to see.

First take a look at Andre’s screencast.

Otherwise, just sign up now and see what your users are doing.

Tags: , , .