the open web, web development, and more

Showing posts with label web development. Show all posts
Showing posts with label web development. Show all posts

Monday, July 20, 2009

Methods Plugin 0.1

Since my introductory post on the Methods Plugin, I've improved the API and published it to jQuery's Plugin Directory.

The latest 0.1 version now adds 2 methods to jQuery: addMethod for adding methods and methods for retrieving the methods you added. Let's jump into some example code to explain it better. In this example I'll create a function that returns a jQuery object which has custom methods added to it. These methods can only be called by first calling the methods method on the jQuery object.

/**
* A generic productListing widget that can be displayed in a list...
*
* @param {String} tag - A string of HTML that will be converted to a jQuery Object
* @param {Object} data - A JSON Object of all the data, e.g.: {name: string, quantity: integer, price: float, description: string, freeShipping: boolean}
*/
function productListing(tag, data) {
var $el = $(tag);

$el
.addClass("product-listing")
.append("<h3>" + data.name + "</h3>")
.append("<p>" + data.description + "</p>")
.append('<span class="product-listing-quantity" >' + data.quantity + '</span>')
.append('<span class="product-listing-price" >' + data.price + '</span>')
// And on and on doing DOM stuff.
// Now here is the interesting part!
.addMethod("getQuantity", function () {
return data.quantity;
})
.addMethod("setQuantity", function (quantity) {
data.quantity = quantity;
$el.find(".product-listing-quantity").html(quantity);
})
.addMethod("freeShipping", function () {
return data.freeShipping;
});
}
So now we have a productListing function that returns a jQuery object. This object can be inserted into the DOM, hidden, animated, or anything else you like to do with jQuery. However, you can also call the methods method, which returns a simple object of your functions, and start calling any of the methods you added previously: getQuantity, setQuantity, and freeShipping. If any of these methods does not return a value, the methods object is returned so you can continue to call methods in a chain. You can also call the method end to get back to the jQuery objects scope (included for chainability).

To explain this better, let's get back to code:
// Some data or our productListing
var data = {
name: "Internet Celebrities Spoon Set",
description: "Now get the Star Wars Kid on a coffee spoon! These commemorative spoons...",
quantity: 10,
price: 19.99,
freeShipping: false
};

// Create a new productListing object
var commemorativeSpoonSet = productListing("<li/>", data);

// Append it to a DOM node, manipulate it, and call custom methods
$("#products-list")
.append(commemorativeSpoonSet)
.hide()
.methods()
.setQuantity(20)
.end()
.show();

// Look it up in the DOM too
var products = $(".product-listing");

products.each(function (i) {
if (!$(this).methods().freeShipping())
{
$(this).hide();
}
});
And there you have it. Methods is a small plugin, but hopefully it makes your life as a JavaScript developer a little easier.

Wednesday, July 8, 2009

Better Objects Using jQuery

I've been working almost exclusively with JavaScript building single page applications recently. jQuery has made developing the apps enjoyable but one area I find a bit awkward is creating complex objects.

Classes work well but can be cumbersome when creating a user interface since the object reference returned from the constructor is not a DOM node but a JavaScript object. Therefore, in order to insert the user interface component into the page, a special method like getHTML must be available for that object. This isn't terrible but creates more complicated code. Here's an example user interface widget - a simple box displaying a name:

function Widget(name) {
var container = $("<div/>");

function setName(newName) {
name = newName;
container.html(name);
}

this.getHTML = function () {
setName(name);
return container;
};

this.getName = function () {
return name;
};

this.setName = function (newName) {
setName(name);
};
}

And the code that uses it:

var nameWidget = new Widget("Dave");
var widgetNode = nameWidget.getHTML();
$(document.body).append(widgetNode);

This isn't too bad but gets a bit ugly when you need the ability to hide, show, animate, or do anything interesting. The choice is either to attach more methods to the Widget class or work with the jQuery object returned by getHTML. Pattern-wise, adding more methods to Widget is the cleanest but could require creating a lot of methods. Working with the jQuery object returned by getHTML is easy but leads to managing two objects in your code: nameWidget and widgetNode

What would be really nice is the ability to call any jQuery method on the nameWidget object PLUS all the methods specific to the Widget class. It occurred to me that this could be possible with the addition of a small jQuery Plugin I've dubbed Methods.

