Mar 19

Gears Future APIs: OpenID and OAuth

Gears, Tech, Web Browsing with tags: , 14 Comments »

Single Sign On

When I was looking over Brad Neuberg’s Paper Airplane thought experiment I noticed the single sign on feature, where you login to the browser, and then you are done.

I realized that this is what I actually want. Having one signon via OpenID is really nice. It allows me to plug in “http://almaer.com” as my identifier. However, I always have to go around finding the OpenID option (if it exists) and put that in.

What I really want is for the browser to do that work for me. If a site groks OpenID the browser should be able to pass that over without having me intervene at all. It could hide the entire login process if we came up with a microformat to let all sides know what is going on.

It would be a breath of fresh air to be able to jump through sites leaving comments on blogs, and checking out my todo list, all without me once having to actually login.

I wonder if a Gear could be made with a complementary microformat / server side handshake that could then give us single sign-on in all of the browsers.

As Brian McCallister suggests:

<link rel="openid-auth" href="..." />

Other Future APIs

Disclaimer: This is me rambling about APIs and tools that I would love to see in Gears, or the Open Web as a whole. Do you have ideas for cool Gears that make the Web better? Let us know!.

Mar 07

Crying over “Becoming Jane”, College Gears, and Pizza

Gears, Tech, Travel 3 Comments »

Becoming Jane

I have failed my Wired “traveling too much test”. I buy Wired at the airport, and if I go on a trip and already have read the current copy, I am traveling too much.

The effects of travel are even more wearing when you have an uncomfortable flight. I am on my way back from a mini tour of the mid-west with Brad Neuberg. We hit the University of Illinois Urbana-Champaign, and the University of Michigan, to chat with students about Gears.

It probably wasn’t the smartest time of year to have a March trip, and it was bloody freezing most of the time. This also lead to delays on 4 out of 6 of my flights. Ah the fun.

Due to a cancelled flight I got put on another one, and ended up at the back of the plane in a tight corner. There was no way I could use the ole laptop, so I was putting all of my hope in the in-flight movie.

Unfortunately, my hope back fired:

1. The View

No, fortunately they didn’t broadcast The View, but I was in the position where I could barely see a television set in the sky. A full third of the set was obscured by the curve in the plane itself. I looked down the line to the next one to see if a smaller view would give me more content, but the curve kicked in for all sets. The colour on the set closest to me was off too. It reminded me of the monochrome games that I loved on the ZX Spectrum. Oh ye olde rubber keyboard. Q-A-O-P-Space were all very worn!

2. The Content

When the entertainment kicked in, we got to see Ebert & Roeper tell us about the movie we are about to see. You get the added bonus of showing half of the actual movie as they pre-explain. Just what you need. In this case the film they were blathering about was Becoming Jane. When I am on a plane I tend to revert a few years and want some silly shoot ‘em up entertainment. The new Rambo, where Sly literally knocks someones block off would have been a good choice. But a period piece about Jane Austin? Do I really want to find out about the REAL Darcy?

Anne Hathaway plays the part, and although she does a fair job at it… all I can think about is that Princess movie that she was in with Mary Poppins. Somehow it feels like I have seen that movie, even though I never actually have. It has been on TV so often that I have picked 80% of the picture as I flick through channels over time.

3. The Tear

Being stuck in the back of the plane meant that I was hot. When you are hot on the plane your only choice is to turn up the minute air jet from above. I turned it up to the max, which barely helped, but had a bad side effect. It kept making the duct in my right eye release saline. It was streaming.

This meant that the others in my row thought I was crying over the plight of Jane and the loss of her love due to pride and prejudice. Oh the shame!

But, back to the reason why I was putting up with the flights, with their re-reads of Wired. Reading about the cockiness of 37signals never gets old!

We made it to champaign

It was really cool to start off the trip in Champaign. Talking about Gears, at the birthplace of the browser was pretty cool, especially on the day that Marc Andreessen blogged about hanging with Barak. These kids could do that too. Brad and I got to tour the ACM where we saw a bunch of cool hacks and fun robotics. These students were smart.

I felt lucky to get to the event on time. After I finally got into the airport, which is tiny, I waited for over an hour for a cab that never came, so I ended up jumping on a bus and trying to work out what the hell I was doing. I made it to Brad’s hotel in time for us to walk over to the event.

At the Gears event itself we had a varied audience. On one side we had students who had never touched JavaScript. On the other side we had Mozilla contributors, and Yahoo! Ajax Map interns. It made me realise how I could have gotten just a touch more out of my college years ;)

Pizza destroyers

