Todo in 200 lines

JavaScript

var myStorage = {};
if (window.openDatabase) {
    //use WebSQL datasource if it is available
    
    myStorage.open = function () {
        var dbSize = 5 * 1024 * 1024; // 5MB
        myStorage.db = openDatabase("Todo", "1.0", "Todo manager", dbSize);
    }
    
    myStorage.createTable = function () {
        var db = myStorage.db;
        db.transaction(function (tx) {
            tx.executeSql("CREATE TABLE IF NOT EXISTS todo(ID INTEGER PRIMARY KEY ASC, todo TEXT, added_on DATETIME)", []);
        });
    }
    
    myStorage.init = function () {
        myStorage.open();
        myStorage.createTable();
    }
    
    //save new item
    myStorage.addTodo = function (todoText) {
        var db = myStorage.db;
        db.transaction(function (tx) {
            var addedOn = new Date();
            tx.executeSql("INSERT INTO todo(todo, added_on) VALUES (?,?)",
                          [todoText, addedOn],
                          myStorage.onSuccess,
                          myStorage.onError);
        });
    }
    
    myStorage.onError = function (tx, e) {
        alert("There has been an error: " + e.message);
    }
    
    myStorage.onSuccess = function (tx, r) {
        //re-render the data.
        myStorage.getAllTodoItems(loadTodoItems);
    }
    
    //Read all records from DB
    myStorage.getAllTodoItems = function () {
        var db = myStorage.db;
        db.transaction(function (tx) {
            tx.executeSql("SELECT * FROM todo", [], loadTodoItems,
                          myStorage.onError);
        });
    }
    
    //Process the results
    function loadTodoItems(tx, rs) {
        
        for (var i = 0; i < rs.rows.length; i++) {
            console.dir(rs.rows.item(i));
        }
    }
    
    console.log("webSQL");
    
}
else {
    //Use IndexedDB if WebSQL isn't available
    
    console.log("indexeddb");
    var indexedDB = window.indexedDB || window.webkitIndexedDB ||
        window.mozIndexedDB;
    
    if...