(function ($) {

$.fn.methods = function (arg0) {
if (arg0)
{
return this.each(function (i) {
$(this).data("methods", arg0);
});
}
else
{
return $(this).data("methods");
}
};

})(jQuery);

This plugin adds the methods method to jQuery. A collection of functions can be passed to methods to attach it to a specific jQuery object. Calling methods then returns the collection of functions. Here's a rewrite of the Widget class to explain this better:

function widget(tag, name) {
var container;

container = $(tag)
.html(name)
.methods({
getName: function () {
return name;
},

// Return "this" for chainability
setName: function (newName) {
name = newName;
container.html(name);
return this;
},

// Add the end method for chainability
end: function () {
return container;
}
});
return container;
}

And the code that uses this:

var nameWigdet = widget("<div/>", "Dave");
$(document.body).append(nameWidget);

Now we have a nameWidget that directly corresponds to the user interface component and, using jQuery, can be inserted anywhere in the page. To access the object's specific methods, you simply call methods. Here's an example that shows the combination of the methods and chaining:

nameWidget
.hide()
.methods()
.setName("Bob")
.end()
.show()
.addClass("widget");

Since the Methods plugin uses jQuery's data method behind the scenes, the nameWidget can actually be retrieved through a DOM lookup.

var nameWidget = $(".widget")
.hide()
.methods()
.setName("Sally")
.end()
.show();

And that's it. In the end, Methods is a simple jQuery plugin that lets you create complex objects with custom methods and closures and can still be used like a regular jQuery object.

Friday, November 14, 2008

Nice JavaScript Animation

I just popped over to Ubuntu's site to download the Intrepid Ibex (Ubuntu 8.10) and saw a very well produced animation made entirely out of JavaScript. I'm not at all surprised to see that Flash was snubbed (given that Ubuntu is Open Source) but was impressed with the smoothness and quality of the animation.

Nicely done!

Friday, November 7, 2008

Enumerating Objects in JavaScript

Enumerating through objects is something I only occassionally do in JavaScript, but when it does come up, I always find it a bit unintuitive. Here's some sample code for the future me that is faced with this task again:

var dataObject = {
foo: "bar",
one: "fish",
hello: "world"
};

var key;
for (key in dataObject)
{
document.write("Key: " + key ", Value: " + dataObject[key]);
document.write("\n");
}

This code will produce the following lines:
Key: foo, Value: bar
Key: one, Value: fish
Key: hello, Value: world

Wednesday, October 22, 2008

Victoria Open Web

The Victoria Open Ajax & Web 2.0 group held its first hack night earlier this month. Not a bad start and we figured out how to proceed with this loosely coupled group. In November we will be having another hack night and tackling Greasemonkey scripts. Hopefully we'll actually write some code and learn a bit at the same time. Meeting details coming soon-ish.

What is the purpose of the group? I suppose that is different for each member, but my main goals are to:

  • Expose myself to new technologies and techniques
  • Meet other Web nerds in Victoria
Also, since some participants are not Facebook users, we decided to use Google Groups instead. You can find us on google at, Victoria Open Web. The group is public so feel free to sign up.

Friday, October 17, 2008

Why Lenient Browsers are Evil

Evil might be a strong word, but it accurately conveys my frustration with web browsers and how their overly forgiving parsing rules can lead to a lot of wasted time.

The particular browser leniency I am talking about is the auto-insertion of the <tbody> element into an HTML table. Given that I try to use semantic markup whenever possible, I rarely use tables and therefore my knowledge of table markup goes back to pre-web 2.0 to when every part of a page resided in a table cell. At that time, table markup typically looked like:


<table cellspacing="0" cellpadding="0" border="0">
<tr>
<td>Foo</td>
<td>Bar</td>
</tr>
</table>

Yes, this is really simple and in reality would contain a table within table within table and nasty shims, but I think you get the point. However, what isn't apparent from this markup (and you are excused from forgetting) is that this is an invalid table because of the missing <tbody> tags around the table row. Instead of breaking the page though, the browser will just auto-insert the missing tags into its internal version of the page (a.k.a the DOM).

This doesn't seem all that evil yet and really just makes writing the HTML easier. However, fast forward this browser trait to the world of Ajax and manipulating the DOM and it becomes rather annoying. For example, take the same table and add some ids:

<table cellspacing="0" cellpadding="0" border="0" id="parent">
<tr id="child">
<td>Foo</td>
<td>Bar</td>
</tr>
</table>

Then run some simple JavaScript to delete the table row:

