Click here to Skip to main content
Click here to Skip to main content

Beginner's Guide to HTML5 and CSS3 - Enabling the App Cache (Part 9 of 12)

, 14 May 2014 CPOL
Rate this:
Please Sign up or sign in to vote.
This article is all about Application Caching or App Cache. We will be seeing how to cache files that's required to make our application offline accessible. The article starts with basics and then goes in deep.


In this article we will see the below mentioned topics in detail. You will learning the application caching from basics to intermediate level.

By the end of this article, you should be able to create cache manifest file and implement offline applications.


If you are a beginner , it's highly recommended to read through the following articles to understand more about the HTML and CSS.

Beginner's Guide to HTML5 and CSS3 - Writing Your First Code (Series 1 of 12)

Beginner's Guide to HTML5/CSS3 - Styling Your First Web Page (Series 3 of 12)

Beginner's Guide to HTML5 & CSS3 - Laying Out Your First Web Page (Series 4 of 12)

Beginner's Guide to HTML5 & CSS3 - Getting Fancy with HTML5 & CSS3 (Series 5 of 12)

Beginner's Guide to HTML5 and CSS3 - Formidable Forms with HTML5 (Series 6 of 12)

Beginner's Guide to HTML5 and CSS3 - Coding Canvas (Part 7 of 12)

Beginner's Guide to HTML5 and CSS3 - Starting with SVG (Scalable Vector Graphics) (Part 8 of 12)

Beginner's Guide to HTML5 and CSS3 - Web Storage Wizardry (Part 10 of 12)

What is Application Cache?

AppCache or Application Caching API is a specification introduced in HTML5 which allows us to run our web application is offline; which in turn reduces the bandwidth consumption, and hence loads pages much faster. Also the web applications which are cached are accessible without the need of internet connection.

The applications which are running in offline gives us the same experience as if it's connected. Even if you say refresh or click on the links and if the pages, images etc resources are associated with the application caching, everything gets loaded from the cache as opposed to get the response by making a HTTP request.

The AppCache allows the developers to selectively cache the web pages, images, scripts, styles sheets, fonts etc when the application is online and make available to users if there are issues with the network connectivity and unable to reach the server.

Why would you use App Cache? Where is it useful?

Consider a scenario, where you are developing a financial application which has a functionality to analyze data and perform some calculations, show up a bunch of graphs based on the data. In such cases, you can build an application to cache all the data when the user is connected and trying to access the financial analytic tool. Say if the user loose network connection and the application goes offline, but the user can still perform all the data analysis, do some filtering on the data and the chart can be rendered based on some set of calculations. The offline applications makes sense for those users who have issues with the network connectivity.

Another example that you can think of in real world scenario where there's a need for App Cache would be, say you are going to view some online presentation (Slides). Ones the connection is established and the presentation gets download to App Cache, further the user don't have get any of the presentation slides through internet but instead everything will be retrieved from the App Cache. Think about how useful it would be in providing offline experiences to the user.

In order for you to experience the lack of App Cache or a similar techniques, you will have to really fell the experience. Let us open up a presentation in , navigate to one or more slides when your internet connection is alive. Now just disconnect the internet connection and try to click on next button and see what happens. Yes it's trying to get the slide content in real time by making a HTTP Request (To be specific, it makes an AJAX Request and just brings in the slide content what you have requested for). We know that we have disconnected the internet connection and obviously on click on next button, you won't be able to see any new contents being loaded.

The following are the benefits of using application cache.

Offline browsing: The App Cache allows the users to navigate a site even when they are offline. Users can greatly benefit from this feature so it allows the clients to fell as if they are connected, they can even perform all the things that they used to do. To an extent you can allow the clients to navigate to related pages and can view or perform some operations.

Speed: Cached resources reside at client side stored in browser App Cache area, and therefore load faster.

Reduced server load: With application caching, the browser only downloads resources that have changed from the server.

Resilience – The resilience is the capability to recover from difficulties. Say your website goes under maintenance, say your developer accidentally checked in some code which had minor issues that you happened to notice at a later point of time and you plan to take the site down for a minute to rollback the changes in such cases you can let the users to have the offline experience and let them feel as if everything is connected.

The basics of creating a cache manifest

