Activate your free membership today | Log-in

Friday, April 24th, 2009

Mouse Gestures with GWT

Category: Flash, Fun, Gears, UI

Marc Englund wrote to us about his recent experiments with mouse gestures and GWT:

SimpleGesture is a GWT (and IT Mill Toolkit) implementation of the mouse gesture recognition method described by Didier Brun at bytearray.org (as I understand it). It allows you to register easy to understand (human readable) gestures, and receive events when these occur. Additionally, SimpleGesture can record new gestures, so that you don’t have to write them by hand.

In this video demo, he’s using a Wii to show it off (this confused me at first, but he’s using the Wii as a mouse and isn’t doing anything with the Wii-specific inputs):

You can also play with a live demo.

SimpleGesture relies on a bit of Flash to do its thing:

I have used the bytearray mouse gesture library for a Flash project before, and I love how simple the method is, and yet it works very well.
The method works by assigning a number depending on which direction the mouse moves in (moving right will produce “0″, moving down will produce “2″, and so on), and comparing the resulting string of numbers to the registered gestures. The gesture with the lowest Levenshtein distance (and below a set threshold), is considered a match.

Posted by Ben Galbraith at 9:00 am
5 Comments

+++--
3.5 rating from 22 votes

Tuesday, January 27th, 2009

Gmail Offline is here (or coming soon for you!)

Category: Gears, Google, Offline

Gmail Offline has been an incredibly long wished for product feature and now it is coming (takes time to push it out to people and it will appear in Settings - Labs).

This is a big deal. It uses Gears of course, and many people are always saying “it’s about bloody time.”

This is easy to say from the comfort of the arm chair at home. In reality, an architectural change like this is huge. Moving to a sync model that works reliably is tough in the best of times, and when you try to do it to a product that is popular, it gets that much harder to do right.

I got to use this when I was working at Google and saw numerous ups and downs (one version works well, then it gets buggy, then it gets better, etc). It was fantastic to be able to use it on the plane (or would have been if I wasn’t scared that someone would look over my shoulder). It resets expectations. You get used to opening up the browser when you KNOW you are offline. Having this in a product that you use as much as email will change user behaviour and will lead us down the path of more easily being able to do browser like things when connectivity is rough. Hell, knowing that WiFi jumping up and down won’t affect me is a big deal.

Congrats to Andy Palay and the team. I hope that we get to see an interview him as he discusses the architecture and the various tweaks to that architecture as they nailed this all down. We have much that we can learn from the process.

If you don’t have it in your “Labs” settings (I don’t right now, and the witing game is annoying I know!) check out the high level video:

Posted by Dion Almaer at 7:48 pm
14 Comments

++++-
4.5 rating from 22 votes

Tuesday, January 20th, 2009

Passpack ups it game with Gears

Category: Gears

Without Gears, it took about 23 seconds to unpack the tags.
Versus just over 1 second for the same operation with Gears.

What is that quote about? Passpack is a long time Gears user, but they have put out a new update that uses Gears in a better way. They use WorkerPools, and it really matters.

Today we’re releasing our first baby-step using the Gears WorkerPool to speed up the encryption/decryption processes.

For now, we’ve optimized the “unpacking tags” process, and the results are impressive. Further optimizations will definitely follow.

How Much Faster Is It?

Passpack makes heavy use of Javascript cryptographic algorithms, so slower machines and certain browsers [cough: Explorer] will see the biggest improvements.

In an entirely unscientific experiment, we timed logging into a Passpack account with 112 tags and about 400 entries.

Web Workers (WorkerPool) are coming to user agents near you!

Posted by Dion Almaer at 6:53 am
4 Comments

+++--
3.3 rating from 6 votes

Wednesday, January 14th, 2009

ActiveRecord.js Released: ORM for Multiple JavaScript Environments

Category: Announcements, Aptana, Gears, Storage

Aptana has put out their first beta release of ActiveRecord.js. The details according to Ryan Johnson, a developer at Aptana:

ActiveRecord.js is an open source object relational mapper (ORM) that supports multiple JavaScript environments, including:

  • Google Gears (client-side persistence)
  • In Memory (if no SQL server is available on the client)
  • Adobe AIR (client-side persistence)
  • SQLite and MySQL (via Aptana Jaxer, the open source Ajax server)
  • additional environments (like HTML5) expected to come through working with the community on the project

