Ajax offline with Gears, a tutorial

Running Ajax offline and use the browser as a platform for application is rather simple, to do that you may install the Gears plug-in and use the scripts included in this basic tutorial as a starting point.

This tutorial is simple: our first application displays only the message "Hello World!", but it does so without Internet connection when you type the URL of the demonstration page ...

Then we go further with the image gallery offline and later we will see how to add buttons, menus, lists and any other widget ...

IMPORTANT: Gears is a portable solution, usable immediately, but since Google has choosen to move to HTML 5, for long-term development, you should use the HTML 5 APIs instead.

Why Ajax offline?

When you use Ajax offline, it becomes possible to use a web page as GUI for a script running locally. In fact as we explain in the second demonstration, the system becomes a way to install applications and update them instantly, in a very simplified way.

It is important that the same application works on a reactive manner, either offline or online, hence the value of combining these two technologies, Gears and Ajax.

Overview

To build an offline application, you must use the Gears API that is downloaded with the plug-in.
Its overall architecture uses the following components:
- LocalServer, which provides synchronization between the data on the server and the local copy.
- Workerpool which controls the execution of JavaScript code.
- A Desktop module to run the application on the desktop.
- A SQLite database to reproduce locally the contents of an SQL database on the server.
- A library that includes JavaScript, XMLHttpRequest and a Timer.
In addition, a geolocation module adapts the application to the country.

Structure of a Gears page

A page must include some Gears scripts and eventually have an area to display information on the status of Gears.

Including the scripts

<script type="text/javascript" src="gears_init.js"></script>
<script type="text/javascript" src="gears_offline.js"></script>
<script type="text/javascript" src="ajax-gears.js"></script>

gears_init.js initializes Gears, but does not prepare the offline mode.
gears_offline.js initialize the offline mode or return online by offering the choice to the user, it is in connection with the buttons.
ajax-gears.js is our script to combine Ajax and Gears.

Body of the page

<body>
   <div id="textOut"></div>
   <button onClick="createStore()"> Go offline </button>
<button onClick="removeStore()"> Return online </button> </body>

The page contains two buttons. They call the functions createStore call () and removeStore () to go offline or online.
The textOut field displays messages about the state of Gears.

Option: Since we've added a script, we have chosen to initialize Gears by calling the init () function from it, otherwise an attribut would be added to <body> tag:

<body onload="init">  

Automatic offline

You can call the createStore function () after the initialization of Gears, and remove the two buttons, for the application to run directly offline. But if we want to update the scripts and other resources, the buttons are needed.

The Gears code

The gears_init.js file is provided by Google and the programmer does not need to care about it.
The Gears_offline.js file is a modified version of the go_offline.js file from Google.

Functions and variables in gears_offline.js

init()

Creates a local storage space managed by Gears.

createStore()

Stores the documents locally. It depends on the manifest file that holds the list of files and scripts involved.

removeStore()

Redirects the user to the online site and removes the local space and its contents.

In addition to these functions, the file contains the variables STORE_NAME and MANIFEST_FILENAME. The second is assigned the name of the manifest file, manifest.json by default.

The manifest.json file

In the example, it contains the following lines:

{
"betaManifestVersion": 1,
"version": "1.0",
"entries": [
{ "url": "ajax-offline-demo.html"},
{ "url": "gears_offline.js"},
{ "url": "gears_init.js"},
{ "url": "ajax-gears.js"}
]
}

The URLs are those of the web application, in this case a simple demo page, and the scripts. Other files necessary for the application must be mentioned.

The Ajax code

If Gears is installed, the Ajax code used is the one that is included in the Gears framework. Otherwise we must return to the classic XMLHttpRequest object recognized by the browser.
To do this we define a function that creates an instance depending on the available object recognized by the browser:

function gearsCreate()
{
     var xhr = google.gears.factory.create('beta.httprequest');
     if(!xhr)
     {
         try  {   xhr = new ActiveXObject('Msxml2.XMLHTTP');   }
         catch (err1) 
         {
               try { xhr = new ActiveXObject('Microsoft.XMLHTTP');  }
               catch (err2) 
               {
                  try  {  xhr = new XMLHttpRequest();   }
                  catch (err3) 
                  {
                     xhr = false;
                  }
               }
         }
   }
   return xhr;
}  