var parent = document.getElementById("parent");
var child = document.getElementById("child");
parent.removeChild(child);

And boom! This doesn't work because the child element is not a child of the <table> element, but of the magically inserted <tbody> element. The DOM would actually look like this:

<table cellspacing="0" cellpadding="0" border="0" id="parent">
<tbody>
<tr id="child">
<td>Foo</td>
<td>Bar</td>
</tr>
</tbody>
</table>

The terrible thing is you would not know this unless you used a tool like Firebug to inspect the DOM and see that the browser inserted the <tbody> tag to "help" you.

Tuesday, September 23, 2008

Victoria Open Ajax & Web 2.0 Developers

A new group of geeks is forming in Victoria known as the Victoria Open Ajax & Web 2.0 Developers. For some time now, there has been a Vancouver Ajax & Web 2.0 Developers group that would participate in regular "Hackathons" and organize other events for learning and information sharing. Being based in Victoria makes it difficult to participate in these events, but it turns out there are enough like-minded people here to create our own group.

The Victoria group is just getting started and we're using Facebook to get the word out. If you are interested, feel free to join the Victoria Open Ajax & Web 2.0 Developers group on Facebook and find out about soon-to-be-scheduled events.

Wednesday, May 28, 2008

Google Hosting JavaScript Libraries - But Don't Forget the Hash!

JavaScript libraries are great. Anyone that has done a significant amount of JavaScript development knows that using a library is the only sane way to develop an application. However, the downside has always been that the hefty size of the libraries leads to slower loading applications.

I've often discussed with colleagues that a potential solution is to have a "mega-performant" 3rd party site host the libraries. This way any website using the libraries could source them from the same domain leading to a higher chance that your users would already have the libraries cached in their browser. Well, it looks like this is no longer a pipe-dream now that Google has announced they are hosting several popular JavaScript libraries.

However, hosting libraries on a common domain isn't the only way to tackle the large download issue. Douglas Crockford has an excellent suggestion to improve library performance through the use of a hash code making it possible for browsers to reuse libraries regardless of the site hosting them. I won't go into the details of the his idea (follow the link for that) but mention that the one major flaw is that browsers must implement this. Even if the browser vendors do add this feature it would be years before it could be used by Web Developers.

This brings us back to the hosted libraries solution. It can be implemented now (not dependent on browser vendors) but comes with the downside that the site hosting the libraries is in complete control of what libraries are available. Google might not be overly evil but it probably won't host just any library. There are some simple solutions to this however.

Instead of Google hosting the libraries, a benevolent consortium backed by industry (Google, Yahoo, Microsoft, etc.) could provide the hosting and provide a very open means to upload any library. This is a bit idealistic and could be subject to abuse, but is probably doable.

The best and most realistic solution, however, is probably to push browser vendors to still adopt the hash attribute. Google has stated it will work with the browser vendors to possibly bundle the libraries with the browser, but this will create an even bigger obstacle to non-approved libraries. I like my web open and full of options and hope the hash solution is considered fully.

Update:
Looks like Google will be providing secure access to the libraries as well. Nice move and something that Yahoo does not provide with YUI.

Wednesday, April 9, 2008

Get Ready for Google Apps Engine - Learn Python and Django

I've recently began learning Python and the Django Web Framework for a project I am working on. And with Google's recent App Engine announcement it seemed like other developers might be interested in learning these technologies too.

My first bit of advice is keeping an open mind. If you have never written Python code before, but have a background in other languages like Java or PHP, you are in for a bit of a shock (or at least I was). Python's syntax is minimalistic (and not very flexible) with the goal of making Python scripts look very similar from programmer to programmer and thus understandable by all. After fighting syntax errors and swearing at gedit for auto-inserting spaces instead of tabs I've actually come to like Python a lot.

I have no experience with Ruby on Rails but hear rumors that Django has much in common. Regardless, Django is a lightweight framework that provides the developer with a lot of shortcuts and conveniences. Less configuration hassles and more code (the Python kind that is succinct and readable).

So with an open mind, here are some resources that should help you on your way:

  • Dive Into a Python - a freely available website that provides a good introduction to Python. As an added bonus you can download a PDF or HTML version of the book to read while (gasp) offline;
  • Python Tutorial - An indispensable reference;
  • Django - download the Django Framework and follow the 4 simple tutorials.
  • Django Book - I must admit, I just found out about this free resource and haven't had a chance to look through it yet;
  • DjangoSnippets - User contributed code snippets. Sometimes looking at someone else's code can be invaluable and save a lot of time;
  • Django Screencasts - I prefer reading through well-written documentation, but if you like fancy screencasts, these should help.