The cache manifest file contains various sections like – CACHE MANIFEST, NETWORK, FALLBACK etc. We will be seeing each of these sections in detail.

Let us now see the basics of creating a cache manifest. The cache manifest is a special file which instructs the browser to store only those specific files that are defined in the manifest. Also the manifest tells browser which files are not to be stored or which one requires file substitution. The entire package of cacheable content is called a offline application.

The cache manifest is the key file in HTML5 offline application. The manifest always starts with the words CACHE MANIFEST (note everything should be in upper case). Then in the next line, we start listing the files that we are interesting to cache. Here's how it looks like (Note – It's just an example)



The spaces shown above are optional, you can remove or keep them as it's. You could also include some comments too. We will see coming up.

We have already discussed that the in an offline application, the browser must cache everything that's required as a part of the page. That means, your page might contain images, styles, fonts, scripts etc; so you will have to define all these things in the manifest file in order for them to cache. Here's how you can define them.




#scripts and styles


#images and fonts.






/ offline.html



You will notice few things in here. There are several lines defined with '#' and some texts, these are comments. You might have also noticed the sub folders say Images, Fonts etc as long as these folders exist and is accessible to the browser, you can bundle them up to build a offline application package.

When you completely list all the required files for caching, you can save the file in sites root directory along with your web pages. Note – The manifest file has to be saved with an extension *.appcache. Also make sure to double check what ever you have listed in the manifest file or folders with files exists as a part of your application. Even if there's a small mistake say that you did misspelled one file name or extension in manifest file, it will prevent the offline application feature from working. Let us name our cache file name as CodeProjectCache.appcache

Using manifest file in HTML.

Now let us see how to use manifest file in our web pages as it's required to mention the cache manifest file name in all the pages which you are interested to cache be a part of the offline application.

Here's how we define.

<!DOCTYPE html>
<html lang=”en” manifest=”CodeProjectCache.appcache”>

Let us see an example to understand about application caching.

This example is about video caching. Yes here we are caching a small *.mp4 video.

We shall first create the cache file that's required for this sample. You can notice below we are trying to cache the video by specifying the full URL. Also we do cache the style sheet that's required as a part of this sample.


# Version 1.0






Here's the sample HTML page. Notice below, we have defined the cache manifest in <html> tag.

<html manifest="cache.appcache">
    <meta name="viewport" content="width=device-width">
    <link rel="stylesheet" href="styleSheet.css" type="text/css">
  <video controls="" autoplay="" style="margin-left: 30%; margin-top: 20%">
     <source src="" type="video/mp4">

The next thing we need to do is hosting our sample application locally in IIS. Please note, you might encounter with permission issues while browsing the sample video HTML page. If that's the case, you will have to add users like Network Services , Users etc and assign read permission. Also read below on how to add MIME type for our cache manifest. Click here

Here's how the page looks like.


When you are browsing the page for the first time, since we have specified the manifest attribute in <html> tag, the browser tries to fetch the cache file, it reads though and loads all the files to be cached. Here's how it looks like. You can notice below the application cache progress event for each of the files that's being downloaded.

Now that we know the application cache has all the files that's required for the application to be browsed offline. If you want to have the real offline experience, just disconnect your internet connection and refresh the page; You will still be able to play the video.


Now we will reconnect the internet and refresh the page to see what happens. You will notice below the Cache checking event will be triggered and then we don't have any updates for our cache, so the cache NoUpdate event gets triggered.



The cache manifest section is defined with CACHE MANIFEST , it mainly consists of a list of URL's of the resources that you intend to be cached. Note – The CACHE section is defined implicitly, meaning by default the manifest begins with the CACHE section even if you don't specify one. If you have other cache manifest sections defined in the file, then you must explicitly declare subsequent cache section with CACHE:

Here's an example:



NETWORK section:

The network section which is also called the whitelist section. Begins with the keyword NETWORK followed by a colon.

This section is used to define all the files that may come from the network if the defined files in the network section doesn't exist in the App Cache. Otherwise the files won't be fetched from the network even if the user is online.

The URL can be defined as below.

NETWORK: - Specifies all files in Directory specifies all files in

* specifies all files to be fetched online (Note – If and only if the files do not exist in App Cache). The asterisk are also used to specify the target files of a particular type ex: *.jpeg, *.png etc.

