Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

New API function - getAll

  • Loading branch information...
commit 8d24afd082eedcc0bb32e40f60ecbec18e7f5334 1 parent 81c7b72
Gil Fink authored
Showing with 576 additions and 505 deletions.
  1. +575 −504 story.js/story.js
  2. +1 −1  story.js/story.min.js
View
1,079 story.js/story.js
@@ -1,510 +1,581 @@
/*!
- * story.js v0.1
- *
- * Copyright (c) Sela Group and Gil Fink. All rights reserved.
- * Dual licensed under the MIT or GPL Version 2 licenses.
- *
- * Date: Fri Apr 20 14:00:12 2012
- */
-
- /*
- * story.js enables web developers to use client-side storages in a common and simple way.
- * It includes abstraction layer on top of Web Storage API, IndexedDB API, Cookies API and
- * In-Memory storage.
- *
- * Authors Gil Fink
- * Contributors Ran Wahle
- */
+* story.js v0.1
+*
+* Copyright (c) Sela Group and Gil Fink. All rights reserved.
+* Dual licensed under the MIT or GPL Version 2 licenses.
+*
+* Date: Fri Apr 20 14:00:12 2012
+*/
+
+/*
+* story.js enables web developers to use client-side storages in a common and simple way.
+* It includes abstraction layer on top of Web Storage API, IndexedDB API, Cookies API and
+* In-Memory storage.
+*
+* Authors Gil Fink
+* Contributors Ran Wahle
+*/
(function (story) {
- var storyKeyPrefix = "__story__",
- storyStorageDefaultName = "_story_",
- storage = story.storage = function (name) {
- if (!name) {
- // In-memory storage is the default storage
- return story.types[story.StorageTypes.IN_MEMORY];
- }
- return story.types[name];
- };
-
- /* Public Members */
-
- story.types = {};
- story.StorageTypes = {
- LOCAL_STORAGE: "LocalStorage",
- SESSION_STORAGE: "SessionStorage",
- INDEXEDDB: "IndexedDB",
- COOKIE: "Cookie",
- IN_MEMORY: "InMemroy"
- };
-
- /* Utility Functions and Objects */
-
- var registerType = function (name, type) {
- story.types[name] = type;
- };
-
- var createStoreKey = function (key) {
- return storyKeyPrefix + key;
- };
-
- story.Promise = function () {
- this.thens = [];
- };
-
- story.Promise.prototype = {
- then: function (onResolve, onReject) {
- this.thens.push({ resolve: onResolve, reject: onReject });
- },
- resolve: function (value) {
- this.complete('resolve', value);
- },
- reject: function (error) {
- this.complete('reject', error);
- },
- complete: function (which, arg) {
- if (which === 'resolve') {
- this.then = function (resolve, reject) {
- resolve(arg);
- }
- }
- else {
- this.then = function (resolve, reject) {
- reject(arg);
- }
- }
- this.resolve = this.reject =
- function () {
- throw new Error('Promise already completed.');
- };
- var aThen, i = 0;
- while (aThen = this.thens[i]) {
- aThen[which] && aThen[which](arg);
- i += 1;
- }
- delete this.thens;
- }
- };
-
- function promiseWrap(storyStorage, impl) {
- var promise = new story.Promise();
- impl(storyStorage, promise);
- return promise;
- }
-
- /*** story Types ***/
-
- /* Web Storage */
-
- var WebStorage = function (type) {
- switch (type) {
- case "local":
- this.storage = window.localStorage;
- break;
- case "session":
- this.storage = window.sessionStorage;
- break;
- default:
- throw new Error("No such Web Storage type");
- }
- };
-
- WebStorage.prototype.get = function (key) {
- return promiseWrap(this, function (storyStorage, promise) {
- try {
- var item = storyStorage.storage.getItem(createStoreKey(key));
- if (item !== null && item !== "undefined") {
- item = window.JSON.parse(item);
- }
- else {
- item = undefined;
- }
- promise.resolve(item);
- }
- catch (e) {
- promise.reject(e);
- }
- });
- };
-
- WebStorage.prototype.add = function (key, value) {
- return promiseWrap(this, function (storyStorage, promise) {
- try {
- storyStorage.storage.setItem(createStoreKey(key), window.JSON.stringify(value));
- promise.resolve({ key: key, value: value });
- }
- catch (e) {
- if (e.code === 22 || e.number === 0x8007000E) {
- promise.reject({ message: "QUOTA_EXCEEDED_ERR", error: e });
- } else {
- promise.reject(e);
- }
- }
- });
- };
-
- WebStorage.prototype.update = function (key, value) {
- return this.add(key, value);
- };
-
- WebStorage.prototype.remove = function (key) {
- return promiseWrap(this, function (storyStorage, promise) {
- try {
- storyStorage.storage.removeItem(createStoreKey(key));
- promise.resolve();
- }
- catch (e) {
- promise.reject(e);
- }
- });
- };
-
- WebStorage.prototype.contains = function (key) {
- return promiseWrap(this, function (storyStorage, promise) {
- try {
- var item = storyStorage.storage.getItem(createStoreKey(key));
- promise.resolve(item !== null);
- }
- catch (e) {
- promise.reject(e);
- }
- });
- };
-
- WebStorage.prototype.clear = function () {
- return promiseWrap(this, function (storyStorage, promise) {
- try {
- storyStorage.storage.clear();
- promise.resolve();
- }
- catch (e) {
- promise.reject(e);
- }
- });
- };
-
- if (window.localStorage) {
- registerType(story.StorageTypes.LOCAL_STORAGE, new WebStorage("local"));
- }
- if (window.sessionStorage) {
- registerType(story.StorageTypes.SESSION_STORAGE, new WebStorage("session"));
- }
-
- /* IndexedDB */
-
- var indexeddb = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.msIndexedDB;
- var transaction = window.IDBTransaction || window.webkitIDBTransaction;
-
- var openTransaction = function (storage, mode) {
- var promise = new story.Promise();
- var name = storage.name;
- var db = storage.db;
- if (db) {
- promise.resolve({ trans: db.transaction(name, mode), name: name });
- } else {
- var request = storage.storage.open(storyStorageDefaultName + name);
- request.onsuccess = function (e) {
- storage.db = e.target.result;
- promise.resolve({ trans: db.transaction(name, mode), name: name });
- };
- request.onerror = function (e) {
- promise.reject(e);
- };
- }
- return promise;
- };
-
- var IDBFactory = function () {
- };
-
- var IDBStorage = function (name) {
- this.name = name;
- };
-
- IDBFactory.prototype.createStore = function (options) {
- var promise = new story.Promise();
- var name = options.name;
- var store = new IDBStorage(name || storyStorageDefaultName);
-
- var request = indexeddb.open(name || storyStorageDefaultName, options.version || 1);
- request.onsuccess = function (e) {
- store.db = request.result;
- promise.resolve(store);
- };
-
- request.onerror = function (e) {
- promise.reject("IndexedDB error: " + e.target.errorCode);
- };
-
- request.onupgradeneeded = function (e) {
- var objectStore = e.currentTarget.result.createObjectStore(name, { keyPath: options.keyPath, autoIncrement: options.autoInc });
-
- for (var len = options.names.length, i = 0; i < len; i += 1) {
- objectStore.createIndex(options.names[i], options.values[i], { unique: options.unique[i] });
- }
- };
- return promise;
- };
-
- IDBStorage.prototype.get = function (key) {
- return promiseWrap(this, function (storyStorage, promise) {
- openTransaction(storyStorage, transaction.READ_WRITE).then(function (options) {
- var values = [];
-
- options.trans.onerror = function (e) {
- promise.reject(e);
- };
- options.trans.oncomplete = function () {
- promise.resolve({ key: key, value: values });
- };
-
- var objectStore = options.trans.objectStore(options.name);
- var request = objectStore.get(key);
- request.onsuccess = function (event) {
- values.push(event.target.result);
- }
- }, function (e) {
- promise.reject(e);
- });
- });
- };
-
- IDBStorage.prototype.add = function (key, value) {
- return promiseWrap(this, function (storyStorage, promise) {
- openTransaction(storyStorage, transaction.READ_WRITE).then(function (options) {
- options.trans.onabort = function (e) {
- promise.reject(e);
- };
- options.trans.oncomplete = function () {
- promise.resolve({ key: key, value: value });
- };
-
- options.trans.objectStore(options.name).add(value, key);
- }, function (e) {
- if (e.code === 11) {
- e = { name: "QUOTA_EXCEEDED_ERR", error: e };
- }
- promise.reject(e);
- });
- });
- };
-
- IDBStorage.prototype.update = function (key, value) {
- return promiseWrap(this, function (storyStorage, promise) {
- openTransaction(storyStorage, transaction.READ_WRITE).then(function (options) {
- options.trans.onabort = function (e) {
- promise.reject(e);
- };
- options.trans.oncomplete = function () {
- promise.resolve({ key: key, value: value });
- };
-
- var request = options.trans.objectStore(options.name).openCursor(key);
- request.pair = { key: key, value: value };
- request.onsuccess = function (event) {
- var cursor = event.target.result;
- if (cursor) {
- cursor.update(event.target.pair.value);
- } else {
- options.trans.abort();
- }
- }
- }, function (e) {
- promise.reject(e);
- });
- });
- };
-
- IDBStorage.prototype.remove = function (key) {
- return promiseWrap(this, function (storyStorage, promise) {
- openTransaction(storyStorage, transaction.READ_WRITE).then(function (options) {
- options.trans.onerror = function (e) {
- promise.reject(e);
- };
- options.trans.oncomplete = function () {
- promise.resolve();
- };
-
- var objectStore = options.trans.objectStore(options.name);
- objectStore["delete"](key);
- }, function (e) {
- promise.reject(e);
- });
- });
- };
-
- IDBStorage.prototype.contains = function (key) {
- return promiseWrap(this, function (storyStorage, promise) {
- openTransaction(storyStorage, transaction.READ_ONLY).then(function (options) {
- var request = options.trans.objectStore(options.name).openCursor(IDBKeyRange.only(key));
- options.trans.oncomplete = function () {
- promise.resolve(request.result !== undefined);
- };
- options.trans.onerror = function (e) {
- promise.reject(e);
- };
- }, function (e) {
- promise.reject(e);
- });
- });
- };
-
- IDBStorage.prototype.clear = function () {
- return promiseWrap(this, function (storyStorage, promise) {
- openTransaction(storyStorage, transaction.READ_WRITE).then(function (options) {
- options.trans.onerror = function (e) {
- promise.reject(e);
- };
- options.trans.oncomplete = function () {
- promise.resolve();
- };
-
- options.trans.objectStore(options.name).clear();
- }, function (e) {
- promise.reject(e);
- });
- });
- };
-
- IDBStorage.prototype.close = function () {
- if (this.db) {
- this.db.close();
- this.db = null;
- }
- };
-
- if (indexeddb) {
- registerType(story.StorageTypes.INDEXEDDB, new IDBFactory());
- }
-
- /* Cookie */
-
- var Cookie = function () {
- };
-
- Cookie.prototype.get = function (key) {
- return promiseWrap(this, function (storyStorage, promise) {
- var match = document.cookie.match('(^|;) ?' + key + '=([^;]*)(;|$)');
-
- if (match) {
- promise.resolve(unescape(match[2]));
- }
- else {
- promise.reject({ message: "Cookie doesn't exists" });
- }
- });
- };
-
- Cookie.prototype.add = function (key, value) {
- return promiseWrap(this, function (storyStorage, promise) {
- var cookieStr = key + "=" + escape(value);
- document.cookie = cookieStr;
- promise.resolve({ key: key, cookieString: cookieStr });
- });
- };
-
- Cookie.prototype.update = function (key, value) {
- return this.add(key, value);
- };
-
- Cookie.prototype.remove = function (key) {
- return promiseWrap(this, function (storyStorage, promise) {
- var expiry = new Date();
- expiry.setTime(expiry.getTime() - 1);
- document.cookie = key += "=; expires=" + expiry.toGMTString();
- promise.resolve();
- });
- };
-
- Cookie.prototype.contains = function (key) {
- return promiseWrap(this, function (storyStorage, promise) {
- var match = document.cookie.match('(^|;) ?' + key + '=([^;]*)(;|$)');
- match ? promise.resolve(true) : promise.resolve(false);
- });
- };
-
- Cookie.prototype.clear = function () {
- return promiseWrap(this, function (storyStorage, promise) {
- document.cookie = "";
- promise.resolve();
- });
- };
-
- registerType(story.StorageTypes.COOKIE, new Cookie());
-
- /* In Memory Storage */
-
- var MemoryStorage = function () {
- this.storage = {};
-
- this.validateKey = function (key) {
- if (key instanceof Array || key === null || key === undefined) {
- return false;
- }
- return true;
- };
- };
-
- MemoryStorage.prototype.get = function (key) {
- return promiseWrap(this, function (storyStorage, promise) {
- if (storyStorage.validateKey(key)) {
- promise.resolve(storyStorage.storage[key]);
- }
- else {
- promise.reject("Invalid Key");
- }
- });
- };
-
- MemoryStorage.prototype.add = function (key, value) {
- return promiseWrap(this, function (storyStorage, promise) {
- if (storyStorage.validateKey(key)) {
- if (!storyStorage.storage.hasOwnProperty(key)) {
- storyStorage.storage[key] = value;
- promise.resolve({ key: key, value: value });
- } else {
- promise.reject({ message: "key already exists", key: key });
- }
- }
- });
- };
-
- MemoryStorage.prototype.update = function (key, value) {
- return promiseWrap(this, function (storyStorage, promise) {
- if (storyStorage.validateKey(key)) {
- if (storyStorage.storage.hasOwnProperty(key)) {
- storyStorage.storage[key] = value;
- promise.resolve({ key: key, value: value });
- }
- }
- });
- };
-
- MemoryStorage.prototype.remove = function (key) {
- return promiseWrap(this, function (storyStorage, promise) {
- if (storyStorage.validateKey(key)) {
- if (storyStorage.storage.hasOwnProperty(key)) {
- delete storyStorage.storage[key];
- }
- promise.resolve();
- }
- });
- };
-
- MemoryStorage.prototype.contains = function (key) {
- return promiseWrap(this, function (storyStorage, promise) {
- promise.resolve(storyStorage.storage.hasOwnProperty(key));
- });
- };
-
- MemoryStorage.prototype.clear = function () {
- return promiseWrap(this, function (storyStorage, promise) {
- storyStorage.storage = {};
- promise.resolve();
- });
- };
-
- registerType(story.StorageTypes.IN_MEMORY, new MemoryStorage());
+ var storyKeyPrefix = "__story__",
+ storyStorageDefaultName = "_story_",
+ storage = story.storage = function (name) {
+ if (!name) {
+ // In-memory storage is the default storage
+ return story.types[story.StorageTypes.IN_MEMORY];
+ }
+ return story.types[name];
+ };
+
+ /* Public Members */
+
+ story.types = {};
+ story.StorageTypes = {
+ LOCAL_STORAGE: "LocalStorage",
+ SESSION_STORAGE: "SessionStorage",
+ INDEXEDDB: "IndexedDB",
+ COOKIE: "Cookie",
+ IN_MEMORY: "InMemroy"
+ };
+
+ /* Utility Functions and Objects */
+
+ var registerType = function (name, type) {
+ story.types[name] = type;
+ };
+
+ var createStoreKey = function (key) {
+ return storyKeyPrefix + key;
+ };
+
+ story.Promise = function () {
+ this.thens = [];
+ };
+
+ story.Promise.prototype = {
+ then: function (onResolve, onReject) {
+ this.thens.push({ resolve: onResolve, reject: onReject });
+ },
+ resolve: function (value) {
+ this.complete('resolve', value);
+ },
+ reject: function (error) {
+ this.complete('reject', error);
+ },
+ complete: function (which, arg) {
+ if (which === 'resolve') {
+ this.then = function (resolve, reject) {
+ resolve(arg);
+ }
+ }
+ else {
+ this.then = function (resolve, reject) {
+ reject(arg);
+ }
+ }
+ this.resolve = this.reject =
+ function () {
+ throw new Error('Promise already completed.');
+ };
+ var aThen, i = 0;
+ while (aThen = this.thens[i]) {
+ aThen[which] && aThen[which](arg);
+ i += 1;
+ }
+ delete this.thens;
+ }
+ };
+
+ function promiseWrap(storyStorage, impl) {
+ var promise = new story.Promise();
+ impl(storyStorage, promise);
+ return promise;
+ }
+
+ /*** story Types ***/
+
+ /* Web Storage */
+
+ var WebStorage = function (type) {
+ switch (type) {
+ case "local":
+ this.storage = window.localStorage;
+ break;
+ case "session":
+ this.storage = window.sessionStorage;
+ break;
+ default:
+ throw new Error("No such Web Storage type");
+ }
+ };
+
+ WebStorage.prototype.get = function (key) {
+ return promiseWrap(this, function (storyStorage, promise) {
+ try {
+ var item = storyStorage.storage.getItem(createStoreKey(key));
+ if (item !== null && item !== "undefined") {
+ item = window.JSON.parse(item);
+ }
+ else {
+ item = undefined;
+ }
+ promise.resolve(item);
+ }
+ catch (e) {
+ promise.reject(e);
+ }
+ });
+ };
+
+ WebStorage.prototype.getAll = function () {
+ return promiseWrap(this, function (storyStorage, promise) {
+ try {
+ var items = [];
+ var len = storyStorage.storage.length;
+ for (var i = 0; i < len; i += 1) {
+ var key = storyStorage.storage.key(i);
+ var item = JSON.parse(storyStorage.storage.getItem(key));
+ items.push(item);
+ }
+ promise.resolve(items);
+ }
+ catch (e) {
+ promise.reject(e);
+ }
+ });
+ };
+
+ WebStorage.prototype.add = function (key, value) {
+ return promiseWrap(this, function (storyStorage, promise) {
+ try {
+ storyStorage.storage.setItem(createStoreKey(key), window.JSON.stringify(value));
+ promise.resolve({ key: key, value: value });
+ }
+ catch (e) {
+ if (e.code === 22 || e.number === 0x8007000E) {
+ promise.reject({ message: "QUOTA_EXCEEDED_ERR", error: e });
+ } else {
+ promise.reject(e);
+ }
+ }
+ });
+ };
+
+ WebStorage.prototype.update = function (key, value) {
+ return this.add(key, value);
+ };
+
+ WebStorage.prototype.remove = function (key) {
+ return promiseWrap(this, function (storyStorage, promise) {
+ try {
+ storyStorage.storage.removeItem(createStoreKey(key));
+ promise.resolve();
+ }
+ catch (e) {
+ promise.reject(e);
+ }
+ });
+ };
+
+ WebStorage.prototype.contains = function (key) {
+ return promiseWrap(this, function (storyStorage, promise) {
+ try {
+ var item = storyStorage.storage.getItem(createStoreKey(key));
+ promise.resolve(item !== null);
+ }
+ catch (e) {
+ promise.reject(e);
+ }
+ });
+ };
+
+ WebStorage.prototype.clear = function () {
+ return promiseWrap(this, function (storyStorage, promise) {
+ try {
+ storyStorage.storage.clear();
+ promise.resolve();
+ }
+ catch (e) {
+ promise.reject(e);
+ }
+ });
+ };
+
+ if (window.localStorage) {
+ registerType(story.StorageTypes.LOCAL_STORAGE, new WebStorage("local"));
+ }
+ if (window.sessionStorage) {
+ registerType(story.StorageTypes.SESSION_STORAGE, new WebStorage("session"));
+ }
+
+ /* IndexedDB */
+
+ var indexeddb = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.msIndexedDB;
+ var transaction = window.IDBTransaction || window.webkitIDBTransaction;
+
+ var openTransaction = function (storage, mode) {
+ var promise = new story.Promise();
+ var name = storage.name;
+ var db = storage.db;
+ if (db) {
+ promise.resolve({ trans: db.transaction(name, mode), name: name });
+ } else {
+ var request = storage.storage.open(storyStorageDefaultName + name);
+ request.onsuccess = function (e) {
+ storage.db = e.target.result;
+ promise.resolve({ trans: db.transaction(name, mode), name: name });
+ };
+ request.onerror = function (e) {
+ promise.reject(e);
+ };
+ }
+ return promise;
+ };
+
+ var IDBFactory = function () {
+ };
+
+ var IDBStorage = function (name) {
+ this.name = name;
+ };
+
+ IDBFactory.prototype.createStore = function (options) {
+ var promise = new story.Promise();
+ var name = options.name;
+ var store = new IDBStorage(name || storyStorageDefaultName);
+
+ var request = indexeddb.open(name || storyStorageDefaultName, options.version || 1);
+ request.onsuccess = function (e) {
+ store.db = request.result;
+ promise.resolve(store);
+ };
+
+ request.onerror = function (e) {
+ promise.reject("IndexedDB error: " + e.target.errorCode);
+ };
+
+ request.onupgradeneeded = function (e) {
+ var objectStore = e.currentTarget.result.createObjectStore(name, { keyPath: options.keyPath, autoIncrement: options.autoInc });
+
+ for (var len = options.names.length, i = 0; i < len; i += 1) {
+ objectStore.createIndex(options.names[i], options.values[i], { unique: options.unique[i] });
+ }
+ };
+ return promise;
+ };
+
+ IDBStorage.prototype.get = function (key) {
+ return promiseWrap(this, function (storyStorage, promise) {
+ openTransaction(storyStorage, transaction.READ_WRITE).then(function (options) {
+ var values = [];
+
+ options.trans.onerror = function (e) {
+ promise.reject(e);
+ };
+ options.trans.oncomplete = function () {
+ promise.resolve({ key: key, value: values });
+ };
+
+ var objectStore = options.trans.objectStore(options.name);
+ var request = objectStore.get(key);
+ request.onsuccess = function (event) {
+ values.push(event.target.result);
+ }
+ }, function (e) {
+ promise.reject(e);
+ });
+ });
+ };
+
+ IDBStorage.prototype.getAll = function () {
+ return promiseWrap(this, function (storyStorage, promise) {
+ openTransaction(storyStorage, transaction.READ_WRITE).then(function (options) {
+ var items = [];
+
+ trans.oncomplete = function (evt) {
+ promise.resolve(items);
+ };
+
+ var request = store.openCursor();
+
+ request.onerror = function (e) {
+ promise.reject(e);
+ };
+
+ request.onsuccess = function (evt) {
+ var cursor = evt.target.result;
+ if (cursor) {
+ items.push(cursor.value);
+ cursor["continue"]();
+ }
+ };
+ }, function (e) {
+ promise.reject(e);
+ });
+ });
+ };
+
+ IDBStorage.prototype.add = function (key, value) {
+ return promiseWrap(this, function (storyStorage, promise) {
+ openTransaction(storyStorage, transaction.READ_WRITE).then(function (options) {
+ options.trans.onabort = function (e) {
+ promise.reject(e);
+ };
+ options.trans.oncomplete = function () {
+ promise.resolve({ key: key, value: value });
+ };
+
+ options.trans.objectStore(options.name).add(value, key);
+ }, function (e) {
+ if (e.code === 11) {
+ e = { name: "QUOTA_EXCEEDED_ERR", error: e };
+ }
+ promise.reject(e);
+ });
+ });
+ };
+
+ IDBStorage.prototype.update = function (key, value) {
+ return promiseWrap(this, function (storyStorage, promise) {
+ openTransaction(storyStorage, transaction.READ_WRITE).then(function (options) {
+ options.trans.onabort = function (e) {
+ promise.reject(e);
+ };
+ options.trans.oncomplete = function () {
+ promise.resolve({ key: key, value: value });
+ };
+
+ var request = options.trans.objectStore(options.name).openCursor(key);
+ request.pair = { key: key, value: value };
+ request.onsuccess = function (event) {
+ var cursor = event.target.result;
+ if (cursor) {
+ cursor.update(event.target.pair.value);
+ } else {
+ options.trans.abort();
+ }
+ }
+ }, function (e) {
+ promise.reject(e);
+ });
+ });
+ };
+
+ IDBStorage.prototype.remove = function (key) {
+ return promiseWrap(this, function (storyStorage, promise) {
+ openTransaction(storyStorage, transaction.READ_WRITE).then(function (options) {
+ options.trans.onerror = function (e) {
+ promise.reject(e);
+ };
+ options.trans.oncomplete = function () {
+ promise.resolve();
+ };
+
+ var objectStore = options.trans.objectStore(options.name);
+ objectStore["delete"](key);
+ }, function (e) {
+ promise.reject(e);
+ });
+ });
+ };
+
+ IDBStorage.prototype.contains = function (key) {
+ return promiseWrap(this, function (storyStorage, promise) {
+ openTransaction(storyStorage, transaction.READ_ONLY).then(function (options) {
+ var request = options.trans.objectStore(options.name).openCursor(IDBKeyRange.only(key));
+ options.trans.oncomplete = function () {
+ promise.resolve(request.result !== undefined);
+ };
+ options.trans.onerror = function (e) {
+ promise.reject(e);
+ };
+ }, function (e) {
+ promise.reject(e);
+ });
+ });
+ };
+
+ IDBStorage.prototype.clear = function () {
+ return promiseWrap(this, function (storyStorage, promise) {
+ openTransaction(storyStorage, transaction.READ_WRITE).then(function (options) {
+ options.trans.onerror = function (e) {
+ promise.reject(e);
+ };
+ options.trans.oncomplete = function () {
+ promise.resolve();
+ };
+
+ options.trans.objectStore(options.name).clear();
+ }, function (e) {
+ promise.reject(e);
+ });
+ });
+ };
+
+ IDBStorage.prototype.close = function () {
+ if (this.db) {
+ this.db.close();
+ this.db = null;
+ }
+ };
+
+ if (indexeddb) {
+ registerType(story.StorageTypes.INDEXEDDB, new IDBFactory());
+ }
+
+ /* Cookie */
+
+ var Cookie = function () {
+ };
+
+ Cookie.prototype.get = function (key) {
+ return promiseWrap(this, function (storyStorage, promise) {
+ var match = document.cookie.match('(^|;) ?' + key + '=([^;]*)(;|$)');
+
+ if (match) {
+ promise.resolve(unescape(match[2]));
+ }
+ else {
+ promise.reject({ message: "Cookie doesn't exists" });
+ }
+ });
+ };
+
+ Cookie.prototype.getAll = function () {
+ return promiseWrap(this, function (storyStorage, promise) {
+ var pairs = document.cookie.split(';');
+ var len = pairs.length;
+ var cookies = [];
+ for (var i = 0; i < len; i++) {
+ var pair = pairs[i].split('=');
+ cookies.push({ key: pair[0], value: unescape(pair[1]) });
+ }
+ promise.resolve(cookies);
+ });
+ }
+
+ Cookie.prototype.add = function (key, value) {
+ return promiseWrap(this, function (storyStorage, promise) {
+ var cookieStr = key + "=" + escape(value);
+ document.cookie = cookieStr;
+ promise.resolve({ key: key, cookieString: cookieStr });
+ });
+ };
+
+ Cookie.prototype.update = function (key, value) {
+ return this.add(key, value);
+ };
+
+ Cookie.prototype.remove = function (key) {
+ return promiseWrap(this, function (storyStorage, promise) {
+ var expiry = new Date();
+ expiry.setTime(expiry.getTime() - 1);
+ document.cookie = key += "=; expires=" + expiry.toGMTString();
+ promise.resolve();
+ });
+ };
+
+ Cookie.prototype.contains = function (key) {
+ return promiseWrap(this, function (storyStorage, promise) {
+ var match = document.cookie.match('(^|;) ?' + key + '=([^;]*)(;|$)');
+ match ? promise.resolve(true) : promise.resolve(false);
+ });
+ };
+
+ Cookie.prototype.clear = function () {
+ return promiseWrap(this, function (storyStorage, promise) {
+ document.cookie = "";
+ promise.resolve();
+ });
+ };
+
+ registerType(story.StorageTypes.COOKIE, new Cookie());
+
+ /* In Memory Storage */
+
+ var MemoryStorage = function () {
+ this.storage = {};
+
+ this.validateKey = function (key) {
+ if (key instanceof Array || key === null || key === undefined) {
+ return false;
+ }
+ return true;
+ };
+ };
+
+ MemoryStorage.prototype.get = function (key) {
+ return promiseWrap(this, function (storyStorage, promise) {
+ if (storyStorage.validateKey(key)) {
+ promise.resolve(storyStorage.storage[key]);
+ }
+ else {
+ promise.reject("Invalid Key");
+ }
+ });
+ };
+
+ MemoryStorage.prototype.getAll = function () {
+ return promiseWrap(this, function (storyStorage, promise) {
+ var items = [];
+ for (property in storyStorage.storage) {
+ if (storyStorage.storage.hasOwnProperty(property)) {
+ items.push({ key: property, value: storyStorage.storage[property] });
+ }
+ }
+ promise.resolve(items);
+ });
+ };
+
+ MemoryStorage.prototype.add = function (key, value) {
+ return promiseWrap(this, function (storyStorage, promise) {
+ if (storyStorage.validateKey(key)) {
+ if (!storyStorage.storage.hasOwnProperty(key)) {
+ storyStorage.storage[key] = value;
+ promise.resolve({ key: key, value: value });
+ } else {
+ promise.reject({ message: "key already exists", key: key });
+ }
+ }
+ });
+ };
+
+ MemoryStorage.prototype.update = function (key, value) {
+ return promiseWrap(this, function (storyStorage, promise) {
+ if (storyStorage.validateKey(key)) {
+ if (storyStorage.storage.hasOwnProperty(key)) {
+ storyStorage.storage[key] = value;
+ promise.resolve({ key: key, value: value });
+ }
+ }
+ });
+ };
+
+ MemoryStorage.prototype.remove = function (key) {
+ return promiseWrap(this, function (storyStorage, promise) {
+ if (storyStorage.validateKey(key)) {
+ if (storyStorage.storage.hasOwnProperty(key)) {
+ delete storyStorage.storage[key];
+ }
+ promise.resolve();
+ }
+ });
+ };
+
+ MemoryStorage.prototype.contains = function (key) {
+ return promiseWrap(this, function (storyStorage, promise) {
+ promise.resolve(storyStorage.storage.hasOwnProperty(key));
+ });
+ };
+
+ MemoryStorage.prototype.clear = function () {
+ return promiseWrap(this, function (storyStorage, promise) {
+ storyStorage.storage = {};
+ promise.resolve();
+ });
+ };
+
+ registerType(story.StorageTypes.IN_MEMORY, new MemoryStorage());
} (this.story = this.story || {}));
View
2  story.js/story.min.js
@@ -6,4 +6,4 @@
*
* Date: Fri Apr 20 14:00:12 2012
*/
-(function (b) { var n = "__story__", k = "_story_", o = b.storage = function (a) { return !a ? b.types[b.StorageTypes.IN_MEMORY] : b.types[a] }; b.types = {}; b.StorageTypes = { LOCAL_STORAGE: "LocalStorage", SESSION_STORAGE: "SessionStorage", INDEXEDDB: "IndexedDB", COOKIE: "Cookie", IN_MEMORY: "InMemroy" }; var i = function (a, c) { b.types[a] = c }, j = function (a) { return n + a }; b.Promise = function () { this.thens = [] }; b.Promise.prototype = { then: function (a, b) { this.thens.push({ resolve: a, reject: b }) }, resolve: function (a) { this.complete("resolve", a) }, reject: function (a) { this.complete("reject", a) }, complete: function (b, c) { if (b === "resolve") this.then = function (a) { a(c) }; else this.then = function (b, a) { a(c) }; this.resolve = this.reject = function () { throw new Error("Promise already completed."); }; var a, d = 0; while (a = this.thens[d]) { a[b] && a[b](c); d += 1 } delete this.thens } }; function a(c, d) { var a = new b.Promise; d(c, a); return a } var d = function (a) { switch (a) { case "local": this.storage = window.localStorage; break; case "session": this.storage = window.sessionStorage; break; default: throw new Error("No such Web Storage type"); } }; d.prototype.get = function (b) { return a(this, function (d, c) { try { var a = d.storage.getItem(j(b)); if (a !== null && a !== "undefined") a = window.JSON.parse(a); else a = undefined; c.resolve(a) } catch (e) { c.reject(e) } }) }; d.prototype.add = function (c, b) { return a(this, function (d, a) { try { d.storage.setItem(j(c), window.JSON.stringify(b)); a.resolve({ key: c, value: b }) } catch (e) { if (e.code === 22 || e.number === 2147942414) a.reject({ message: "QUOTA_EXCEEDED_ERR", error: e }); else a.reject(e) } }) }; d.prototype.update = function (b, a) { return this.add(b, a) }; d.prototype.remove = function (b) { return a(this, function (c, a) { try { c.storage.removeItem(j(b)); a.resolve() } catch (d) { a.reject(d) } }) }; d.prototype.contains = function (b) { return a(this, function (c, a) { try { var d = c.storage.getItem(j(b)); a.resolve(d !== null) } catch (e) { a.reject(e) } }) }; d.prototype.clear = function () { return a(this, function (b, a) { try { b.storage.clear(); a.resolve() } catch (c) { a.reject(c) } }) }; window.localStorage && i(b.StorageTypes.LOCAL_STORAGE, new d("local")); window.sessionStorage && i(b.StorageTypes.SESSION_STORAGE, new d("session")); var m = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.msIndexedDB, h = window.IDBTransaction || window.webkitIDBTransaction, g = function (d, g) { var c = new b.Promise, a = d.name, e = d.db; if (e) c.resolve({ trans: e.transaction(a, g), name: a }); else { var f = d.storage.open(k + a); f.onsuccess = function (b) { d.db = b.target.result; c.resolve({ trans: e.transaction(a, g), name: a }) }; f.onerror = function (a) { c.reject(a) } } return c }, l = function () { }, c = function (a) { this.name = a }; l.prototype.createStore = function (a) { var e = new b.Promise, f = a.name, g = new c(f || k), d = m.open(f || k, a.version || 1); d.onsuccess = function () { g.db = d.result; e.resolve(g) }; d.onerror = function (a) { e.reject("IndexedDB error: " + a.target.errorCode) }; d.onupgradeneeded = function (e) { for (var c = e.currentTarget.result.createObjectStore(f, { keyPath: a.keyPath, autoIncrement: a.autoInc }), d = a.names.length, b = 0; b < d; b += 1) c.createIndex(a.names[b], a.values[b], { unique: a.unique[b] }) }; return e }; c.prototype.get = function (b) { return a(this, function (c, a) { g(c, h.READ_WRITE).then(function (c) { var d = []; c.trans.onerror = function (b) { a.reject(b) }; c.trans.oncomplete = function () { a.resolve({ key: b, value: d }) }; var e = c.trans.objectStore(c.name), f = e.get(b); f.onsuccess = function (a) { d.push(a.target.result) } }, function (b) { a.reject(b) }) }) }; c.prototype.add = function (c, b) { return a(this, function (d, a) { g(d, h.READ_WRITE).then(function (d) { d.trans.onabort = function (b) { a.reject(b) }; d.trans.oncomplete = function () { a.resolve({ key: c, value: b }) }; d.trans.objectStore(d.name).add(b, c) }, function (b) { if (b.code === 11) b = { name: "QUOTA_EXCEEDED_ERR", error: b }; a.reject(b) }) }) }; c.prototype.update = function (b, c) { return a(this, function (d, a) { g(d, h.READ_WRITE).then(function (d) { d.trans.onabort = function (b) { a.reject(b) }; d.trans.oncomplete = function () { a.resolve({ key: b, value: c }) }; var e = d.trans.objectStore(d.name).openCursor(b); e.pair = { key: b, value: c }; e.onsuccess = function (b) { var a = b.target.result; if (a) a.update(b.target.pair.value); else d.trans.abort() } }, function (b) { a.reject(b) }) }) }; c.prototype.remove = function (b) { return a(this, function (c, a) { g(c, h.READ_WRITE).then(function (c) { c.trans.onerror = function (b) { a.reject(b) }; c.trans.oncomplete = function () { a.resolve() }; var d = c.trans.objectStore(c.name); d["delete"](b) }, function (b) { a.reject(b) }) }) }; c.prototype.contains = function (b) { return a(this, function (c, a) { g(c, h.READ_ONLY).then(function (c) { var d = c.trans.objectStore(c.name).openCursor(IDBKeyRange.only(b)); c.trans.oncomplete = function () { a.resolve(d.result !== undefined) }; c.trans.onerror = function (b) { a.reject(b) } }, function (b) { a.reject(b) }) }) }; c.prototype.clear = function () { return a(this, function (b, a) { g(b, h.READ_WRITE).then(function (b) { b.trans.onerror = function (b) { a.reject(b) }; b.trans.oncomplete = function () { a.resolve() }; b.trans.objectStore(b.name).clear() }, function (b) { a.reject(b) }) }) }; c.prototype.close = function () { if (this.db) { this.db.close(); this.db = null } }; m && i(b.StorageTypes.INDEXEDDB, new l); var f = function () { }; f.prototype.get = function (b) { return a(this, function (d, a) { var c = document.cookie.match("(^|;) ?" + b + "=([^;]*)(;|$)"); if (c) a.resolve(unescape(c[2])); else a.reject({ message: "Cookie doesn't exists" }) }) }; f.prototype.add = function (b, c) { return a(this, function (e, d) { var a = b + "=" + escape(c); document.cookie = a; d.resolve({ key: b, cookieString: a }) }) }; f.prototype.update = function (b, a) { return this.add(b, a) }; f.prototype.remove = function (b) { return a(this, function (d, c) { var a = new Date; a.setTime(a.getTime() - 1); document.cookie = b += "=; expires=" + a.toGMTString(); c.resolve() }) }; f.prototype.contains = function (b) { return a(this, function (d, a) { var c = document.cookie.match("(^|;) ?" + b + "=([^;]*)(;|$)"); c ? a.resolve(true) : a.resolve(false) }) }; f.prototype.clear = function () { return a(this, function (b, a) { document.cookie = ""; a.resolve() }) }; i(b.StorageTypes.COOKIE, new f); var e = function () { this.storage = {}; this.validateKey = function (a) { return a instanceof Array || a === null || a === undefined ? false : true } }; e.prototype.get = function (b) { return a(this, function (a, c) { if (a.validateKey(b)) c.resolve(a.storage[b]); else c.reject("Invalid Key") }) }; e.prototype.add = function (b, c) { return a(this, function (a, d) { if (a.validateKey(b)) if (!a.storage.hasOwnProperty(b)) { a.storage[b] = c; d.resolve({ key: b, value: c }) } else d.reject({ message: "key already exists", key: b }) }) }; e.prototype.update = function (b, c) { return a(this, function (a, d) { if (a.validateKey(b)) if (a.storage.hasOwnProperty(b)) { a.storage[b] = c; d.resolve({ key: b, value: c }) } }) }; e.prototype.remove = function (b) { return a(this, function (a, c) { if (a.validateKey(b)) { if (a.storage.hasOwnProperty(b)) delete a.storage[b]; c.resolve() } }) }; e.prototype.contains = function (b) { return a(this, function (a, c) { c.resolve(a.storage.hasOwnProperty(b)) }) }; e.prototype.clear = function () { return a(this, function (a, b) { a.storage = {}; b.resolve() }) }; i(b.StorageTypes.IN_MEMORY, new e) })(this.story = this.story || {});
+(function (b) { var n = "__story__", k = "_story_", o = b.storage = function (a) { return !a ? b.types[b.StorageTypes.IN_MEMORY] : b.types[a] }; b.types = {}; b.StorageTypes = { LOCAL_STORAGE: "LocalStorage", SESSION_STORAGE: "SessionStorage", INDEXEDDB: "IndexedDB", COOKIE: "Cookie", IN_MEMORY: "InMemroy" }; var i = function (a, c) { b.types[a] = c }, j = function (a) { return n + a }; b.Promise = function () { this.thens = [] }; b.Promise.prototype = { then: function (a, b) { this.thens.push({ resolve: a, reject: b }) }, resolve: function (a) { this.complete("resolve", a) }, reject: function (a) { this.complete("reject", a) }, complete: function (b, c) { if (b === "resolve") this.then = function (a) { a(c) }; else this.then = function (b, a) { a(c) }; this.resolve = this.reject = function () { throw new Error("Promise already completed."); }; var a, d = 0; while (a = this.thens[d]) { a[b] && a[b](c); d += 1 } delete this.thens } }; function a(c, d) { var a = new b.Promise; d(c, a); return a } var d = function (a) { switch (a) { case "local": this.storage = window.localStorage; break; case "session": this.storage = window.sessionStorage; break; default: throw new Error("No such Web Storage type"); } }; d.prototype.get = function (b) { return a(this, function (d, c) { try { var a = d.storage.getItem(j(b)); if (a !== null && a !== "undefined") a = window.JSON.parse(a); else a = undefined; c.resolve(a) } catch (e) { c.reject(e) } }) }; d.prototype.getAll = function () { return a(this, function (a, c) { try { for (var d = [], g = a.storage.length, b = 0; b < g; b += 1) { var f = a.storage.key(b), e = JSON.parse(a.storage.getItem(f)); d.push(e) } c.resolve(d) } catch (h) { c.reject(h) } }) }; d.prototype.add = function (c, b) { return a(this, function (d, a) { try { d.storage.setItem(j(c), window.JSON.stringify(b)); a.resolve({ key: c, value: b }) } catch (e) { if (e.code === 22 || e.number === 2147942414) a.reject({ message: "QUOTA_EXCEEDED_ERR", error: e }); else a.reject(e) } }) }; d.prototype.update = function (b, a) { return this.add(b, a) }; d.prototype.remove = function (b) { return a(this, function (c, a) { try { c.storage.removeItem(j(b)); a.resolve() } catch (d) { a.reject(d) } }) }; d.prototype.contains = function (b) { return a(this, function (c, a) { try { var d = c.storage.getItem(j(b)); a.resolve(d !== null) } catch (e) { a.reject(e) } }) }; d.prototype.clear = function () { return a(this, function (b, a) { try { b.storage.clear(); a.resolve() } catch (c) { a.reject(c) } }) }; window.localStorage && i(b.StorageTypes.LOCAL_STORAGE, new d("local")); window.sessionStorage && i(b.StorageTypes.SESSION_STORAGE, new d("session")); var m = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.msIndexedDB, h = window.IDBTransaction || window.webkitIDBTransaction, g = function (d, g) { var c = new b.Promise, a = d.name, e = d.db; if (e) c.resolve({ trans: e.transaction(a, g), name: a }); else { var f = d.storage.open(k + a); f.onsuccess = function (b) { d.db = b.target.result; c.resolve({ trans: e.transaction(a, g), name: a }) }; f.onerror = function (a) { c.reject(a) } } return c }, l = function () { }, c = function (a) { this.name = a }; l.prototype.createStore = function (a) { var e = new b.Promise, f = a.name, g = new c(f || k), d = m.open(f || k, a.version || 1); d.onsuccess = function () { g.db = d.result; e.resolve(g) }; d.onerror = function (a) { e.reject("IndexedDB error: " + a.target.errorCode) }; d.onupgradeneeded = function (e) { for (var c = e.currentTarget.result.createObjectStore(f, { keyPath: a.keyPath, autoIncrement: a.autoInc }), d = a.names.length, b = 0; b < d; b += 1) c.createIndex(a.names[b], a.values[b], { unique: a.unique[b] }) }; return e }; c.prototype.get = function (b) { return a(this, function (c, a) { g(c, h.READ_WRITE).then(function (c) { var d = []; c.trans.onerror = function (b) { a.reject(b) }; c.trans.oncomplete = function () { a.resolve({ key: b, value: d }) }; var e = c.trans.objectStore(c.name), f = e.get(b); f.onsuccess = function (a) { d.push(a.target.result) } }, function (b) { a.reject(b) }) }) }; c.prototype.getAll = function () { return a(this, function (b, a) { g(b, h.READ_WRITE).then(function () { var c = []; trans.oncomplete = function () { a.resolve(c) }; var b = store.openCursor(); b.onerror = function (b) { a.reject(b) }; b.onsuccess = function (b) { var a = b.target.result; if (a) { c.push(a.value); a["continue"]() } } }, function (b) { a.reject(b) }) }) }; c.prototype.add = function (c, b) { return a(this, function (d, a) { g(d, h.READ_WRITE).then(function (d) { d.trans.onabort = function (b) { a.reject(b) }; d.trans.oncomplete = function () { a.resolve({ key: c, value: b }) }; d.trans.objectStore(d.name).add(b, c) }, function (b) { if (b.code === 11) b = { name: "QUOTA_EXCEEDED_ERR", error: b }; a.reject(b) }) }) }; c.prototype.update = function (b, c) { return a(this, function (d, a) { g(d, h.READ_WRITE).then(function (d) { d.trans.onabort = function (b) { a.reject(b) }; d.trans.oncomplete = function () { a.resolve({ key: b, value: c }) }; var e = d.trans.objectStore(d.name).openCursor(b); e.pair = { key: b, value: c }; e.onsuccess = function (b) { var a = b.target.result; if (a) a.update(b.target.pair.value); else d.trans.abort() } }, function (b) { a.reject(b) }) }) }; c.prototype.remove = function (b) { return a(this, function (c, a) { g(c, h.READ_WRITE).then(function (c) { c.trans.onerror = function (b) { a.reject(b) }; c.trans.oncomplete = function () { a.resolve() }; var d = c.trans.objectStore(c.name); d["delete"](b) }, function (b) { a.reject(b) }) }) }; c.prototype.contains = function (b) { return a(this, function (c, a) { g(c, h.READ_ONLY).then(function (c) { var d = c.trans.objectStore(c.name).openCursor(IDBKeyRange.only(b)); c.trans.oncomplete = function () { a.resolve(d.result !== undefined) }; c.trans.onerror = function (b) { a.reject(b) } }, function (b) { a.reject(b) }) }) }; c.prototype.clear = function () { return a(this, function (b, a) { g(b, h.READ_WRITE).then(function (b) { b.trans.onerror = function (b) { a.reject(b) }; b.trans.oncomplete = function () { a.resolve() }; b.trans.objectStore(b.name).clear() }, function (b) { a.reject(b) }) }) }; c.prototype.close = function () { if (this.db) { this.db.close(); this.db = null } }; m && i(b.StorageTypes.INDEXEDDB, new l); var f = function () { }; f.prototype.get = function (b) { return a(this, function (d, a) { var c = document.cookie.match("(^|;) ?" + b + "=([^;]*)(;|$)"); if (c) a.resolve(unescape(c[2])); else a.reject({ message: "Cookie doesn't exists" }) }) }; f.prototype.getAll = function () { return a(this, function (g, e) { for (var c = document.cookie.split(";"), f = c.length, b = [], a = 0; a < f; a++) { var d = c[a].split("="); b.push({ key: d[0], value: unescape(d[1]) }) } e.resolve(b) }) }; f.prototype.add = function (b, c) { return a(this, function (e, d) { var a = b + "=" + escape(c); document.cookie = a; d.resolve({ key: b, cookieString: a }) }) }; f.prototype.update = function (b, a) { return this.add(b, a) }; f.prototype.remove = function (b) { return a(this, function (d, c) { var a = new Date; a.setTime(a.getTime() - 1); document.cookie = b += "=; expires=" + a.toGMTString(); c.resolve() }) }; f.prototype.contains = function (b) { return a(this, function (d, a) { var c = document.cookie.match("(^|;) ?" + b + "=([^;]*)(;|$)"); c ? a.resolve(true) : a.resolve(false) }) }; f.prototype.clear = function () { return a(this, function (b, a) { document.cookie = ""; a.resolve() }) }; i(b.StorageTypes.COOKIE, new f); var e = function () { this.storage = {}; this.validateKey = function (a) { return a instanceof Array || a === null || a === undefined ? false : true } }; e.prototype.get = function (b) { return a(this, function (a, c) { if (a.validateKey(b)) c.resolve(a.storage[b]); else c.reject("Invalid Key") }) }; e.prototype.getAll = function () { return a(this, function (a, c) { var b = []; for (property in a.storage) a.storage.hasOwnProperty(property) && b.push({ key: property, value: a.storage[property] }); c.resolve(b) }) }; e.prototype.add = function (b, c) { return a(this, function (a, d) { if (a.validateKey(b)) if (!a.storage.hasOwnProperty(b)) { a.storage[b] = c; d.resolve({ key: b, value: c }) } else d.reject({ message: "key already exists", key: b }) }) }; e.prototype.update = function (b, c) { return a(this, function (a, d) { if (a.validateKey(b)) if (a.storage.hasOwnProperty(b)) { a.storage[b] = c; d.resolve({ key: b, value: c }) } }) }; e.prototype.remove = function (b) { return a(this, function (a, c) { if (a.validateKey(b)) { if (a.storage.hasOwnProperty(b)) delete a.storage[b]; c.resolve() } }) }; e.prototype.contains = function (b) { return a(this, function (a, c) { c.resolve(a.storage.hasOwnProperty(b)) }) }; e.prototype.clear = function () { return a(this, function (a, b) { a.storage = {}; b.resolve() }) }; i(b.StorageTypes.IN_MEMORY, new e) })(this.story = this.story || {});
Please sign in to comment.
Something went wrong with that request. Please try again.