This short list contains all that you need to get going. Grab your favourite editor and marvel at how easy web development can be. You'll be mocking your J2EE-toiling friends in no time.

... and if you really want more to read, check out this Top 30 Django Tutorials List.

Sunday, March 30, 2008

Open Web Vancouver

Open Web Vancouver is coming April 14 & 15 to Vancouver Convention & Exhibition Centre. I'll be attending this year and I'm quite excited as I haven't had the opportunity to attend many web conferences in the past.

The sessions look great and I am particularly looking forward to:

Friday, February 15, 2008

Cloud Samurai: New look for Atomeo

If you are reading this post from an RSS Reader, head on over to Atomeo Cloud Samurai to see the new "Cloud Samurai" theme. With previous blogging attempts I got wrapped up in the development and maintenance of the blogging platform (yes, I'm talking about you WordPress) and hardly posted to my blog. With my latest attempt at blogging I decided to use Blogger and focus on the content. So far this has been working out so I figured it was high-time I gave it a better skin.

I learned a lot about image creation from this project since the Samurai Kite image was created from scratch (hand sketched, scanned, GIMPed and Inkscaped). Knowing what I know now I think I could create a better image (I should have used Inkscape from the start) but I have run out of steam and want to move on.

Let me know what you think.

Monday, January 21, 2008

Douglas Crockford's Proposal for HTML5

I was reading through a blog post and found a link to Douglas Crockford's Proposal for HTML 5. It's a quick read and very high level but interesting nonetheless. Overall, the theme is small tweaks to HTML that will have a big impact on making web application easier to develop and safer to use.

If you have a passing interest in understanding how this portion of the web might evolve, I'd recommend the read.

Update: Minutes after publishing this post, the W3C made the HTML5 proposal an official recommendation. Check out the differences between HTML4 and HTML5 for an even better indication of how the web might evolve.

Thursday, December 6, 2007

Semi-Transparent (Dithered) GIF Slows IE

I recently had an odd page performance problem in IE6 & 7. The page redraw was quite slow on window resize and the page would react very slowly to mouse hover events. I spent hours investigating JavaScript bugs and possible mark-up issues with no success. In the end, removing a dithered GIF from the style sheet did the trick.

Once again, I was baffled by IE's shortcomings (did I mention all other browser's performed normally?) but had to move on and find a solution. I'm posting this article to take a break from ranting about IE to my co-workers and in the hopes that other frustrated developers might stumble upon this when trying to understand why a simple web page is performing so poorly in IE.

First, you might be wondering what I mean by a dithered GIF. It's a checker-board-like image that alternates between solid colour and full transparency. Below is an example of what this GIF "looks" like.



The grey squares represent fully transparent pixels (like only a GIF can do) and the white squares represent opaque pixels. The idea is that this image can be used as a tiling background image and allow images underneath it (from parent elements - think body background) to show through. This can create a nice effect and might sometimes be used to mimic alpha-transparency in PNGs when IE6 support is important. Or so I thought. Turns out the performance hit that IE 6 & 7 users take don't really make this a viable option.

I'm not sure why IE performs so poorly when using the dithered GIF as a background image but a pretty good solution was to replace the GIF with a white PNG that had its opacity set to 50%. This solved the IE performance problems and the real alpha-transparency looked better in IE 7. The only problem was that IE 6 rendered the PNG as solid grey. To fix this the star hack came in handy to set the background colour to solid white. The slight alteration to the page's design was far outweighed by the performance boost so this made the solution quite acceptable.

Alternative Solutions that Didn't Work

  • Reproducing the dithered GIF in the PNG format (keeping the binary transparency) does not improve performance
  • Adding full PNG support to IE 6 through the HTC file does not work on background images
  • Although it is possible to set a background colour for a PNG (I believe for the purpose of degrading when alpha-transparency is not supported), IE 6 ignores the setting and just defaults to grey
And there you have it. Hopefully this was helpful or at least interesting. If you have any insight into why IE performance is negatively impacted by the dithered GIF, please share.

Monday, October 15, 2007

How to install a GoDaddy Wildcard SSL Certificate on JBoss

