<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>JSDoc: Source: store/dom.js</title>
    
    <script src="scripts/prettify/prettify.js"> </script>
    <script src="scripts/prettify/lang-css.js"> </script>
    <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
    <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>

<body>

<div id="main">
    
    <h1 class="page-title">Source: store/dom.js</h1>
    
    


    
    <section>
        <article>
            <pre class="prettyprint source"><code>﻿/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
'use strict';

/** @module store/dom */



var utils = require('./../utils.js');

// Imports.
var throwErrorCallback = utils.throwErrorCallback;
var delay = utils.delay;

var localStorage = null;

/** This method is used to override the Date.toJSON method and is called only by
 * JSON.stringify.  It should never be called directly.
 * @summary Converts a Date object into an object representation friendly to JSON serialization.
 * @returns {Object} Object that represents the Date.
 */
function domStoreDateToJSON() {
    var newValue = { v: this.valueOf(), t: "[object Date]" };
    // Date objects might have extra properties on them so we save them.
    for (var name in this) {
        newValue[name] = this[name];
    }
    return newValue;
}

/** This method is used during JSON parsing and invoked only by the reviver function.
 * It should never be called directly.
 * @summary JSON reviver function for converting an object representing a Date in a JSON stream to a Date object
 * @param value _
 * @param value - Object to convert.
 * @returns {Date} Date object.
 */
function domStoreJSONToDate(_, value) {
    if (value && value.t === "[object Date]") {
        var newValue = new Date(value.v);
        for (var name in value) {
            if (name !== "t" && name !== "v") {
                newValue[name] = value[name];
            }
        }
        value = newValue;
    }
    return value;
}

/** Qualifies the key with the name of the store.
 * @param {Object} store - Store object whose name will be used for qualifying the key.
 * @param {String} key - Key string.
 * @returns {String} Fully qualified key string.
 */
function qualifyDomStoreKey(store, key) {
    return store.name + "#!#" + key;
}

/** Gets the key part of a fully qualified key string.
 * @param {Object} store - Store object whose name will be used for qualifying the key.
 * @param {String} key - Fully qualified key string.
 * @returns {String} Key part string
 */
function unqualifyDomStoreKey(store, key) {
    return key.replace(store.name + "#!#", "");
}

/** Constructor for store objects that use DOM storage as the underlying mechanism.
 * @class DomStore
 * @constructor
 * @param {String} name - Store name.
 */
function DomStore(name) {
    this.name = name;
}

/** Creates a store object that uses DOM Storage as its underlying mechanism.
 * @method module:store/dom~DomStore.create
 * @param {String} name - Store name.
 * @returns {Object} Store object.
 */
DomStore.create = function (name) {

    if (DomStore.isSupported()) {
        localStorage = localStorage || window.localStorage;
        return new DomStore(name);
    }

    throw { message: "Web Storage not supported by the browser" };
};

/** Checks whether the underlying mechanism for this kind of store objects is supported by the browser.
 * @method DomStore.isSupported
 * @returns {Boolean} - True if the mechanism is supported by the browser; otherwise false.
*/
DomStore.isSupported = function () {
    return !!window.localStorage;
};

/** Adds a new value identified by a key to the store.
 * @method module:store/dom~DomStore#add
 * @param {String} key - Key string.
 * @param value - Value that is going to be added to the store.
 * @param {Function} success - Callback for a successful add operation.
 * @param {Function} [error] - Callback for handling errors. If not specified then store.defaultError is invoked.
 * This method errors out if the store already contains the specified key.
 */
DomStore.prototype.add = function (key, value, success, error) {
    error = error || this.defaultError;
    var store = this;
    this.contains(key, function (contained) {
        if (!contained) {
            store.addOrUpdate(key, value, success, error);
        } else {
            delay(error, { message: "key already exists", key: key });
        }
    }, error);
};

/** This method will overwrite the key's current value if it already exists in the store; otherwise it simply adds the new key and value.
 * @summary Adds or updates a value identified by a key to the store.
 * @method module:store/dom~DomStore#addOrUpdate
 * @param {String} key - Key string.
 * @param value - Value that is going to be added or updated to the store.
 * @param {Function} success - Callback for a successful add or update operation.
 * @param {Function} [error] - Callback for handling errors. If not specified then store.defaultError is invoked.
 */
DomStore.prototype.addOrUpdate = function (key, value, success, error) {
    error = error || this.defaultError;

    if (key instanceof Array) {
        error({ message: "Array of keys not supported" });
    } else {
        var fullKey = qualifyDomStoreKey(this, key);
        var oldDateToJSON = Date.prototype.toJSON;
        try {
            var storedValue = value;
            if (storedValue !== undefined) {
                // Dehydrate using json
                Date.prototype.toJSON = domStoreDateToJSON;
                storedValue = window.JSON.stringify(value);
            }
            // Save the json string.
            localStorage.setItem(fullKey, storedValue);
            delay(success, key, value);
        }
        catch (e) {
            if (e.code === 22 || e.number === 0x8007000E) {
                delay(error, { name: "QUOTA_EXCEEDED_ERR", error: e });
            } else {
                delay(error, e);
            }
        }
        finally {
            Date.prototype.toJSON = oldDateToJSON;
        }
    }
};

/** In case of an error, this method will not restore any keys that might have been deleted at that point.
 * @summary Removes all the data associated with this store object.
 * @method module:store/dom~DomStore#clear
 * @param {Function} success - Callback for a successful clear operation.
 * @param {Function} [error] - Callback for handling errors. If not specified then store.defaultError is invoked.
 */
DomStore.prototype.clear = function (success, error) {

    error = error || this.defaultError;
    try {
        var i = 0, len = localStorage.length;
        while (len > 0 && i &lt; len) {
            var fullKey = localStorage.key(i);
            var key = unqualifyDomStoreKey(this, fullKey);
            if (fullKey !== key) {
                localStorage.removeItem(fullKey);
                len = localStorage.length;
            } else {
                i++;
            }
        }
        delay(success);
    }
    catch (e) {
        delay(error, e);
    }
};

/** This function does nothing in DomStore as it does not have a connection model
 * @method module:store/dom~DomStore#close
 */
DomStore.prototype.close = function () {
};

/** Checks whether a key exists in the store.
 * @method module:store/dom~DomStore#contains
 * @param {String} key - Key string.
 * @param {Function} success - Callback indicating whether the store contains the key or not.
 * @param {Function} [error] - Callback for handling errors. If not specified then store.defaultError is invoked.
*/
DomStore.prototype.contains = function (key, success, error) {
    error = error || this.defaultError;
    try {
        var fullKey = qualifyDomStoreKey(this, key);
        var value = localStorage.getItem(fullKey);
        delay(success, value !== null);
    } catch (e) {
        delay(error, e);
    }
};

DomStore.prototype.defaultError = throwErrorCallback;

/** Gets all the keys that exist in the store.
 * @method module:store/dom~DomStore#getAllKeys
 * @param {Function} success - Callback for a successful get operation.
 * @param {Function} [error] - Callback for handling errors. If not specified then store.defaultError is invoked.
 */
DomStore.prototype.getAllKeys = function (success, error) {

    error = error || this.defaultError;

    var results = [];
    var i, len;

    try {
        for (i = 0, len = localStorage.length; i &lt; len; i++) {
            var fullKey = localStorage.key(i);
            var key = unqualifyDomStoreKey(this, fullKey);
            if (fullKey !== key) {
                results.push(key);
            }
        }
        delay(success, results);
    }
    catch (e) {
        delay(error, e);
    }
};

/** Identifies the underlying mechanism used by the store.*/
DomStore.prototype.mechanism = "dom";