The attributes and methods of the object, those of Gears, XMLHttpRequest or ActiveX, are the same and the rest of the code is common to the three cases.

Example with GET

The exemple loads a text file whose name is "xhr-demo.txt."

var xhr = createXHR();
xhr.open('GET', "xhr-demo.txt");
xhr.onreadystatechange = function() 
{
      if (xhr.readyState == 4) 
      {
           alert(xhr.responseText);
      }
};
xhr.send();

The call to createXHR() creates an instance of an Gears/XMLHttpRequest/ActiveX object assigned to the xhr variable.
The contents of the file is loaded into xhr.responseText and displayed it in an alert box.

Small demonstration with the GET method

To begin simply, an Ajax application is defined that loads just the contents of a file with the GET method and display the content in the page.

It uses the createXHR() andgearsGet() functions in the preceding code, but the name of the file to load is given as parameter along with the name of a function that processes the contents of the file once loaded.

function gearsGet(xhr, fun, filename)
{ 
     xhr.open('GET', filename);
     xhr.onreadystatechange = function() 
     {
         if (xhr.readyState == 4) 
         {
               fun(xhr.responseText);
         }
     };
    xhr.send();
}
function storing(result)
{
     var storage = document.getElementById("storage");
     storage.innerHTML = result;
}
function demo()
{
     init();  // starts gears
     var xhr = gearsCreate();    // creates an XHR object 
     gearsGet(xhr, storing, 'xhr-demo.txt');    // loads a file on the server
}   

window.onload=demo;

The demo() function initializes Gears, creates an instance and calls the gearsGet() function with in arguments the name of a file to load and the storing function to treat the content.

The storing() function displays the contents of the file in an area of the page dedicated to this whose ID is storage.

Robots gallery offline

This demonstration showing a gallery of photos is the beginning of an offline Web application and also the beginning of a new way to install software on the desktop.
Here's how we will run applications in the near future:

  1. We connect to the site of the distributor.
  2. Add a bookmark on the page of the application.
  3. We request to move offline, that orders Gears to copy all the files locally including the scripts of the application.
    In this case the photos of the gallery and scripts to display them.
  4. We can then access the gallery at any time by clicking on the bookmark.
  5. To update the gallery, we return to the site, go online and come back offline for a new synchronization which replaces and adds the new files.

In fact it is as to go to the retailer's site and download a software, with the advantage of a simplified update.

The developer must add in the manifest file the list of all images in the gallery. We renamed the file gallery.json.

We must also change the name assigned to the variable MANIFEST_FILENAME in the gears_offline.js. But it is not necessary to change the file, simply reassigning the variable in the script specific to the application, gallery.js.

This application uses Ajax to load images while the user looks at the pictures and thus eliminates waiting time. The waiting time is minimal when the application is offline, but our application should work both on the desktop and on the Web.

The script calls the preloading() function for each image of the gallery, it loads the picture in asynchone mode and is started at loading the page.

The enlarge() function displays the image in a full format in the <div> dedicated to this, whose ID is bigview.

function enlarge(element)
{
  var name = element.src;
 
  name = localFilename(name);
  name = name.slice(6);   // remove the "thumb-" part
  name = "robots/" + name;  // restore path 
 
  var str = "<img src='" + name + "' >";
  document.getElementById("bigview").innerHTML = str;
}

The demo() function uses the gallery.js script.

function demo()
{
    MANIFEST_FILENAME = "gallery.json";		// changes manifest filename
    init();           // starts gears 
    preloading("robots/asimo.jpg");
    preloading("robots/manoi.jpg");
    preloading("robots/nao.jpg");
    preloading("robots/robonova.jpg");
    preloading("robots/repliee.jpg");
}

window.onload=demo;   // launched when the page is displayed

Demonstration and download

Problems and limitations

Erase the memory buffer in case of problems. In Firefox, go to Tools -> Clear Private Data -> Check Cache. Uncheck any other data stored if you do not want to erase them. Then confirm.
For Internet Explorer you can pass through the control panel of the operating system.

When a document is offline, it becomes impossible for the developer to update the resources involved in the application. They are loaded on the server but can not be downloaded. He must return offline to acces the modified versions.

The two demos has been tested and they work but if you have several applications offline at the same time, they could no work.

The Ajax POST method might work, but the server side PHP scripts to process data received are not synchronized by Gears, the application will not work online as stated in the Gears FAQ.

See also