ActiveRecord.js abstracts away underlying SQL commands so that JavaScript developers can have a unified API for storing, finding, selecting and retrieving objects and their data using the ActiveRecord pattern popularized by the Ruby on Rails community.

Here is some example code using the ActiveRecord.js framework; note that they've made some interesting changes away from how Ruby on Rail's does the ActiveRecord pattern:

JAVASCRIPT:
  1. var User = ActiveRecord.define('users',{
  2. username: '',
  3. email: ''
  4. });
  5. User.hasMany('articles');
  6.  
  7. var ryan = User.create({
  8. username: 'ryan',
  9. email: 'rjohnson@aptana.com'
  10. });
  11.  
  12. var Article = ActiveRecord.define('articles',{
  13. name: '',
  14. body: '',
  15. user_id: 0
  16. });
  17. Article.belongsTo('user');
  18.  
  19. var a = Article.create({
  20. name: 'Announcing ActiveRecord.js',
  21. user_id: ryan.id
  22. });
  23. a.set('name','Announcing ActiveRecord.js!!!');
  24. a.save();
  25.  
  26. a.getUser() == ryan;
  27. ryan.getArticleList()[0] == a;

See the Aptana blog post for more details.

Posted by Brad Neuberg at 6:30 am
14 Comments

++++-
4.5 rating from 13 votes

Thursday, August 28th, 2008

GALGWT 1.0… it isn’t a land next to Mordor

Category: GWT, Gears, Google

GWT has long had a project that aimed to give rich support for Google APIs called GALGWT, or "Google API Libraries for Google Web Toolkit".

This project has stepped up to higher gear recently, and we have seen the GALGWT 1.0 release candidate appear.

What is in GALGWT?

The project is a collection of libraries that provide Java language bindings
and API specific 'plumbing' for some Google JavaScript APIs. The goal is to
make it easy for developers to use these JavaScript APIs with GWT. Libraries
available at this time include a new version of Gears, as well as new
libraries for Gadgets and the Google AJAX Search API.

Gears 1.1 Library

A new version of the Gears library is available. In addition to the earlier
version's support for the Gears LocalServer, Database, and WorkerPool, 1.1
adds integrated support for offline applications and updated sample
applications. The bindings have also been refactored to use GWT 1.5
JavaScript overlay types and a new package hierarchy.

Gadgets 1.0 Library

The Gadgets library simplifies gadget development with GWT by automatically
generating a Gadget specification from Java source and inserting a selection
script in the specification much like a regular GWT project. After compiling
your gadget with GWT, all files are in place to publish your gadget. This
version currently supports the legacy Gadgets API based on the _IG_...
namespace.

Google AJAX Search 1.0 Library

The Google AJAX Search API lets you put Google Search in your web pages,
including Web, Local, and Multimedia searches. This library allows you to
access the API from Java code compiled with the GWT compiler without having
to write additional JavaScript code.

Posted by Dion Almaer at 5:45 am
Comment here

++++-
4.2 rating from 6 votes

Wednesday, August 27th, 2008

YouTube Uploader now using Gears, and what people missed in Gears 0.4

Category: Gears

While we posted about the Gears 0.4 features a lot of the press only really talked about the Geolocation piece.

I think that is important, and posted on that too, but Brad's piece discussed the full gamut including the Blob API, resummable HTTP, and Desktop API improvements to allow controlled file system access. The example that Brad built was the upload movie tool which ties this all together.

Check out the source code and you will see the parts and pieces in action:

Geolocation