Note – The asterisks are only supported in network section and you can't really make use of asterisks say to cache file. There's a reason, the inventors of the HTML5 specification were concerned about careless web developers might misuse and try to cache all files.

FALLBACK section:

The fallback section is defined with FALLBACK: , lets us to swap files depending upon the user is online or offline.

Here's an example how we define the fallback section.


CodeprojectArticle.aspx CodeprojectArticleOffline.aspx

The fall back section has files defined with two pairs for each line items. The first file name indicates the file to be used when the user is online; the second file name indicates the file to be used when the user goes offline.

Note - The browser will download the fallback file and keep them in application cache and will only use them when the user goes offline.

There are several reasons you can think why we need to define a fallback section in our manifest file. Say you wish to show a file with small size resources or show up a cut down version of the page. You can put the fallback section where ever you want with in the manifest but make sure the fallback section precedes the cache manifest section title.



CodeprojectArticle.aspx CodeprojectArticleOffline.aspx
Images/bob.jpeg Images/smallbob.jpeg

The fallback section supports wildcard character like '/' , which will be helpful when you want to create a generic offline pages. Here's how it works. If someone attempts to request a page assuming the user goes offline. Say if the page is not available in the cache or the attempted request for the page does not exist in the web server, in such cases the web browser will shows up the cached offline page.

Here's an example:

/ offlinePage.html

Updating the cache

When the application gets cached in App Cache area in clients browser, The cache gets updated for the below events.

1. User forcibly clears the browsers Application cache. In Chrome you can do easily by navigating to chrome://appcache-internals/

2. The Application cache gets updated when the manifest file gets updated. There are several reasons why you would update the manifest file.

a. You wish to add more files to be cached.

b. Say If you have decided not to cache some of the files, in such cases you have to update the CACHE MANIFEST and/or CACHE section by removing the file name that you don't want to cache. Or the other way, you wish to specify the files to fetched from network when the user is online; You will have to specify update the manifest NETWORK section.
c. You wish to add or remove entries from the FALLBACK section, the cache gets updated automatically when the user makes a request.

3. The cache gets updated when the application cache is programmatically updated.

We will see in detail how the application cache can be updated programmatically. We can trigger the cache update from Javascript code based on the application cache status.

Here's how we will get to know the cache application status. By using window object.


When you are browsing the webpage containing the manifest attribute for the first time, Here are the application cache events that gets happened.

• Checking: The checking event occurs when the browser is checking for an updated manifest file or is attempting to download for the first time.

• Downloading: The downloading event occurs when the browser starts downloading the resources in the manifest file.

• Progress: The progress event provides information on how many files are downloaded and how many files are yet to be downloaded.

• Cached: The cached event gets triggered when all the resources in the manifest file are downloaded and the application is ready to be used offline.

The following events gets triggered when the user browses the web page when she/he has already browsed.

Note – Assuming the cache manifest file has already been recognized at first time.

• No update: The noupdate event occurs when there is no change in the manifest file

• Downloading: The downloading event occurs when the cache manifest file and the resources listed in the file are changed. The browser starts downloading the resources.

• Progress: The progress event provides information on how many files are downloaded and how many files are yet to be downloaded

• Update Ready – The updateready event occurs when the resources in the manifest file are downloaded again for changes and the new application if ready to be used for offline

Below are the scenarios when the error events gets triggered.

• The manifest returns 404 or 410 , when the download failed, or the manifest changed while the download was in progress.

• When the cache manifest file is changed while the update is being run.

• An error occurred while downloading the resources listed in the manifest file.

• When the page referencing the manifest failed to download or there could be a fatal error while fetching the files.

Here's the code block which registers the application cache updateready event.

window.applicationCache.addEventListener('updateready', onCacheUpdateReady);

Here's what we do on updateready event.

1. Check for the application cache status whether it is 'updateready'

2. Swap in the new cache by making a call to swapCache.

3. Reload the window.

function onCacheUpdateReady()

   if(window.applicationCache.status == window.applicationCache.UPDATEREADY)




Let us see with an example to understand the application cache events.

Here's the sample application consists of dedicated folders for CSS, Javascripts, Images. We have a single HTML page. Also notice the appcache file named 'cache'.


