<!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>
    <!--[if lt IE 9]>
      <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
    <![endif]-->
    <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>