JAVASCRIPT:
  1.  
  2. MovieTool.prototype.getLocation = function(callback) {
  3.   var geolocation = google.gears.factory.create('beta.geolocation');
  4.   if (!geolocation.getPermission('Upload Movie Tool', '',
  5.                                   'This sample can use your '
  6.                                 + 'geographic coordinates in order to tag '
  7.                                 + 'uploaded videos with your location')) {
  8.     document.getElementById('location').innerHTML = 'Permission denied';
  9.     callback();
  10.     return;
  11.   }
  12.  
  13.   var self = this;
  14.   geolocation.getCurrentPosition(
  15.     function(p) {
  16.       var addr = p.gearsAddress;
  17.       var address = addr.city + ', ' + addr.region + ', ' + addr.country;
  18.       var latitude = p.latitude;
  19.       var longitude = p.longitude;
  20.       self.geoAddress_ = address + ' (' + latitude + ', ' + longitude + ')';
  21.       document.getElementById('location').innerHTML = self.geoAddress_;
  22.       callback();
  23.     },
  24.  
  25.     function(err) {
  26.       var msg = 'Error retrieving your location: ' + err.message;
  27.       document.getElementById('location').innerHTML = msg;
  28.       callback();
  29.     },
  30.    
  31.     {
  32.       enableHighAccuracy: true,
  33.       gearsRequestAddress: true,
  34.       gearsLocationProviderUrls: ['http://www.google.com/loc/json']
  35.     }
  36.   );
  37. }
  38.  

HTTPRequest

JAVASCRIPT:
  1.  
  2.   var req = google.gears.factory.create('beta.httprequest');
  3.   req.open('GET', '/list');
  4.   var self = this;
  5.   req.onreadystatechange = function() {
  6.     if (req.readyState == 4) {
  7.       if (req.status == 200) {
  8.         var loadingMsg = document.getElementById('loadingFilesMsg');
  9.         loadingMsg.parentNode.removeChild(loadingMsg);
  10.         self.movieList_ = eval(req.responseText);
  11.         for (var i = 0; i <self.movieList_.length; i++) {
  12.           var entry = self.movieList_[i];
  13.           // associative entry for fast lookup based on filename
  14.           self.movieList_['_' + entry.filename] = entry;
  15.           var status = 'Uploaded'
  16.           var percent = '100%';
  17.          
  18.           // was this movie partially uploaded during an earlier browser
  19.           // session?
  20.           if (entry.uploaded == false && entry.blob == null) {
  21.             status = 'Partially uploaded; re-select file to continue uploading';
  22.             percent = Math.round((entry.bytesUploaded / entry.length) * 100) + '%';
  23.           }
  24.          
  25.           // is this movie too large?
  26.           if (entry.uploaded == false && entry.length> self.MAX_FILE_SIZE) {
  27.             status = 'File too large';
  28.             percent = 'N/A';
  29.           }
  30.          
  31.           self.drawRow(entry.filename, entry.geoAddress, status, percent);
  32.         }
  33.       }
  34.      
  35.       callback();
  36.     }
  37.   }
  38.  
  39.   req.send();
  40. }
  41.  
  42. ....
  43.  
  44. // sending a piece
  45.   req.open('POST', uploadURL);
  46.  
  47.   req.setRequestHeader('Content-Disposition',
  48.                         'attachment; filename="' + fileName + '"');
  49.   req.setRequestHeader('Content-Type', 'application/octet-stream');
  50.   req.setRequestHeader('Content-Range', 'bytes ' + byteRange);
  51.  
  52.  

Desktop API

JAVASCRIPT:
  1.  
  2. MovieTool.prototype.selectFiles = function() {
  3.   var desktop = google.gears.factory.create('beta.desktop');
  4.   var self = this;
  5.   desktop.openFiles(
  6.     function(files) {
  7.       for (var i = 0; i <files.length; i++) {
  8.         var entry = {filename: files[i].name, uploaded: false,
  9.                             length: files[i].blob.length,
  10.                             blob: files[i].blob, bytesUploaded: 0,
  11.                             geoAddress: self.geoAddress_, uploadRetries: 0};
  12.         if (self.movieList_['_' + entry.filename]) {
  13.           // was previously uploaded at an earlier browser session
  14.           var oldEntry = self.movieList_['_' + entry.filename];
  15.           if (!oldEntry.uploaded) { // partial upload
  16.             oldEntry.length = entry.length;
  17.             oldEntry.blob = entry.blob;
  18.             var percent = Math.round((oldEntry.bytesUploaded / oldEntry.length) * 100);
  19.             self.updateStatus(oldEntry.filename, 'Not uploaded', percent + '%');
  20.           } else {
  21.             self.updateStatus(oldEntry.filename, 'Uploaded', '100%');
  22.           }
  23.         } else { // new file
  24.           // associative entry for fast lookup based on filename
  25.           self.movieList_['_' + entry.filename] = entry;                   
  26.           self.movieList_.push(entry);
  27.          
  28.           var status = 'Not uploaded';
  29.           var percent = '0%';
  30.           // is this movie too large?
  31.           if (entry.length> self.MAX_FILE_SIZE) {
  32.             status = 'File too large';
  33.             percent = 'N/A';
  34.           }
  35.          
  36.           self.drawRow(files[i].name, self.geoAddress_, status, percent);
  37.         }
  38.       }
  39.      
  40.       document.getElementById('movieUpload').disabled = false;
  41.       document.getElementById('clearMovies').disabled = false;
  42.     },
  43.    
  44.     { filter: ['video/quicktime', '.wmv', 'video/avi'] }
  45.   );
  46. }
  47.  

