uangsl
3/16/2017 - 3:00 AM

IndexedDB-storing-and-retrieving-files.js

//forked from robnyman/IndexedDB-storing-and-retrieving-files.js
(function () {
    // IndexedDB

    function BrowserType() {
        var n = navigator.appName;
        var ua = navigator.userAgent;
        var tem;
        var m = ua.match(/(opera|chrome|safari|firefox|msie)\/?\s*(\.?\d+(\.\d+)*)/i);
        if (m && (tem = ua.match(/version\/([\.\d]+)/i)) != null) m[2] = tem[1];
        m = m ? [m[1], m[2]] : [n, navigator.appVersion, '-?'];
        if ((m[0] == "Netscape") && ua.match(/rv:11/g)) {
            m[0] = "MSIE";
        }
        return { brand: m[0], version: m[1] };
    }

    var browserName = BrowserType().brand;
    console.log(browserName);

    var indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.OIndexedDB || window.msIndexedDB,
        IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.OIDBTransaction || window.msIDBTransaction,
        dbVersion = 1.0;

    // Create/open database
    var request = indexedDB.open("elephantFiles", dbVersion),
        db,
        createObjectStore = function (dataBase) {
            // Create an objectStore
            console.log("Creating objectStore")
            dataBase.createObjectStore("elephants");
        },

        getImageFile = function () {
            // Create XHR
            var xhr = new XMLHttpRequest(),
                blob;

            xhr.open("GET", "elephant.jpg", true);
            // Set the responseType to blob
            xhr.responseType = "blob";

            xhr.addEventListener("load", function () {
                if (xhr.status === 200) {
                    console.log("Image retrieved");
                    
                    // Blob as response
                    blob = xhr.response;
                    console.log("Blob:" + blob);

                    // Put the received blob into IndexedDB
                    putElephantInDb(blob);
                }
            }, false);
            // Send XHR
            xhr.send();
        },

        convertToBase64 = function(blob, cb) {
            var fr = new FileReader();
            fr.onload = function(e) {
                cb(e.target.result);
            }
            fr.readAsDataURL(blob);
        },

        dataURLToBlob = function(dataURL) {
            var BASE64_MARKER = ';base64,';
            if (dataURL.indexOf(BASE64_MARKER) == -1) {
              var parts = dataURL.split(',');
              var contentType = parts[0].split(':')[1];
              var raw = parts[1];

              return new Blob([raw], {type: contentType});
            }

            var parts = dataURL.split(BASE64_MARKER);
            var contentType = parts[0].split(':')[1];
            var raw = window.atob(parts[1]);
            var rawLength = raw.length;

            var uInt8Array = new Uint8Array(rawLength);

            for (var i = 0; i < rawLength; ++i) {
              uInt8Array[i] = raw.charCodeAt(i);
            }

            return new Blob([uInt8Array], {type: contentType});
        },

        putElephantInDb = function (blob) {
            console.log("Putting elephants in IndexedDB");

            // Put the blob into the dabase
            if (browserName == 'Chrome') {
                // Chrome can't store blobs at the moment.
                // Convert to base64.
                convertToBase64(blob, continuation);
            } else {
                continuation(blob);
            }

            function continuation(blob) {
                // Open a transaction to the database
                var transaction = db.transaction(["elephants"], 'readwrite');
                var put = transaction.objectStore("elephants").put(blob, "image");

                // Retrieve the file that was just stored
                transaction.objectStore("elephants").get("image").onsuccess = function (event) {
                    var imgFile = event.target.result;
                    console.log("Got elephant! " + imgFile);

                    // we've received our image from the database.  Convert it back to
                    // a blob if it is not a blob already.
                    if (browserName == 'Chrome') {
                        // Why conver to a blob instead of using the data url?
                        // because data URLs are huge and contain the entire image int he url.
                        // If you reference the same image multiple times 
                        // with a data url you essentially
                        // end up with multiple copies of your image floating around.
                        // dataUrls also take up JS heap space.
                        imgFile = dataURLToBlob(imgFile);
                    }

                    // Get window.URL object
                    var URL = window.URL || window.webkitURL;

                    // Create and revoke ObjectURL
                    var imgURL = URL.createObjectURL(imgFile);

                    // Set img src to ObjectURL
                    var imgElephant = document.getElementById("elephant");
                    imgElephant.setAttribute("src", imgURL);

                    // localStorage.setItem('img', imgURL);
                    // window.open('blank.html');
                    // Revoking ObjectURL
                    URL.revokeObjectURL(imgURL);

                };
            }
        };

    request.onerror = function (event) {
        console.log("Error creating/accessing IndexedDB database");
    };

    request.onsuccess = function (event) {
        console.log("Success creating/accessing IndexedDB database");
        db = request.result;

        db.onerror = function (event) {
            console.log("Error creating/accessing IndexedDB database");
        };
        
        // Interim solution for Google Chrome to create an objectStore. Will be deprecated
        if (db.setVersion) {
            if (db.version != dbVersion) {
                var setVersion = db.setVersion(dbVersion);
                setVersion.onsuccess = function () {
                    createObjectStore(db);
                    getImageFile();
                };
            }
            else {
                getImageFile();
            }
        }
        else {
            getImageFile();
        }
    }
    
    // For future use. Currently only in latest Firefox versions
    request.onupgradeneeded = function (event) {
        createObjectStore(event.target.result);
    };
})();