» tagged pages
» logout

sorted by: recent | see : popular
Content Tagged with Gears + JavaScript

Ajaxian " Joose expands with new ORM

joose meta object system + gears

json: del.icio.us/tag/json

Creating Offline Web Applications with Dojo Offline Tutorial

Dojo Offline is an open-source toolkit that makes it easy to create sophisticated, offline web applications. It sits on top of Google Gears, a plugin from Google that helps extend web browsers with new functionality.

Dojo: del.icio.us tag dojo

Creating Offline Web Applications with Dojo Offline Tutorial

Dojo Offline is an open-source toolkit that makes it easy to create sophisticated, offline web applications. It sits on top of Google Gears, a plugin from Google that helps extend web browsers with new functionality.

open-source: del.icio.us tag/open-source

More on offline web applications - Google Gears

Google Gears is an open source browser plugin that will enable developers to create offline web applications using JavaScript APIs. As a developer, you'll be able to make an application with the assurance that it will work offline and online across browsers.

open-source: del.icio.us tag/open-source

Creating a Client-Side Search Engine With Gears

This article describes how Gears can be used to create a client-side search engine plugged right into your web page.

Dojo: del.icio.us tag dojo

Creating a Client-Side Search Engine With Gears

This article describes how Gears can be used to create a client-side search engine plugged right into your web page.

Firefox: del.icio.us/tag/firefox

Growl for Windows and a Web Notification API

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"

Ajax: Ajaxian

Location APIs: The Discussions

The Gears community is discussing a Geo Location API, which Aaron Boodman mentioned "was recently proposed to the W3C WebAPI group."

Aza Raskin just posted today about Geolocation in Firefox and Beyond which covers his thoughts on an API.

I thought it would be fun to look at the proposed APIs:

Gears Examples

JAVASCRIPT:
  1.  
  2. var geo = google.gears.factory.create('beta.geolocation');
  3.  
  4. // Get the position.
  5. geo.getCurrentPosition(function(position) {
  6.   updateMap(position.latitude, position.longitude);
  7. });
  8.  
  9. // Watch the position over time.
  10. var watchId = geo.watchPosition(function(position) {
  11.   updateMap(position.latitude, position.longitude, position.accuracy);
  12. });
  13.  
  14. geo.clearWatch(watchId);
  15.  
  16. // Only get the position if the last known position is more than a minute old.
  17. var now = new Date().getTime();
  18. var threshold = now - 60000;
  19.  
  20. if (geo.lastPosition &&
  21.     geo.lastPosition.timestamp.getTime()> threshold) {
  22.   updateMap2(geo.lastPosition);
  23. } else {
  24.   loc.getCurrentPosition(function(position) {
  25.     updateMap2(position);
  26.   });
  27. }
  28.  

Aza Examples

JAVASCRIPT:
  1.  
  2. var geolocator = new navigator.GeolocationRequest();
  3. geolocator.request(function(location) {
  4.   alert( location.latitude + ', '+ location.longitude + ", " + location.accuracy );
  5. });
  6.  
  7. var geolocator = new navigator.GeolocationRequest();
  8. geolocator.request({
  9.   success: function(location) { /* We've got the location! */ },
  10.   error: function(err){ /* There was an error getting location. */ },
  11.   accuracy: "neighborhood"
  12. });
  13.  

There is also a lot of talk around privacy and accuracy, and Apple has their own location manager too.

I hope that we can unify some of this, and give the browsers a geo location API soon. One simple JavaScript abstraction will enable a lot of great apps.

Ajax: Ajaxian

Joose expands with new ORM

Malte has continued to work on Joose, his meta object system for JavaScript. He has added a lot of documentation, including cookbooks that tell the story nicely. He also told us about a feature that is near and dear to my Google heart:

Joose now includes a simple object relational mapper for the Gears database in the examples section. If you have Gears installed, you can run it.

It will run its test suite and then display a class browser that displays the contents of a table for classes that represent a database
tables. The example has two entities (Car and Person in the MyEntities module).

Declaring the entities with this proof-of-concept OR-mapper looks like
this:

JAVASCRIPT:
  1.  
  2. Module("MyEntities", function (m) {
  3.  
  4.    Class("Car", {
  5.        isa:  ORM.Entity,
  6.  
  7.        has: {
  8.            owner: {
  9.                metaclass: ORM.HasOne,
  10.                isa:       function () { return m.Person }
  11.            }
  12.        },
  13.  
  14.        classMethods: {
  15.            tableName: function () {
  16.                return "car"
  17.            }
  18.        }
  19.    })
  20.  
  21.    Class("Person", {
  22.        isa:  ORM.Entity,
  23.  
  24.        classMethods: {
  25.            tableName: function () {
  26.                return "person"
  27.            }
  28.        },
  29.  
  30.        has: {
  31.            mother: {
  32.                metaclass: ORM.HasOne,
  33.                isa:       function () { return m.Person }
  34.            },
  35.  
  36.            cars: {
  37.                metaclass:  ORM.HasMany,
  38.                isa:        function () { return m.Car },
  39.                foreignKey: "owner"
  40.            }
  41.        }
  42.    });
  43. });
  44.  