/** Reads the value associated to a key in the store.
 * @method module:store/dom~DomStore#read
 * @param {String} key - Key string.
 * @param {Function} success - Callback for a successful reads operation.
 * @param {Function} [error] - Callback for handling errors. If not specified then store.defaultError is invoked.
 */
DomStore.prototype.read = function (key, success, error) {

    error = error || this.defaultError;

    if (key instanceof Array) {
        error({ message: "Array of keys not supported" });
    } else {
        try {
            var fullKey = qualifyDomStoreKey(this, key);
            var value = localStorage.getItem(fullKey);
            if (value !== null && value !== "undefined") {
                // Hydrate using json
                value = window.JSON.parse(value, domStoreJSONToDate);
            }
            else {
                value = undefined;
            }
            delay(success, key, value);
        } catch (e) {
            delay(error, e);
        }
    }
};

/** Removes a key and its value from the store.
 * @method module:store/dom~DomStore#remove
 * @param {String} key - Key string.
 * @param {Function} success - Callback for a successful remove operation.
 * @param {Function} [error] - Callback for handling errors. If not specified then store.defaultError is invoked.
 */
DomStore.prototype.remove = function (key, success, error) {
    error = error || this.defaultError;

    if (key instanceof Array) {
        error({ message: "Batches not supported" });
    } else {
        try {
            var fullKey = qualifyDomStoreKey(this, key);
            localStorage.removeItem(fullKey);
            delay(success);
        } catch (e) {
            delay(error, e);
        }
    }
};

/** Updates the value associated to a key in the store.
 * @method module:store/dom~DomStore#update
 * @param {String} key - Key string.
 * @param value - New value.
 * @param {Function} success - Callback for a successful update operation.
 * @param {Function} [error] - Callback for handling errors. If not specified then store.defaultError is invoked
 * This method errors out if the specified key is not found in the store.
 */
DomStore.prototype.update = function (key, value, success, error) {
    error = error || this.defaultError;
    var store = this;
    this.contains(key, function (contained) {
        if (contained) {
            store.addOrUpdate(key, value, success, error);
        } else {
            delay(error, { message: "key not found", key: key });
        }
    }, error);
};

module.exports = DomStore;</code></pre>
        </article>
    </section>




</div>

<nav>
    <h2><a href="index.html">Index</a></h2><h3>Modules</h3><ul><li><a href="module-cache.html">cache</a></li><li><a href="source.html">cache/source</a></li><li><a href="module-odata.html">odata</a></li><li><a href="batch.html">odata/batch</a></li><li><a href="handler.html">odata/handler</a></li><li><a href="json.html">odata/json</a></li><li><a href="metadata.html">odata/metadata</a></li><li><a href="net.html">odata/net</a></li><li><a href="utils.html">odata/utils</a></li><li><a href="deferred.html">odatajs/deferred</a></li><li><a href="utils_.html">odatajs/utils</a></li><li><a href="xml.html">odatajs/xml</a></li><li><a href="module-store.html">store</a></li><li><a href="dom.html">store/dom</a></li><li><a href="indexeddb.html">store/indexeddb</a></li><li><a href="memory.html">store/memory</a></li></ul><h3>Classes</h3><ul><li><a href="DataCache.html">DataCache</a></li><li><a href="DataCacheOperation.html">DataCacheOperation</a></li><li><a href="DjsDeferred.html">DjsDeferred</a></li><li><a href="dom-DomStore.html">DomStore</a></li><li><a href="indexeddb-IndexedDBStore.html">IndexedDBStore</a></li><li><a href="memory-MemoryStore.html">MemoryStore</a></li><li><a href="ODataCacheSource.html">ODataCacheSource</a></li></ul><h3><a href="global.html">Global</a></h3>
</nav>

<br clear="both">

<footer>
    Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.2.2</a> on Thu Apr 09 2015 08:31:26 GMT+0200 (MESZ)
</footer>

<script> prettyPrint(); </script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>