A few delays, and many red carpet club hours later, I was in Ann Arbor. We had an equally good time with the gifted students that showed up. This crew didn’t wolf down the pizza in 30 seconds flat like the fighting Illini the day before. They were equally smart though, and I was really excited to see postings by one of them to the Gears list. He is porting Gears to 64bit Linux. Nice!

The Computer Science and Engineering building also has the most geeky cafe ever:

Geekiest university cafe ever

Thanks to the students from both schools for showing up, and I can’t wait to see what you come up with.

Mar 05

IE 8 and Google Gears

Gears, Microsoft, Tech with tags: , 4 Comments »

The IE 8 updates are out, and there are some great features that relate to Gears. Also, a lot of the features are standards based so we will see the functionality in other browsers too.

Six connections per host

Yay! The 2 connection limit has been so painful for rich Ajax development, especially when you get into advanced work like Comet. This small change is going to be huge.

Connectivity Events

Connectivity events allow websites to check when the user is connected to the network and receive notification of connectivity changes.

This is fantastic. A lot of developers want this functionality, and we have held off implementing it in Gears as it is actually quite tricky to do correctly. Having a version of this in the browser will be great, and Gears applications can leverage it.

DOM Storage

The simple storage for offline applications. I could see someone writing an app that uses DOM storage for simple cases, and Gears for the more advanced (SQL vs. name/value pairs).

Cross Domain

Cross domain is actually going to happen in 2008, which is very exciting indeed. By jumping in we can iron out the issues and end up with a real mashup world that is more than read only tools. I am assuming that this is also using standards such as postMessage.

Cross-domain communication is an integral part of AJAX development
and mashup Web applications. Internet Explorer 8 includes two
features to help you build cross-domain communications that are safe
and easy to implement:

  • With Cross-domain Request (XDR), developers can
    create cross-site data aggregation scenarios. Similar to the
    XMLHttpRequest object but with a simpler programming model, this
    request, called XDomainRequest, is the easiest way to make anonymous
    requests to third-party sites that support XDR and opt in to making
    their data available across domains. Three lines of code will have
    you making basic cross-site requests. This will ensure data
    aggregation for public sites (such as blogs) will be simple, secure
    and fast.
  • Cross-document Messaging (XDM) APIs allow
    communication between documents from different domains through
    IFrames in a way that is easy, secure and standardized.
Mar 03

xssinterface and Google Gears

Gears, JavaScript, Tech with tags: 1 Comment »

I mentioned the cross domain library, xssinterface, created by Malte Ubl on Ajaxian the other day.

His library abstracts on top of postMessage() and browser hacks to give you cross domain work. No sooner than I say “It would be nice if the library used cross domain workers if Gears is installed.” than Melde comments “Thanks for the hint to google gears. It is now implemented in trunk :)”. How about that for service!

Below is his first version that uses cross domain workerpools and the database to keep a message queue going. Very nice!

var wp       = google.gears.workerPool;
wp.allowCrossOrigin();
wp.onmessage = function(a, b, message) {  
  var origin = new String(message.origin);
  var parts  = origin.split("/");
  var domain = parts[2];
  parts      = domain.split(":"); // remove port
  domain     = parts[0];
 
  var recipient = domain;
  var channelId = message.text;
 
 
  var db = google.gears.factory.create('beta.database');
  db.open('database-xssinterface');
  db.execute('create table if not exists XSSMessageQueue' +
     ' (id INTEGER PRIMARY KEY AUTOINCREMENT, recipient_domain TEXT, channel_id TEXT, message TEXT, insert_time INTEGER)');
 
  // delete (and thus ignore) old messages
  var maxAge = new Date().getTime() - 2000;
  db.execute('delete from XSSMessageQueue where insert_time < ?',[maxAge]);
 
  // find new messages for me
  var rs = db.execute('select id, message from XSSMessageQueue where recipient_domain = ? and channel_id = ?', [recipient, channelId]);
 
  // there is a new message for the recipient
  if (rs.isValidRow()) {
          var id   = rs.field(0);
          var text = rs.field(1);
          db.execute("DELETE from XSSMessageQueue where id=?", [id]); // unqueue message
          wp.sendMessage(text, message.sender)
  }
 
  rs.close();
}
Feb 28

Gears and AIR: The Open Source Difference

Adobe, Gears, Tech 2 Comments »

AIR had their big launch this week, and I am very happy for the folks over there to have that 1.0 out in the wild. It is a huge deal. I really like the idea of taking Web technology and development skills, and expanding them out from the desktop browser into new worlds such as the mobile device and the desktop itself.

Who knew that little XHR would grow and the Ajax universe would expand in such a way that you can imagine a time 2 to 10 years from now where the world of Web vs. desktop vs. mobile no longer make sense. Many universes are combining. Surely in the future we will have APIs and services. You will be able to use JavaScript to talk to native services on a computer, as well as services in a cloud. It will all start coming together.

With Gears, you can start to see this vision. Starting with LocalServer, Database, and Workerpool; then maybe seeing notification, crypto, messaging, location, shortcut, and more.

Here we see more and more services being made available to the Web developer in a way that makes sense to them.

AIR has a set of APIs too of course, but there are a couple of differences.

1. Desktop focus

AIR is very much about building desktop applications using Flash and Ajax. If you want a desktop application, you can choose AIR as a choice versus Swing, WPF, Cocoa, etc.

Gears is about adding more value to the browser itself, and letting you keep building your Ajax applications, just with more power. We will constantly be adding more and more APIs and services for you to work with.

2. Control

Adobe develops AIR, and they have plans for the future, which I am sure are constantly changing. You have the power to change their mind by being vocal customers.

Gears is an entirely open source framework. Although Google has the majority of developers on the project, you have different advantages, due to the open source model:

  • If you are running into an issue, you can get down to the metal and look at the source code. You can even contribute a fix!
  • You can scratch your own itch. Let’s say your company has a particular Gear that you would really like to see. You can create that Gear yourself. If it is generally useful (which is normally the case) then you can propose it to the Gears community, and it can get into the Gears distribution itself. That’s right guys, you can write your own Gears. Of course, there is no guarantee that your Gear will get in the distribution. If that is the case, you still have options though. You can distribute your own MyGears. Hopefully it wouldn’t come to that, but at least you have the option

This is why it is a big deal that Gears is open source. I know that it is hard when a company like Google is behind it, but I hope to see some non-Google Gears getting out there and attaching themselves to the browser service bus that is “Gears”.

Gears and AIR

Gears and AIR are very different, and although there is an overlap, they are complementary too. I would love to see some convergence in the future where Gears and AIR APIs join together. That would be a win win for everyone in my opinion. I would also love to see AIR open sourced, which isn’t a crazy idea given how Adobe has been moving in that direction for many of their projects.

Feb 21

Google Gears API supported by Aptana Jaxer

Gears, Google, JavaScript, Tech with tags: , No Comments »

Man I love it when I can delete code. Seeing the line count go away and leaving a small amount of text is a sight for sore eyes. I got to delete a lot of code today thanks to the kind folks at Aptana.

I recently wrote a shim that allows the Google Gears API to run as is on the server side. It wraps the Gears Database API with the Jaxer one.

What is particularly cool about this is that you can then write some code and:

  • If the user has Gears installed, it runs client-side
  • If the user doesn’t have Gears installed just run it on the server

I want to setup a nice way to make this trivial to setup.

The majority of the code was a simple wrapper around the result set, so Aptana decided to directly support the Gears API itself which allowed me to get rid of it all!

This makes the shim as simple as this:

// -- Wrap this code so it is available if using a proxy call
function oncallback() {
 
  // Make up the namespaces to mimic Gears and a place for Jaxer holders
  google = {}; google.gears = {}; google.gears.factory = {}; google.gears.jaxer = {};
 
  // Create sets up a database instance to be used
  google.gears.factory.create = function(className, version) {
    if (className.indexOf('database') < 0) {
      throw new Error('I can only do Database work right now');
    }
    return new google.gears.jaxer.Db();
  }
 
// -- The Database Wrapper
  google.gears.jaxer.Db = function() {
    this.db = null;
  }
 
  google.gears.jaxer.Db.prototype.open = function(name) {
    this.db = new Jaxer.DB.SQLite.Connection({
      PATH: 'resource:///../data/' + name + '.sqlite',
      CLOSE_AFTER_EXECUTE: 'open'
    });
  }
 
  google.gears.jaxer.Db.prototype.execute = function(sqlStatement, argArray) {
    var rs = (argArray) ? this.db.execute(sqlStatement, argArray) : this.db.execute(sqlStatement);
    return rs;
  }
 
}

Philip Maker has also taken GearsORM and made it work with Jaxer. Very cool indeed.

Feb 05

Google Gears Database API on the Server

Gears, Google, JavaScript, Tech with tags: , , 2 Comments »

As soon as I started to play with Aptana Jaxer, I saw an interesting opportunity to port the Google Gears Database API (note the Gears in the logo!)

If I could use the same API for both client and server side database access, then I can be enabled to do things like:

  • Use one API, and have the system do a sync from local to remote databases
  • If the user has JavaScript, use a local database, else do the work remotely
  • Share higher level database libraries and ORMs such as Gears DBLib for use on server side data too

