StorageBin

PHOTO EMBED

Sun Feb 06 2022 18:54:42 GMT+0000 (UTC)

Saved by @daemondevin #javascript #localstorage #cookies

/**
 * ## StorageBin
 * A localStorage wrapper with a cookie fallback
 * 
 * All methods checks for localStorage support first
 * 
 * If no support is found then all methods will 
 * fallback to implementing cookies instead.
 */
const prefs = new function StorageBin () {
    let self = this,
        test = "a";

    const supported = () => {
        let granted;
        try {
            window.localStorage.setItem(test, test);
            window.localStorage.removeItem(test);
            granted = true;
        } catch (e) {
            granted = false;
        }
        return granted;
    };

    /**
     * Stores the specified key/value pair allowing
     * for the following types: <em>string</em>, <em>number</em>,
     * <em>boolean</em>, <em>object</em>, and <em>array</em>.<br />
     * If no key is supplied and only an object is passed,
     * this function acts as an alias for <code>StorageBin.store()</code>.
     * 
     * @param {string/int/boolean/object/array} key 
     * @param {object/string} value
     */
    StorageBin.prototype.set = function(key, value) {
        if (supported) {
            if (arguments.length === 1) {
                self.store(key);
            } else if (typeof key === "string") {
                if (typeof value === "object") {
                    value = JSON.stringify(value);
                }
                window.localStorage.setItem(key, value);
            } else {
                throw new TypeError("Failed to execute StorageBin.set(): one or more arguments are invalid");
            }
        } else {
            document.cookie = key + "=" + value + "; path=/";
        }
    };

    /**
     * Stores the object in localStorage, allowing access to individual object properties
     * @param {object} value
     */
    StorageBin.prototype.store = function(value) {
        if (typeof value === "object" && !(value instanceof Array)) {
            for (const property in value) {
                if(value.hasOwnProperty(property)) {
                    window.localStorage.setItem(property, value[property]);
                }
            }
        } else {
            throw new TypeError("Failed to execute StorageBin.store(): argument must be of type object! " + typeof(value) + " given.");
        }
    };
    
    /**
     * Returns the value of a specified key in localStorage.
     * This value is converted to its proper type upon retrieval.
     * If the key is not in local storage, then defaultValue is
     * returned if specified.
     * @param key
     * @param defaultValue
     * @returns {string|boolean|null|number|any}
     */
    StorageBin.prototype.get = function(key, defaultValue) {
        if (supported) {
            if (typeof key !== "string") {
                throw new TypeError("Failed to execute StorageBin.get(): key must be of type string! " + typeof(key) + " given.");
            }

            let value = window.localStorage.getItem(key); // retrieve value
            let number = parseFloat(value); // to allow for number checking

            if (value === null) {
                // Returns default value if key is not set, otherwise returns null
                return arguments.length === 2 ? defaultValue : null;
            } else if (!isNaN(number)) {
                return number; // value was of type number
            } else if (
                value.toLowerCase() === "true" ||
                value.toLowerCase() === "false"
            ) {
                return value === "true"; //value was of type boolean
            } else {
                try {
                    value = JSON.parse(value);
                    return value;
                } catch (e) {
                    return value;
                }
            }
        } else {
            let key_equals = key + "=",
                cookies = document.cookie.split(";");
            for (let i = 0, j = cookies.length; i < j; i++) {
                let this_cookie = cookies[i];
                while (this_cookie.charAt(0) === " ") {
                    this_cookie = this_cookie.substring(1, this_cookie.length);
                }
                if (this_cookie.indexOf(key_equals) === 0) {
                    return this_cookie.substring(
                        key_equals.length,
                        this_cookie.length
                    );
                }
            }
            return null;
        }
    };

    /**
     * Returns an array of keys currently stored in localStorage
     * @returns {*[]}
     */
    StorageBin.prototype.getKeys = function() {
        let result = [];
        for (let i = 0; i < window.localStorage.length; i++) {
            result.push(window.localStorage.key(i));
        }
        return result;
    };

    /**
     * Checks if localStorage contains the specified key
     * @param {string} key
     * @returns {boolean}
     */
    StorageBin.prototype.contains = function(key) {
        if (typeof key !== "string") {
            throw new TypeError("Failed to execute StorageBin.contains(): key must be of type string! " + typeof(key) + " given.");
        }
        return self.getKeys().indexOf(key) !== -1;
    };

    /**
     * Removes the specified key/value pair from localStorage given a key<br/>
     * Optionally takes an array to remove key/value pairs specified in the array
     * @param {string/array} key
     */
    StorageBin.prototype.del = function(key) {
        if (supported) {
            if (typeof key === "string") {
                window.localStorage.removeItem(key);
            } else if (key instanceof Array) {
                for (let i = 0; i < key.length; i++) {
                    if (typeof key[i] === "string") {
                        window.localStorage.removeItem(key[i]);
                    } else {
                        throw new TypeError("Failed to execute StorageBin.del(): the array key at index " + i + " must be of type string! " + typeof(key[i]) + " given.");
                    }
                }
            } else {
                throw new TypeError("Failed to execute StorageBin.del(): key must be of type string! " + typeof(key) + " given.");
            }
        } else {
            self.set(key, "");
        }
    };

    /**
     * An alias for <code>StorageBin.clear()</code>
     */
    StorageBin.prototype.empty = function() {
        self.clear();
    };

    /**
     * Removes all key/value pairs from localStorage
     */
    StorageBin.prototype.clear = function() {
        if (supported) {
            window.localStorage.clear();
        } else {
            let cookies = document.cookie.split(";");
            let i = 0,
                j = cookies.length;
            for (; i < j; i++) {
                let this_cookie = cookies[i];
                let equals_position = this_cookie.indexOf("=");
                let name =
                    equals_position > -1 ? this_cookie.substr(0, equals_position) : this_cookie;
                document.cookie =
                    name + "=;expires=Thu, 01 Jan 1970 00:00:00 GMT";
            }
        }
    };

    /**
     * Returns an object representation of the current state of localStorage
     * @returns {{}}
     */
    StorageBin.prototype.toObject = function() {
        const o = {};
        const keys = self.getKeys();

        for (let i = 0; i < keys.length; i++) {
            const key = keys[i];
            o[key] = self.get(key);
        }
        return o;
    };
}();
content_copyCOPY

https://github.com/daemondevin/cdn/blob/main/StorageBin.js