It turns out that YouTube has implemented a multifile upload using Gears which puts this into practice. As someone who uses YouTube a lot to upload files this is very welcome indeed, and I can't wait to see more sites use it now the building blocks are there in a different way (can always use Flash / other controls in the past).

Posted by Dion Almaer at 9:20 am
2 Comments

++++-
4.3 rating from 13 votes

Tuesday, August 26th, 2008

navigator.geolocation: Using the W3C Geolocation API today

Category: Gears, Google, JavaScript, Mapping, Standards

Last week I wrote a simple WhereAreYou? application that used the Google Ajax APIs ClientLocation API to access your location via your IP address.

At the same time, we announced support for the Gears Geolocation API that can calculate your address using a GPS device, WiFi info, cell tower ids, and IP address lookups.

Add to all of that, the W3C Geolocation API that Andrei Popescu of the Gears team is editing. You will notice that it looks similar to the Gears API, with subtle differences. The ClientLocation API is quite different.

To make life easier, I decided to put together a shim called GeoMeta that give you the W3C Geolocation API, and happens to use the other APIs under the hood.

If you have the Geolocation API native in your browser (no one does yet, future proof!) that will be used. If you have Gears, that API will be used, and finally, with nothing the ClientLocation API will be used behind the scenes.

To you the API will look similar:

// navigator.geolocation.getCurrentPosition(successCallback, errorCallback, options)
navigator.geolocation.getCurrentPosition(function(position) {
      var location = [position.address.city, position.address.region, position.address.country].join(', ');
      createMap(position.latitude, position.longitude, location);
}, function() {
      document.getElementById('cantfindyou').innerHTML = "Crap, I don't know. Good hiding!";
});

At least, that is what I would like. Unfortunately, there are a few little differences that leak through.

  • The W3C API only seems to give you a lat / long, so you have to do the geocoding to get address info
  • The Gears API gives you an additional gearsAddress object attached to the resulting position object. This can contain a lot of information on the resulting area (street address to city to ...) however for certain providers the API returns that as null, the same as the W3C standard
  • That gearsAddress object has slightly different information from the address data that the ClientLocation API returns. NOTE: I would love to see this just called 'address' to help the shim.

To give you control when you need it, you can ask the navigator.geolocation object what type it is. navigator.geolocation.type will be null if it is native, but 'Gears' or 'ClientLocation' if a shim kicks in. You can also check navigator.geolocation.shim to see if it is augmented code.

Implementation

There is some fun implementation code in there if you poke around. For example, for the ClientLocation API, when you make a call, it will be added to a queue if the Google Loader hasn't fully loaded yet, and it will kick off that call when finished. Dealing with dynamically creating <script src> as a loading mechanism sure is fun!

I like the idea of jumping straight to the W3C standard and updating the shim as the APIs change. That way, when browsers catch up, the code will still work using the native APIs and you don't have to change a thing.

I also hope that we get general reverse geocoding in place, which would enable me to even take the native "standard" and strap on useful address info to the bare bones lat/long.

Where are you?

Posted by Dion Almaer at 9:14 am
9 Comments

+++--
3.6 rating from 23 votes

Friday, August 22nd, 2008

Gears 0.4 + Mashup of Gears and Google App Engine

Category: Announcements, Gears, Screencast

Hi folks, this is my first guest blog post here on Ajaxian. It's great to join the team.

Gears, the open source browser plugin that teaches web browsers new tricks, has pushed out a new 0.4 release

Andrei Popescu from the Gears team lets us in on some of the nifty new features:

We have added a new Geolocation API, which allows you to build applications that can do new and exciting things based on your users' location. You can query Gears for the user's current location using the getCurrentPosition() method or you can ask Gears to notify you every time the location changes, using the watchPosition() method. Of course, we take privacy issues very seriously, which is why we have a special permission dialog that allows users to decide which Web sites should have access to their location information. If you want to learn more about how the Geolocation API works, please see the Google Code blog post.

In addition, Gears now makes uploading large and multiple files on the web much easier, giving you the primitives to roll a resumable uploader, which means hopefully we can see custom desktop uploaders go away soon. In addition, Gears 0.4 introduces a new thing called Blobs:

Another cool new feature is the Blob API. Unlike strings, blobs let you reference arbitrary binary data — a first for JavaScript! Therefore, blobs can more naturally represent things like files and images, and they can be passed around efficiently. We have updated several existing APIs to work with blobs, such as WorkerPool sendMessage() and HttpRequest send(). And that's not all! We have also extended the Desktop API with a new method, openFiles(), which allows users to select multiple files of a particular content type, and then returns them as blobs for easy uploading or worker processing.

As a final note, Gears is continuing to push new features and experiments like the Geolocation API into the standards process:

Finally, an update on how we are doing on Web standards: in line with our earlier promises, the Geolocation API is a W3C Editor's draft and its current design is a result of open collaboration with many other people and organizations. We plan to continue to drive this standardization effort, as well as work with the community on new Web standards.

I decided to give the new Gears 0.4 APIs a roll to illustrate how powerful they are when put together, mashing them up to create a sample application. In addition, I needed a server-side implementation, so I created a Python server-side that runs on Google App Engine. This mashup is named Upload Movie Tool (not the most creative name, I know ;)

This demo allows you to select multiple movies, and then upload them in a resumable way with feedback using the Gears Blob and File System API. We also use the Geolocation API to figure out what your location is for tagging the video, and the Google App Engine to store everything on the back-end.

Give the demo a try yourself, or check out its source code (see the client JavaScript and the Google App Engine Python). This code is open source so you can feel free to use it as the basis of your own Gears-based resumable uploader/geolocation app.

I put together a screencast where I run through the application. There is a bonus if you make it all the way to the end, with videos showing Dion and I using the new slide that was installed last week in the Google San Francisco office!


 
Disclosure: I work for Google

Posted by Brad Neuberg at 9:50 am
Comment here

++++-
4.4 rating from 15 votes

Friday, August 8th, 2008

Tombs of Asciiroth: GWT, Gears, and AIR enabled RPG Game

Category: Adobe, Games, Gears

Alx Dark has created The Tombs of Asciiroth a fully functional roguelike-meets-puzzle-arcade game.