I quickly built a prototype to see if this would all work.

The Jaxer shim of the Gears API was born, and to test it out I took the database example from Gears itself and made it work.

To do so, I only had to make a few changes:

Run code on the server

I changed the main library to run on the server via:

<script type="text/javascript" src="gears_init.js" runat="server"></script>

I wrapped database access in proxy objects, such as:

function addPhrase(phrase, currTime) {
  getDB().execute('insert into Demo values (?, ?)', [phrase, currTime]);
}
addPhrase.proxy = true;

This now allows me to run the addPhrase code from the browser, and it will be proxied up to the server to actually execute that INSERT statement.

This forced me to separate the server side code from the client side code, which is a better practice anyway, but it does make you think about what goes where. In a pure Gears solution I can put everything in one place since it all runs on the client.

Create the new gears_init.js

A new gears_init.js acts as the shim itself. Instead of doing the typical Gears logic, it implements the Gears database contract. This wasn’t that tough, although there are differences between the Gears way, and the Jaxer.DB way. The main difference is to do with the ResultSet implementation, where Gears goes for a rs.next()/rs.field(1) type model versus the Jaxer.DB rs.rows[x] model.

I actually much prefer Gears DBLib as it hides all of that, and just gives the programmer what he wants… the rows to work on.

oncallback magic

In the current Jaxer beta, I ran into an issue where I wanted the Gears library to just “be there” for any proxy requests.

You have to think about the lifecycle of a Jaxer application, and the documentation tells you what you need to know to work around the issue.

In this case, I wrapped the code in:

function oncallback() {
  // create the wrapper here
}

This is less than idea, and Aptana is playing with nice scoping which would enable you to just say “hey, load this library once and keep it around for the lifetime of the server | application | session | page”. That will be very nice indeed.

You can do a little bit of this by opening up your jaxer_prefs file and adding the resource for your file:

// This option sets up an html document that will be loaded
// everytime a callback is processed.  This has to be a local file.
// If not specified, an empty document will be loaded.
// pref("Jaxer.dev.LoadDocForCallback", "resource:///framework/callback.html");

Future…

This is just the beginning. As I mentioned at the beginning, I am interested to see where you can take this to handle clients who do not support JavaScript, and also to deal with synchronization with minimal code (sync from local to remote with exactly the same SQL API).

Feb 03

Checking the network to handle offline applications

Gears, Tech with tags: 1 Comment »

One of the common questions we here in Gears land is, how to handle checking if an application is online or offline. This is a trickier problem that you may think at first. What does it mean to be offline?

The Autodesk guys talked about this a little in their interview. They have the notion of online and offline, which is just a flag. They then have the notion of connected or disconnected, which they test at regular intervals.

Mathew Foster recently posted the code that he uses to handle this situation. He basically ported the Dojo Offline work to Prototype, and you end up with a library that you can use like this:

var netCheck = new NetworkDetection("blank.php");
 
netCheck.addEventListener("online", function(eAja) {
  $("display").innerHTML = "online";
});
netCheck.addEventListener("offline", function(eAja){                                          
  $("display").innerHTML = "offline";                                      
});

Some other folks also put their thoughts out there.

Firstly, Dimitri Glazkov (who is on fire recently btw) posted his monitor script:

    // provides connection monitoring
    // controller
    function Monitor() {
 
        var me = this;
 
        //  triggered when connection changes
        //  sends as parameter:
        //      online : Boolean, true if connection became available,
        //          false if connection is broken
        this.onconnectionchange = nil;
 
        // starts the monitoring
        this.start = function() {
            try {
                wp = google.gears.factory.create('beta.workerpool', '1.0');
            }
            catch(e) {
                return false;
            }
            wp.onmessage = function(a, b, message) {
                if (message.sender == id) {
                    // only two messages: 
                    // first [f]ailure to connect 
                    // or back [o]nline
                    var text = message.text;
                    if (text == 'f') {
                        me.onconnectionchange(false);
                    }
                    else if (text == 'o') {
                        me.onconnectionchange(true);
                    }
                }
            }
            id = wp.createWorker(String(worker) + ';worker()');
            // send a message to the worker, identifying owner's id
            wp.sendMessage(window.location + '?poll', id);
            return true;
        }
 
        function worker() {
            var POLLING_INTERVAL = 2000;
 
            var wp = google.gears.workerPool;
            var url;
            var parentId;
 
            var first = true;
            var online;
 
            var timer = google.gears.factory.create('beta.timer', '1.0');
 
            wp.onmessage = function(a, b, message) {
                url = message.text;
                parentId = message.sender;
                poll();
            }
 
            function poll() {
                var request = google.gears.factory.create('beta.httprequest', '1.0');
                request.open('HEAD', url);
                request.onreadystatechange = function() {
                    if (request.readyState == 4) {
                        try {
                            if (request.status == 200) {
                                if (!online) {
                                    online = true;
                                    wp.sendMessage('o', parentId);
                                }
                            }
                        }
                        catch(e) {
                            if (online || first) {
                                online = false;
                                first = false;
                                wp.sendMessage('f', parentId);
                            }
                        }
                        wp.sendMessage('d', parentId);
                        timer.setTimeout(poll, POLLING_INTERVAL);
                    }
                }
                try {
                    request.send();
                }
                catch(e) {
                    if (online) {
                        online = false;
                        wp.sendMessage('f', parentId);
                    }
                }
            }
 
        }
 
        function nil() {}
    }