I write this post mainly so that I retain the knowledge of stumbling through this frustrating and poorly documented process and in the hopes that it will be of use to another poor soul on the Internet. Specifically, this how-to will be useful if you:

  • Have purchased a Wildcard SSL Certificate through GoDaddy
  • Need to enable SSL on JBoss (should apply to Tomcat too) because the Apache web server is not being used to pass requests to JBoss
  • Are running Ubuntu (or any Linux/Unix OS) on your server
  • Are running Sun Java 1.5
To summarize the steps, you need to follow the GoDaddy instructions for installing the certificate on Tomcat but add an additional step of extracting your private key from "tomcat.keystore" (a file you will create). However, for the purpose of this how-to, I'll cover all the steps.

Step 1

SSH into one of your production servers and create the directory "ssl-files" to work in as you will be creating and downloading several files. CD into "ssl-files" Then run the command:

keytool -genkey -alias tomcat -keyalg RSA -keystore tomcat.keystore

This will run a command line wizard that prompts you to enter data. Whoever wrote this tool could have spent more time on the clarifying the instructions.

Enter keystore password:
[Pick something clever and write it down]
What is your first and last name?
[Don't take this literally. It turns out that "*.yourdomain.com" is the best answer]
What is the name of your organizational unit?
[Anything, this isn't really important but should be the same as a previous certificate if you are renewing]
What is the name of your organization?
[Same as above]
What is the name of your City or Locality?
[Same as above]
What is the name of your State or Province?
[Same as above]
What is the two-letter country code for this unit?
[Same as above]

Once you finished the wizard you should now have the file "tomcat.keystore" in your current directory.

Step 2

From the "ssl-files" directory, run another command to create a certificate request (.csr) file:

keytool -certreq -keyalg RSA -alias tomcat -file <your-file-name-here>.csr -keystore tomcat.keystore

Now open the newly created file:

cat your-file-name-here.csr

Copy the contents of the file so you can paste it into the CSR field of the Certificate Request form on GoDaddy's website. I'm assuming you found the correct form on the website, but if you haven't, don't feel bad as the GoDaddy site has a deplorable UI.

Step 3 (Not found in GoDaddy's instructions - nor many other places on the net)

You now need to extract a private key from the tomcat.keystore binary. This is where any official documentation leaves you hanging. Not only are you unaware of this step but there is no easy way to do using the keytool. Luckily, someone at the University of Texas has a nice write-up on this. Scroll down to the "Additional esoteric Java keytool operations" section to the 3rd step. Copy the code, and paste it into a new file (in the "ssl-files" directory) names, "GetKeys.java". Delete the first line in the file that is specifying the package as "MyPackage" and replace the three values as indicated at the University of Texas website.

Compile GetKeys: javac GetKeys.java

Run the class: java GetKeys

If all goes well you should see some text that begins with "-----BEGIN PRIVATE KEY-----". If not, you will have to go back to GetKeys.java and debug. Once you get it working, copy all the output (including the begin and end private key lines) and paste it into a new file you create named "<your-file-name-here>.key".

Step 4

Download the .zip archive provided by GoDaddy to your server (you will likely have to download it to your desktop and then scp or ftp it to your server). Now run the unzip command (note: unzip is not installed by default on Ubuntu, but a quick sudo apt-get install unzip will fix that):

unzip <big-long-random-string.zip>

This will extract 4 .crt files into your current directory, hopefully you are still in "ssl-files". Now create your "keystore.tomcat" file (not to be confused with the existing "tomcat.keystore" file) that you can copy to the correct location on your servers:

openssl pkcs12 -export -chain -CAfile gd_bundle.crt -in <_.yourdomain.com> .crt -inkey <your-file-name-here>.key -out keystore.tomcat -name tomcat -passout pass:<your-password>

Now you should have the file "keystore.tomcat" in your current directory.

Step 5

At this point you can head back to the GoDaddy instructions in order enable/modify SSL support in server.xml. The "keystore.tomcat" file can be safely used in a clustered environment and re-used on the remaining servers.

Hopefully you found this helpful. If you find any errors or simpler alternatives, please post a comment.

Thursday, August 9, 2007

Resources for Web Developers on Ubuntu

Below are some links to software and web sites that I use on a regular basis. I post these as a resource for myself (when I inevitably have to rebuild a box) and in the hopes that it is useful to others.

Applications

Firefox: the majority of readers will already be users, or at least aware of this excellent browser, but I mention it to give context to the add-ons below (and because it is so good).

Add-ons (a.k.a. Extensions)

  • Firebug: The ability to debug and step through JavaScript code is amazing. I have never used Microsoft’s products for web development (which I understand also provide this ability) so this is practically revolutionary for me.
  • Web Developer: A collection of very handy tools for Web Developers. You have the option to use it as a toolbar, or keep it out of sight, and access its tools through the context menu.
  • Live HTTP Headers: A simple tool that allows you to see the request and response HTTP headers. Although, the Firebug add-on contains header information as well, I keep coming back to Live HTTP Headers as it is simpler to use.
  • Google Browser Sync: I never found bookmarks useful until I found this add-on. With this tool you can synchronize bookmarks between multiple Firefox installations. As an added bonus, it serves as a backup when you need to unexpectedly scrub your box.

Eclipse: As an Ubuntu user, that needs a full featured Java IDE, Eclipse is a pretty solid choice. Installation is a snap (apt-get, done) and the plugins can make it very powerful.

Plugins

  • Aptana: IDEs or Eclipse Plugins to assist in AJAX development are few at this point. Aptana seems to be a pretty good choice so far and works with many of the major JavaScript libraries out-of-the-box. It has excellent documentation and is open source to boot.
  • Subversive: I just started using this plugin. Until recently I was using Subclipse but found it a bit buggy and awkward to use. So far, Subversive has been a pretty solid replacement. I’ll need more time to fully vet it though.
  • Veloeclipse: A plugin that will aid in developing velocity templates. It provides some much needed syntax highlighting and other features. What is Velocity? Velocity is an awesome Apache replacement for JSP.
  • QuickREx: An indispensable tool for writing/testing your regular expressions. Includes a very handy method of converting your RegEx into Java syntax (you know, extra escape characters to make the RegEx less readable)

Useful Sites

  • Regular-Expressions.info: A very handy reference site for looking up some of the more obscure aspects of Regular Expressions or trying to write a Regex in a new language.

Wednesday, June 20, 2007

A Box of Google Gears

Google Gears is a plugin that has been a long time coming and addresses some the of the ideas I discussed in my earlier post, "Offline Web Applications". My only exposure to it has been as a Google Reader user and to be honest I was a bit disappointed. My main gripe is that it requires the browser to remain open after going offline. It works fine if you go offline, then disconnect from the Internet and keep your browser open. But shutting down the browser, then restarting without an Internet connection does not work at all. Also, reloading Google Reader while in offline mode (without an Internet connection) does not yield pleasant results.

I don't suspect many users will find this acceptable. But since this a Google backed plugin I have hope that it will improve soon. In fact, I would not be surprised if Google rushed the plugin out the door in reaction to the spat of RIA Frameworks being announced.

Even though the plugin needs some refining, the potential is there for Web Applications to become viable alternatives to Desktop Applications. Fast-forward a few years and Google Gears is probably more stable and sophisticated. In fact, the API it exposes is likely included by default in most browsers (i.e. Firefox 3). More importantly, Web Application Developers have figured out how to incorporate offline mode seemlessly into the user experience.

But how do Web Applications gain greater acceptance in the enterprise? Perhaps by bringing the server closer to the user. This could come in the form of a box that plugs into a network and services requests for certain URLs itself (i.e. intercepts requests for Google Docs or GMail), runs code locally against a local database, and responds back to the browser. Then, depending on how the box is configured, synchronizes data back to an origin server. With the box in place, data is stored in-house (with optional offsite storage) and application response rates are much faster. Devices like the Asus Eee PC or OLPC could replace the desktop for most needs and would have the added benefit of continuing to work as normal outside of the enterprise network since requests for Web Applications would go directly to the origin server.

This box could be equally useful in a home setting (likely even more accepted) as a combo unit that acts as a wifi access point, router, and file server in addition to its application server role. Imagine using an App like Flickr served from a Gears box (leap of faith: assume box is open). Upload rates would be super fast as would editing and organizing your media. So fast in fact, there would be no need to use a Desktop App to first organize and upload your media (Goodbye F-Spot). What does Google have to do with this box? Nothing, other than they seem to be a company that wants to push the usefulness of Web Applications and become a dominant application provider.

But that's enough baseless speculation over the future of computing. At this point I am merely hopeful that in a few years Web Applications will have the option to be delivered this way.