Asciiroth is a a complete, functional, open source game, written using GWT, and distributed either as an Adobe AIR application, or as a game you can play over the web. In the latter case, it uses Gears to provide saved game support. (So bottom line is you can play it using AIR or Firefox... IE is too slow, Opera/Safari aren't supported by Gears.) It also has a map editor that is distributed as an Adobe AIR application.

It is very cool to see applications written using Ajax, and then using both Gears for in-browser functionality, and AIR for desktop deployment.

Posted by Dion Almaer at 6:22 am
1 Comment

++++-
4.2 rating from 17 votes

Tuesday, July 15th, 2008

PubTools Search: Fast client-side searching with Gears

Category: Dojo, Gears, Interview

Brad Neuberg has built a very easy to use client side search tool called PubTools Search using Gears. The project is open source and provides a great avenue to share knowledge on Gears itself.

To accompany the code, Brad wrote a detailed article:

Did you know that you can use Gearsto do fast, client-side searching of data, similar to a client-side search engine? Gears bundles Full-Text Search (FTS) abilities right into its local, SQLite database. MySpace, for example, uses this feature with their MySpace Mail application, downloading all of a user's messages for fast, client-side search. Because all of the data is local, you can do nifty things like search over the data in real-time as the user types, something that is much harder if you have to query over the network to a server to do the searching.

Would you like to add the same kind of fast, local searching to your own web page and web applications? This article introduces you to PubTools Search and the Gears features that power it, namely Full-Text Search and Workers. PubTools Search is an open source JavaScript library that drops a client-side search engine right into your page. You configure it with basic HTML plus a list of URLs to index. Once loaded, a search form that uses the local Gears full-text search abilities will appear in your page to quickly and locally search over the documents in real time as a user types into the search field.

Brad sat down with me to discuss the project, some of the best practices, and his use of Dojo.

Posted by Dion Almaer at 9:37 am
Comment here

+++--
3.5 rating from 22 votes

Monday, July 14th, 2008

Interview with the Gears on Rails team

Category: Gears, JavaScript, Podcasts, Rails, Ruby

With my Google hat on, I got to interview Michael Marcus and Rui Ma, two recent graduates from a masters program at NYU. They joined me to discuss Gears on Rails, their open source framework that makes it easier than ever to take a Rails code-base offline.

They take the approach of giving you a high level Ruby-ish way of developing your Rails app and having it work offline against local storage.

This means that you end up building actions like this:

RUBY:
    def create_local
     '
       post = Post.build(params("post"));
       Post.create_local(post);
       window.location.reload( false );
     '
    end

They build the local framework on the Jester framework that is a "JavaScript client for REST APIs that uses Rails conventions, and is inspired by Rails' own ActiveResource".

This means that you can write client side code like this:

JAVASCRIPT:
  1.  
  2. Resource.model("Twitter", {format: "json", prefix: "http://www.twitter.com", urls: {list: "/statuses/user_timeline/:username.json"}})
  3.  
  4. Twitter.find("all", {username: "bob"}, function(results) {
  5.   twitters = results
  6. });
  7.  

Listen to the audio interview directly (or subscribe via iTunes).

Posted by Dion Almaer at 4:29 pm
1 Comment

++---
2.9 rating from 16 votes

Thursday, June 12th, 2008

Gears 0.3 Released, and Google I/O videos on Ajax related content available

Category: Ajax, GWT, Gears, Google, JavaScript, Presentation

Some good stuff came out from my employer. First, we have the Gears 0.3 release which includes support for Firefox 3! I have been using it for awhile, and it has been great. The team wanted to get it out before the Firefox 3 launch (planned for June 17th). A plugin like Gears can get deep into browser internals, so it is a challenge to keep up to date as APIs change in beta releases, so it is great to be out there now and I we will take a close look at the final release!

As well as Firefox 3 support, Gears 0.3 includes:

Then, all of the videos from Google I/O sessions have been published.

I put together a playlist that includes Ajax and Gears related content:

Check out the great talks such as:

Gears

GWT

General Ajax

Wow, a lot of material there!

Posted by Dion Almaer at 3:53 pm
7 Comments

+++--
3.9 rating from 15 votes

Thursday, May 29th, 2008

Gears turns one; Old enough to power MySpace message search

Category: Gears

Chris Prince posted about Gears turning one year old. It was launched at last years Google Developer Day, and here we are at Google I/O a short year later.

There was some fun news around Gears yesterday. Firstly, MySpace is using Gears to enable users to search their MySpace messages:

One feature that they were lacking was the ability for MySpace users to actually search their MySpace messages. To go through mail, users have to page through all of their messages until their find the right one. Not optimal to say the least!

They could have tried to do search on the server side, but it can be a very expensive operation, and when you are at MySpace scale, you have to choose your battles.

With server side search out, they looked at doing the work on the client. They ended up with a Gears powered solution that not only searches, but gives back results in real-time as you are typing it in. This means that you can stop typing earlier, as you find what you are looking for.

The MySpace team has been a pleasure to work with, and were very fast to put the pieces together of an Full Text Search datastore, and the WorkerPool to offload the search without hanging the browser.

This is yet another use of Gears that isn't just about "offline", which we are seeing more and more. In fact, Chris Prince gave a talk yesterday that showed prototypes and examples of Gears that people are exploring. There was exciting stuff in there such as:

  • Multiple File Upload: Using the File System API, Chris demonstrated a multiple file upload experience. Selecting multiple files, finally!
  • Resumable File Upload: He then showed a YouTube mockup that showed uploading multiple files, seeing their status, and after a connection died showing how the file resumes and doesn't start from 0% All using a ResumableRequest that sat on top of the Blog API and HttpRequest
  • Find nearby stuff! Next up was a demo that let Chris search for beer, resulting in local places around the Moscone Center. This example used the Geolocation API which uses GPS, Wifi IDs, Cell IDs, and IP address to work out where you are
  • Notifications: Love the Windows toasters, or Growl-ing on the Mac? Chris showed notification examples

Posted by Dion Almaer at 9:23 am
2 Comments

+++--
3.1 rating from 18 votes

Speed Up! with Wordpress and Gears

Category: Gears, Performance

Reposted from my personal techno.blog

I was sitting on the tube a few months ago in London when I looked up to see Matt Mullenweg, Om Malik, and another nice chap whose name escapes me. A little random to bump into them in the middle of London, but we were all in town for the "Future of Web Apps" conference. I had the fortune to chat with Matt a little about Gears and Wordpress. The marriage of which would make me a happy man as I use both technologies on a daily basis (this blog and Ajaxian both run Wordpress).

Brad Neuberg got to working with the Wordpress team, and after a short IRC session they had great progress. At first it can seem daunting "Oh man, won't it be a ton of work to rewrite Wordpress to work offline?"

Speed Up!

This leads us to this post by James who did an "svn up" recently, and saw new support for Gears which lead to some pleasant surprises:

As a side note and introduction to what has been sped up, here’s a little rant.

I personally LOVE the changes that were implemented with WordPress 2.5.

But, some of the new features (and features I’ve just started using now that I use the Visual Editor) just aren’t as cool thanks to the not-so-great internet speeds in South Africa.

For example, if you want to create a link. Every time you click the link icon in the editor’s toolbar, it has to download the same stuff over and over…

Well, it looks to me like the WordPress Google Gears implementation has solved that. The link and the “insert embedded media” popups are now instantaneous!

Thank you to whoever decided to do this.

It also seems that switching between each “pane” in the admin section is a LOT faster… Believe me, working on the South African tubes (via iBurst), this makes a HUGE difference!

I am really proud of the Gears team whenever I open up Google Docs, Reader, Zoho, or any other application that uses Gears to let me access the application while offline. There have been situations where it really saved me, and offline is an important boundary.

However, Gears is so much more than offline, and it is really exciting to see "Speed Up!" as a link instead of "Go Offline?"

This is just the beginning. As the Gears community fills in the gaps in the Web development model and begins to bring you HTML5 functionality I expect to see less "Go Offline" and more "Speed Up!" and other such phrases. In fact, I will be most excited when I don't see any such linkage, and the applications are just better.

With an embedded database, local server storage, worker pool execution, desktop APIs, and other exciting modules such as notifications, resumable HTTP being talked about in the community.... I think we can all get excited.

Kudos to the Wordpress team for finding a great way to increase the performance of their great application, and I can't wait to see how you use Gears in the future.

Posted by Dion Almaer at 8:40 am
1 Comment

++++-
4.6 rating from 17 votes

Wednesday, May 28th, 2008

Addressbook: An example of the Form History Pattern

Category: Gears, Showcase, UI, Usability

One of the examples that Ben and I give in our State of Ajax talk at Google I/O today revolves around form history.

We were thinking about the case for Undo on the Web that Aza Raskin is proposing and it got us thinking about the usage patterns of form data.

An example that got me was the Address Book application on the Mac. I find myself storing past addresses in the general "Notes" section at the bottom, but what if history was built into the system so I could go back in time? This could be a nice metaphor in general that goes beyond undo.

I took this use case and put together a working example that uses Gears to store the history locally so it can be speedy through the history.

The slider component comes from Script.aculo.us, and you can check out all of the code.

In the video below I show the application in action and then do a quick code walk through:

This is just the beginning of course. A slider if fun, but it would probably be more usable if it was simply left and right arrows that click through the versions, or at least putting tacks onto the slider.

Posted by Dion Almaer at 11:34 am
9 Comments

+++--
3.8 rating from 17 votes

Thursday, May 8th, 2008

Growl for Windows and a Web Notification API

Category: Gears, JavaScript

I have talked before about the desire for a Notification API on the Web. As a Mac user, I would love to see Growl from JavaScript, and there have been libraries written from as far back as protoGrowl.

The difference is between a JavaScript API that does notifications on the desktop, versus trying to get little custom notifications inside the browser window itself. I am talking about the former.

Brian Dunnington has developed Growl for Windows, and with his latest version, he allows you to talk to the system via JavaScript.

You can check out the growl.js library.

What was interesting was the implementation side, and the paths Brian went down to get this working. I asked him for his thoughts, and he wrote up the following:

One of the biggest new features in the latest version of Growl for Windows (v1.2 alpha) is the ability to receive notifications from websites running in your browser. i spent quite a bit of time working out the best way to handle this functionality and thought i would share my thought process.

since Growl can already receive notifications over the network, i figured that it would be easiset to build the Web-based notification system on top of that. Growl receives network notifications using a simple protocol over UDP. ok - first hurdle: browsers and javascript dont do UDP, so i figured i would have to go with some kind of add-on. i wanted the solution to work cross-browser, so Firefox extensions and ActiveX plug-ins were ruled out. i also wanted the solution to work for the broadest range of people, so i didnt want to write a custom add-on (a la Gears). i knew that Flash and Silverlight both had networking support, but neither can do UDP, so they were both quickly ruled out.

that left Java as the only other widely-installed cross-browser extension at my disposal. Java obviously has robust networking support, including UDP, so i headed down that path. the biggest problem now was that i have never created a Java applet, nor even written a line of Java code. but the syntax was familiar enough, and i was able to find some good sample code on the net that i was able to mash into a tiny applet that could send UDP packets. it actually worked brilliantly, and i was quite happy with myself for solving the problem so easily.

but of course, it was not that easy. there is that little restriction known as the 'same-origin policy'. running the applet on my localhost worked great, but as soon as i ran it from any other location, i would get a secuirty exception. i tried all kinds of combinations of values for the CODE and CODEBASE attributes, including file:// urls and even encoding the applet code as a data: uri, but i was thwarted at every turn (as so i should have been - the entire reason the restriction is in place is to prevent what i was trying to do). right before i gave up on the applet idea, i had the realization that if i could serve the applet up from the local host, then it would be able to communicate with the local host later. but configuring and installing a simple web server just to serve up an applet seemed like overkill. alas, the Java idea was a dead end.

so, it was back to the drawing board. what did the browser have access to that could bridge the gap? i decided to try a custom protocol handler, similar to the Itunes Music Store (itms://). a couple of simple registry entries and i had my growl:// protocol working. i had a helper process that sat in the background and everytime a growl:// url link was clicked, the browser would pass it off to my handler, along with the original url. i decided that i could pass any information as a JSON-encoded string in that url information. again, it worked great and seemed to be a good solution, but that made me sure that it must have a drawback. turns out the drawback in this case was that there was no way for the browser to know if the protocol handler was installed on the user's machine - if the protocol handler was installed, the browser passed it off nicely and all was good, but if the protocol was not installed, Firefox would present a dialog saying something like 'firefox doesnt know how to open the address because the protocol is not known' (IE and Safari both just returned a 404-type page). since i wanted websites to be able to use the communication feature if the user had Growl installed, but not mess up the experience if they didnt, this was a deal breaker.

i was starting to run out of ideas at this point, but i remembered the idea of serving up the Java applet locally. while i was pondering the details of that solution, i thought 'if i am going to have a local server to serve up the applet, why not skip the applet and just communicate with the local server?'. so i implemented a very simple webserver that runs when Growl is running that can be accessed at something like http://localhost:9889. the idea of using the url to pass JSON was repurposed and soon i was able to pass JSON-encoded Javascript objects to the local server, which code then parse the data and handle it in real application code. i couldnt use ajax to communicate with the local server (same-origin policy strikes again), so i decided to use the hidden iframe technique. i wrote a small js library to abstract everything out, so now you can write code in Javascript that almost mimics the code you would write if you included the Growl libraries in you application code:

JAVASCRIPT:
  1.  
  2. Growl.NotificationType someKindOfNotification = new Growl.NotificationType("some kind of notification", true);
  3. Growl.register("Website Name", [someKindOfNotification]);
  4. Growl.notify(someKindOfNotification, 'Notification from the web', 'this is the description', Growl.Priority.VeryLow, false);
  5.  

of course, receiving notifications from websites opens up the possiblity of spam and other noise, so applications that register from the web have their notifications disabled by default (thus requiring the user to explicity grant the notifications they wish to receive). but that is another topic for another day.

Ed: I decided to make today, "Extend the browser through APIs Day"

Posted by Dion Almaer at 11:38 am
9 Comments

++++-
4.6 rating from 19 votes

Next Page »