Gears co-lead Aaron Boodman also put his hat in the ring with a solution that uses the Gears HttpRequest object, and a clean use of onerror:

function monitorOnlineness(url, onlinenessChanged) {
 var interval = 1000; // check network once a second
 var onlineness = null;
 var timer = google.gears.factory.create('beta.timer');
 var timerId = null;
 
 function check() {
   timerId = timer.setTimeout(function() {
     var req = google.gears.factory.create('beta.httprequest');
     req.onload = function() { onlinenessChanged(true); }
     req.onerror = function() { onlinenessChanged(false); }
     req.open("HEAD", url);
     req.send(null);
   }, interval);
 }
 
 function updateOnlineness(val) {
   if (onlineness !== val) {
     onlineness = val;
     onlinenessChanged(val);
   }
   check();
 }
 
 function cancel() {
   if (timerId) {
     timer.clearTimeout(timerId);
   }
 }
 
 return cancel;
}

You quickly find that there are many solutions, and that they depend on what you really need to do for your application use case. I am still personally hopeful that an 80% solution is placed into Gears itself as a starting point….

Jan 22

Visualizing the business importance, and slow moving development, of the Web

Gears, Tech, Web Browsing, Web Frameworks 2 Comments »

Brad was speaking on a panel at a recent conference and asked a couple of questions, and the answers visually said it all:

Raise your hand if your business relies on the Web in some way:

Group with raised hands

Raise your hand if you think that the Web is moving fast enough as a development platform:

Group without raised hands

Jan 15

Gears Future APIs: Services / Daemon API

Gears, Google, JavaScript, Tech, Web Frameworks with tags: 4 Comments »

Daemon

One of the comments on the Notification API was by lunatix:

It would be really useful if we could set a background javascript process (via WorkerPool) that continue to run after browser is closed and which is able to send System Tray notification.

I would definitely like to see an API (or as part of the Notification API, or WorkerPool in general) that allows you to attach some work to a process that can always be running, or be scheduled to run (a la cron).

This can be particularly important with Offline and syncing that comes along with it. Imagine a world where Gmail worked offline. The need for a service that downloads email in the background may not be that important, as people tend to leave a tab with Gmail running in it.

But, if you take Zoho Writer as another example. You may not have Writer open all the time. You open it when you get a new document that you want to work with. Let’s take a look at a scenario:

  • Bob edits a shared document that discusses the travel for the next quarter
  • Bob closes the document and keeps working for the rest of the day
  • Meanwhile, Harry, Linda, and Chou all edit the document
  • Bob goes offline and heads to the airport
  • Bob opens up the document on the plane

Does Bob just have the document with content from his step? If there was a service that was running in the background, it could detect the changes and bring them down. Then Bob would have the latest and greatest up to when he turned off his computer.

The obvious issues

Of course, a key issue here will be making sure that this isn’t abused, and what UI do we give users. I personally never like it when I find services running on my machine when I closed an app. You know the culprits…. Quicktime and the like. I want to be able to know about every service and prune the list, but also not be burdensome for the average Joe. Does this mean that the system tray notification system has a way to see all of the services?

Also, I don’t want some rogue daemon taking up my resources, and of course, it can’t have special access to things such as key logging ;)

You can write Gears too!

A few people have emailed me about potential Gears saying that they wish they could build a new Gear. Remember, Gears is a true open source project, so you CAN write your own Gears. If you want to implement a new API, start out by emailing the group with your proposal and then get to it!

Other Future APIs

Disclaimer: This is me rambling about APIs and tools that I would love to see in Gears, or the Open Web as a whole. Do you have ideas for cool Gears that make the Web better? Let us know!.