Let us define the cache sections with the files to be cached etc. You will see the version number is defined with a unique number , later on we will be updating the version number and try to get the cache. The version number is really helpful when you don't have any cache file changes but if there are any changes say in the already listed files say you have modified the image file or the javascript files, then in order to notify the browser to refresh it's cache, we can easily do by updating the version number as it in turn updates the cache manifest file itself.

Also notice below, we have added two image files to be a part of the application cache.


# Version 1.0






Here's the sample HTML & Javascript code .

The first thing we need to is include the appcache file name in HTML manifest.

On document ready, we are registering some of the application cache events like checking, noupdate, downloading, progress, cached, updateready, error

We will be hosting this sample offline application in Internet Information Services (IIS). In IIS 7, Add new application with alias and virtual directory folder. Make sure the folder has the permissions I.e Network Services , Users etc.

Now we will have to add the MIME type. You can either set the mime type for this application itself or you can do the same at the Default WebSite Level.

Here's how you can do.


The cache can be updated by manually calling update method of applicationCache object. Similarly the cache can be manually triggered to swap by making a call to swapCache method of applicationCache.

<html manifest="cache.appcache">
        <script src="js/jquery.js"></script> 
      <p>Status of cache: </p>
        Application Status: <span id="applicationStatus">Online</span>
        Progress: <span id="cacheProgress">N/A</span>
      <p><input type="button" id="update" value="Update cache status" onclick="return updateCache();" /></p>
      <p><input type="button" id="swap" value="Update cache to latest"  onclick="return swapCache();" /></p>                
      <ul id="applicationEvents">