And some example usage:

JAVASCRIPT:
  1.  
  2. // Create the mother
  3. var mother = new MyEntities.Person();
  4. mother.name("elke");
  5. mother.city("Elmshorn");
  6. mother.save();
  7.  
  8. // Create the son
  9. var person = new MyEntities.Person();
  10. person.name("malte");
  11. person.city("Hamburg");
  12. person.mother(mother); // set the mother
  13. person.save();
  14.  
  15. // Give the son 10 cars :)
  16. for(var i = 0; i <10; i++) {
  17.     var car = new MyEntities.Car();
  18.     car.model("3."+i);
  19.     car.brand("bmw");
  20.     car.owner(person);
  21.     car.save();
  22. }
  23.  
  24. // refetch the person from the db
  25. var personFromDb = Entities.Person.newFromId(person.rowid());
  26.  
  27. alert(personFromDb.mother().name()) // will alert 'elke'
  28. alert(personFromDb.cars()[0].brand()) // will alert 'bmw'
  29.  

Ajax: Ajaxian

gearsAJAXHelper: Using Gears as an optional speed boost

Ben Lisbakken, who sits 100 feet away from me, developed gearsAJAXHelper, a library that bridges the AJAX search and feed APIs with Gears, to get a speed improvement:

We decided it would be cool to write a small library to make it easy for you AJAX APIs developers to write quick-loading, always fresh searches/feeds. The gearsAJAXHelper has two main features - it allows you to store and return key/value pairs from the local database, and it allows you to choose whether you want all resources files on the page (images, CSS, Javascript, HTML) to automatically be cached in the Gears cache.

The key/value pair database feature let's you store the query/results as a key/value pair. Then, the next time the query is made, the results can be served from the database while fresh results are being retrieved. This dramatically reduces the latency in queries/feed grabs.

The (optional) automatic cacheing of resource files will make it so that each time the user visits your webpage they will be getting resources served from their Google Gears cache, not new versions from the internet. Be careful when using this feature, as you might not want stale content to be served. There is also a refresh function, to clear the Google Gears cache of old files.

You can take a look at the sample, that saves the content for presidential candidates so if you click back on an area, you get instant loads.

gearsAJAXHelper Example

The bulk of the API is:

JAVASCRIPT:
gearsAJAXHelper.initialize("election", "election", false);
gearsAJAXHelper.storeKeyVal(key, value);
gearsAJAXHelper.returnKeyVal(key);
gearsAJAXHelper.refresh();
 

This example shows how you can optional add super-caching to your applications with technology such as Gears. It 'aint just about offline!

NOTE: JavaScript Hackathon

If you are in the bay area, and like JavaScript (and if not, why are you on this blog!), then join us at Google this Friday for a Google Developer Hackathon focusing on JavaScript.

There will be two sessions -- one from 2:00PM - 5:30PM and another from 6:00PM - 10:00PM. You are welcome to stay for both. Please RSVP

Where: Google Campus: 1600 Amphitheatre Pkwy, Mountain View, CA 94043. It will be held in the Seville Tech Talk room.

Ajax: Ajaxian

Server Side JavaScript Databases Access

Reposted from my personal blog

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:

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

I wrapped database access in proxy objects, such as:

JAVASCRIPT:
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:

JAVASCRIPT:
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:

JAVASCRIPT:
// 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).

Ajax: Ajaxian

Drinking offline at the Happy Hour while being openly social

Over in Gears land I met with Chandra Patni, the creator of happyhour:

Open Social Happy Hour is a port of Open Social Container Sample that employs Google Gears for persistence. It allows data coherency of open social widgets across browser windows.

As I said on the Gears blog:

The motivation for the project was speeding up the development cycle of OpenSocial components by allowing developers to bypass talking to a production server, or even a local one. Load up an HTML file and you are good to go. This also helped when getting designers into the mix as they could just style the HTML and they were done.

The container supports Caja, and adds useful minor features such as munging between a JavaScript date, and an ISO 8601 date that SQLite uses:

JAVASCRIPT:
  1.  
  2. opensocial.HappyHourContainer.prototype.toISO8601String = function (date) {
  3.     var