taking web apps offline
TRANSCRIPT
localStorage
Can store a JSON string
window.localStorage[‘helloJSON’] =
JSON.stringify({‘key1’: ‘world’,
‘key2’: ‘Lisbon’});
localStorage limitationsStorage Limits
Spec - 5 MbFirefox - can adjusted
Chrome - 2600k chars (5 mb in UTF-16)
IE - 5000k chars
sql storagework stopped November ’10
sqlite was used in all implementations(webkit, opera)
mozilla & microsoft: “not gonna happen”
sql storage
http://nparashuram.com/IndexedDBShim/
indexed db polyfill over websql
indexed dbAsync API
var request = indexedDB.doStuff();
request.onerror = function(event) {
...
};
request.onsuccess = function(event) {
...
};
indexed db
Opening a database
var request = indexedDB.open("MyTestDatabase");
request.onerror = ...
var db;
request.onsuccess = function(event) {
db = request.result;
};
creating the schema
var request = indexedDB.open("MyTestDatabase", 5);
...
request.onupgradeneeded = function(event) {
var db = event.target.result;
...
};
creating the schema# student: cardNumber, name, email, ...
request.onupgradeneeded = function(event) {
var db = event.target.result;
var studentsStore = db.createObjectStore("students",
{ keyPath: "cardNumber" });
studentsStore.createIndex("nameIndex", "name",
{ unique: false });
studentsStore.createIndex("emailIndex", "email",
{ unique: true });
};
adding datavar transaction
= db.transaction(["students"], "readwrite");
transaction.oncomplete = function(event) {
alert("All done!");
};
...
// transactions go away when you
// return to the event loop
// without making a request
adding data...
var objectStore = transaction.objectStore("customers");
aStudent = { ‘studentCard’: ‘44124’,
‘name’: ‘Pedro Morais’,
‘email’: ‘[email protected]'}
var request = objectStore.add(aStudent);
request.onsuccess = function(event) {
// event.target.result == aStuddent.studentCard
};
updating data...
var objectStore = transaction.objectStore("customers");
aStudent = { ‘studentCard’: ‘44124’,
‘name’: ‘Pedro Morais with updated name’,
‘email’: ‘[email protected]'}
var request = objectStore.put(aStudent);
request.onsuccess = function(event) {
// event.target.result == aStuddent.studentCard
};
deleting data
...
var objectStore = transaction.objectStore("customers");
var request = objectStore.delete(‘44124’);
request.onsuccess = function(event) {
// deleted
};
getting data
var transaction = db.transaction(["students"]);
var objectStore = transaction.objectStore("customers");
var request = objectStore.get(‘44124’);
request.onsuccess = function(event) {
console.log(“Name is “, request.result.name);
};
using a cursor....
var request = objectStore.openCursor();
request.onsuccess = function(event) {
var c = event.target.result;
if (c) {
console.log
("Student " + c + " is named " + c.value.name);
cursor.continue();
} else {
console.log("Done!");
}
};
using an index
...
var index = objectStore.index("name");
index.get("Pedro Morais").onsuccess = function(event) {
console.log("Email=" + event.target.result.email);
};
// if name is not unique
// you get the first entry that matches
using an index + cursor...
var index = objectStore.index("name");
var request
= index.openCursor(IDBKeyRange.only("Pedro Morais"));
request.onsuccess = function(event) {
var c = event.target.result;
if (c) {
// c.key is a name, like "Pedro Morais",
// c.value is the whole object.
console.log("Name: " + cursor.key +
“Email: " + cursor.value.email);
cursor.continue();
}
};
cursor key ranges
IDBKeyRange.only("Pedro Morais")
IDBKeyRange.lowerBound("Pedro")
IDBKeyRange.lowerBound("Pedro", true) // don’t inc Pedro
IDBKeyRange.upperBound("Pedro", true) // don’t inc Pedro
IDBKeyRange.bound("Pedro", "Vanda", false, true);
// include Pedro, don’t include Vanda
offline web apps<!DOCTYPE html>
<html manifest=”cache.appcache”>
...
cache.appcache must be served astext/cache-manifest
cache manifestCACHE MANIFEST# this is a comment
css/styles.cssjs/scripts.jsimages/logo.png
NETWORK:*
cache with fallbackCACHE MANIFEST# this is a comment
css/styles.cssjs/scripts.jsimages/logo.png
FALLBACK:/ /offline.html
NETWORK:*
network accessnot using appcache
• user navigates to http://test.com/app.html
• browser check if file “app.html” is in cache
• browser check if it has not expired
• browser checks validity of file using etags (optional)
• browser renders the cached or downloaded app.html
network accessusing appcache
• user navigates to http://test.com/app.html
• browser renders app.html from appcache
• in the background:
• browser checks if manifest has changed
• if it has, browser downloads all files in the manifest (expires, etags still apply)
• user only gets new version of app.html the next time!
cache manifest versionsCACHE MANIFEST# version 50
css/styles.cssjs/scripts.jsimages/logo.png
NETWORK:*
cache manifest versionsCACHE MANIFEST
css/styles.css?b3c4dejs/scripts.js?adf341images/logo.png?ef3451
NETWORK:*
+ far future expires
cache manifest versionsCACHE MANIFEST
b3c4de/css/styles.cssadf341/js/scripts.jsef3451/images/logo.png
NETWORK:*
+ far future expires