<script type="text/javascript">

            var appStatus = $("#applicationStatus");
            var appEvents = $("#applicationEvents");
            var cacheProgress = $( "#cacheProgress" );
            var appCache = window.applicationCache;          

            var filesDownloaded = 0;

            function updateCache() {

            function swapCache() {

            // This method is used to Log an event to the event list.
            function logEvent( event ){
                    "<li>" +
                        (event + " ... " + (new Date()).toTimeString()) +

            function displayProgress() {
                // Increment the running total.

                        filesDownloaded +
                        " files downloaded."


            // List for checking events. This gets fired when the browser
            // is checking for an updated manifest file or is attempting
            // to download it for the first time.
                function (event) {
                    logEvent("Checking for manifest");

            // This gets fired if there is no update to the manifest file
            // that has just been checked.
                function (event) {
                    logEvent("No cache updates");

            // This gets fired when the browser is downloading the files
            // defined in the cache manifest.
                function (event) {
                    logEvent("Downloading cache");

            // This gets fired for every file that is downloaded by the
            // cache update.
                function (event) {
                    logEvent("File downloaded");

                    // Show the download progress.

            // This gets fired when all cached files have been
            // downloaded and are available to the application cache.
                function (event) {
                    logEvent("All files downloaded");

            // This gets fired when new cache files have been downloaded
            // and are ready to replace the *existing* cache. The old
            // cache will need to be swapped out.
                function (event) {
                    logEvent("New cache available");

                    // Swap out the old cache.

            // This gets fired when an error occurs
                function (event) {
                    logEvent("An error occurred");


When you are browsing this sample for the first time. The browser finds the HTML document is being included with the cache manifest file, hence it tries to read the cache manifest file with *.appcache extension and mime type as text/cache-manifest. As the document gets loaded , in the background the browser will load all the files to be cached.

The sequence of application cache events gets fired.

1. Application cache checking event gets called.
2. Application cache downloading event gets called.
3. Application cache progress event gets called and the files get downloaded. You can notice when the files are getting downloaded, we are updating the filesDownloaded counter and displaying the same in UI.
4. Application cache cached event gets called. This happens when all cache files have been downloaded and are available in the application cache.


If you want to see whether the files are really in the application cache you do inspect element in Chrome. Below you can notice the chrome keeps track and shows all the events that happened.


Also the other way, you can see all the cached files by just navigating to chrome://appcache-internals. You could also see all the cached files if you navigate to Resources in Inspect Element


Now we will update the cache manifest file to include one more image - grapes.jpg


# Version 1.0






Now just give a try by hitting refresh button, you should be able to see the new cache file getting downloaded. You will see the application cache updateready event gets fired and we do swap out the old cache with the new one.


We will now see the application cache noevent case. In order to see how this event gets fired, just hit refresh button. You will see below, it triggers to check the manifest file and since we haven't done any changes to the cache manifest file, No files will be downloaded and hence triggers no update event.


At last, we will see how the cached files gets refreshed by changing the version number in cache manifest file. Open up the cache manifest file and increment the version number and hit refresh on the web page to see the cache files are getting refreshed by downloading them again.

Note – If you clearly read all the events that is fired, you will notice the offlineapp.html file does not appear to be downloaded at first time. However when you navigate to Resources, it will show up. It appears to be a bug in Chrome. But the same thing does not happen when the cache gets updated.


Other tips and best practices

1. The cache manifest should be saved with 'appcache' extension.

2. The cache manifest resource mime type must be set with ‘text/cache-manifest’. It is very important to set the mime type else the browser won't understand how to read the cache file. Also it varies by web server in how you set the mime type.

3. If you wish the cache to be refreshed because you have changed some of the resources say modifying the image or javascript file, you should change the manifest file itself. This can be done in a few ways:

Use a comment line to version the manifest file. Ex: version 1.0

Alternatively you can use the website's build number or generate a GUID or some unique number. So when you make changes on resources and deploy your website, the manifest file changes and browsers will reload it.

4. When it comes to debugging offline applications, it's preferred to use the options that the browser provides us. Say with Chrome you can navigate to Application cache area and see all the files. Also in chrome console, you could see all the application cache events that's triggered when the page gets loaded or refreshed.

5. Wish to clear all the application cache files for your offline application ? Yes we might have to try this one as we learn and work on offline application. We can do this easily say with chrome you can find your application cache in chrome://appcache-internals , then you can remove all files which are cached. Similarly other browsers like Firefox allows us to do by choosing Tools-> Options-> Advanced and by selecting the Network tab.

6. Be careful with application caching in Private browsing. Most browsers prevent storing in application cache while in private browsing modes.

7. As a security consideration, do no store any personal or sensitive information in application cache.

8. The files that you are defining in the cache manifest section are case sensitive. Note – Even if you make a single mistake while defining the cache manifest entries, the application caching will not work as expected.

9. Always handle the application caching error event. Never assume the success case, there are times you would exceed the App cache storage capacity and it's good idea to know. Chrome reports a failed to commit new cache storage, would exceed quota when you are trying to cache too many files and exceeding the application storage capacity.

10. Know your browser before targeting them. Not all the browser supports application caching. As of now Internet Explorer 10, Firefox, Chrome, Safari and Opera support Application cache. If you wish to know more with the latest updates, you can check using

11. Never ever cache the manifest file. Remember when the users browse the page for the first time, the resources gets cached. Say if the manifest file itself gets cached, even if you are trying to update the manifest file say by adding or removed files to be cached, the users cache will don't get effected as the browser always gets the cached copy of the manifest file. Unless the user explicitly removes all the caches files and refresh the page, there won't be any changes to the application cache.

12. Non cached resources on a cached page will not get cached by default. Say you have a HTML page named index.html which has scripts and images. When you are trying to cache this page, you will also have to explicitly state other resources to be cached or you will have to specify them in NETWORK section. In real time mostly you will have to specify '*' in NETWORK section so that the non cached resources will be obtained by making a HTTP Request.

13. Remember , Files always come from cache even if the user is online.

14. It's tough to separate resources for various devices like desktops, mobile, tablets etc because we can have only one cache manifest file.

15. Know the cache size limit.

Chrome has a 5MB limit.
Firefox desktop has unlimited appcache size.
Opera’s default size of 50MB. However the appcache limit can be managed by the user.
Mobile Safari has a 10MB limit
Android browser has no limit to appcache size

16. When it comes to caching the cross domain resources, as per the specification it says all the resources must come from same origin. With the only exception that the origin must be https. However browsers like Chrome does not adhere to this standard; Chrome has argued stating that the single domain origin policy for https is too restrictive for app caching to have a real value.

A Little about client side communication framework

Let us see a framework that we can make use-off in developing offline application. Yes we are talking about amplify.js , it's a small library that used as a Client Side Component Communication.

amplify.publish/subscribe provides a clean and performant API for component to component communication.

OfflineApplication.UpdateReady = (function () {

    var appCache = window.applicationCache;          
    var publishConnectivityStatus = function (status) {
         case "updateready"
         case "error"
         case "checking"
          case "downloading"

    var init = function () {
         $(appCache).bind("updateready", publishConnectivityStatus);
         $(appCache).bind("onchecking", publishConnectivityStatus);
         $(appCache).bind("onerror", publishConnectivityStatus);
         $(appCache).bind("downloading", publishConnectivityStatus);

    return {
         init: init

The subscriber will have to subscribed with the published topic (The name of the message) in order to get notified.

amplify.subscribe( "onupdateready", 
   var appCache = window.applicationCache;          
  function( ) {
      // Swap out the old cache.
  } );

Now we will see how we can use the amplify.js to sync the localStorage data when the application goes online. Note – When the comes to offline apps, it's not just about the application caching; we do have to think about persisting the data and synching the same when the user goes online.

The below code subscribes for 'online' publish topic. When ever the application goes online, the subscriber will be notified and it will make a call to SyncUp method.

Here's what we do in SyncUp method, loop through the localStorage , get the offline records and call post method which does a AJAX POST request and then further removes the localStorage record when the AJAX request is done or completed.

OfflineApplication.SyncUp = (function () {
    var removeRecord = function (record) {

    var post = function (key, row) {
        var record = JSON.parse(localStorage.getItem(key));
        $.ajax({ data: record.form, url: record.url, type: 'POST' })
            .done(function (response) {

    var SyncUp = function () {
        var key, i, offlineRow;
        for (i = 0; i < localStorage.length; i = i + 1) {
            key = localStorage.key(i);

            offlineRow = $('tr#' + key);
            post(key, offlineRow);

    var init = function () {
        amplify.subscribe('online', SyncUp);

    return {
        init: init

Points of Interest

I learnt a lot while working on this article. The modern applications can really take advantage of application caching, web storage etc to make a true offline application. Just take a step back , do some analysis and make improvements in your current applications.


Version 1.0 - Initial version of article writing on Enabling App Caching - 05/04/2014.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Web Developer
United States United States
Around 10 years of professional software development experience in analysis, design, development, testing and implementation of enterprise web applications for healthcare domain with good exposure to object-oriented design, software architectures, design patterns, test-driven development and agile practices.
In Brief
Analyse and create High Level , Detailed Design documents.
Use UML Modelling and create Use Cases , Class Diagram , Component Model , Deployment Diagram, Sequence Diagram in HLD.
Area of Working : Dedicated to Microsoft .NET Technologies
Experience with : C# , J2EE , J2ME, Windows Phone 8, Windows Store App
Proficient in: C# , XML , XHTML, XML, HTML5, Javascript, Jquery, CSS, SQL, LINQ, EF
Software Development
Database: Microsoft SQL Server, FoxPro
Development Frameworks: Microsoft .NET 1.1, 2.0, 3.5, 4.5
UI: Windows Forms, Windows Presentation Foundation, ASP.NET Web Forms and ASP.NET MVC3, MVC4
Coding: WinForm , Web Development, Windows Phone, WinRT Programming, WCF, WebAPI
Healthcare Domain Experience
CCD, CCR, QRDA, HIE, HL7 V3, Healthcare Interoperability
B.E (Computer Science)
CodeProject Contest So Far:
1. Windows Azure Developer Contest - HealthReunion - A Windows Azure based healthcare product , link -
2. DnB Developer Contest - DNB Business Lookup and Analytics , link -
3. Intel Ultrabook Contest - Journey from development, code signing to publishing my App to Intel AppUp , link -
4. Intel App Innovation Contest 2013 - eHealthCare -
5. Grand Prize Winner of CodeProject HTML5 &CSS3 Article Contest 2014
6. Grand Prize Winner of CodeProject Android Article Contest 2014

Comments and Discussions

Questionabout application cache and phonegap PinmemberAsaf Shay1-Jul-14 4:10 
GeneralWow. Again. PinprofessionalJames Jensen13-May-14 13:01 
GeneralRe: Wow. Again. PinmvpRanjan.D13-May-14 14:32 
GeneralRe: Wow. Again. PinprofessionalJames Jensen15-May-14 4:45 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.150224.1 | Last Updated 14 May 2014
Article Copyright 2014 by Ranjan.D
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid