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):
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.
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:
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!
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:
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.
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.
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.
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!
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.
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.
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:
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:
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!
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.
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
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.
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.
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.
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:
Growl.notify(someKindOfNotification, 'Notification from the web', 'this is the description', Growl.Priority.VeryLow, false);
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"