From 21b648e923ff6c608bfd8037c913d40ff11efb1f Mon Sep 17 00:00:00 2001 From: Cyril CHAPON Date: Wed, 10 Oct 2018 10:20:26 +0200 Subject: [PATCH 1/3] Add storage opt in hub. Can now configure localStorage or sessionStorage --- README.md | 17 ++++++++++------- dist/client.js | 6 +++--- dist/client.min.js | 2 +- dist/hub.js | 33 ++++++++++++++++++++------------- dist/hub.min.js | 2 +- lib/client.js | 6 +++--- lib/hub.js | 33 ++++++++++++++++++++------------- test/getOnlyHub.html | 2 +- test/invalidOriginHub.html | 2 +- 9 files changed, 60 insertions(+), 43 deletions(-) diff --git a/README.md b/README.md index 6d16d7d..bf06f47 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Features an API using ES6 promises. * [Overview](#overview) * [Installation](#installation) * [API](#api) - * [CrossStorageHub.init(permissions)](#crossstoragehubinitpermissions) + * [CrossStorageHub.init(opts)](#crossstoragehubinitopts) * [new CrossStorageClient(url, \[opts\])](#new-crossstorageclienturl-opts) * [CrossStorageClient.prototype.onConnect()](#crossstorageclientprototypeonconnect) * [CrossStorageClient.prototype.set(key, value)](#crossstorageclientprototypesetkey-value) @@ -30,13 +30,13 @@ The library is a convenient alternative to sharing a root domain cookie. Unlike cookies, your client-side data isn't limited to a few kilobytes - you get up to 2.49M chars. For a client-heavy application, you can potentially shave a few KB off your request headers by avoiding cookies. This is all thanks -to LocalStorage, which is available in IE 8+, FF 3.5+, Chrome 4+, as well as a +to LocalStorage / SessionStorage API, which is available in IE 8+, FF 3.5+, Chrome 4+, as well as a majority of mobile browsers. For a list of compatible browsers, refer to [caniuse](http://caniuse.com/#feat=namevalue-storage). How does it work? The library is divided into two types of components: hubs and clients. The hubs reside on a host of choice and interact directly with -the LocalStorage API. The clients then load said hub over an embedded iframe +the LocalStorage / SessionStorage API. The clients then load said hub over an embedded iframe and post messages, requesting data to be stored, retrieved, and deleted. This allows multiple clients to access and share the data located in a single store. @@ -119,10 +119,13 @@ init code via another resource. ## API -#### CrossStorageHub.init(permissions) +#### CrossStorageHub.init(opts) -Accepts an array of objects with two keys: origin and allow. The value +Accepts an option object, which may include a permissions and a storage +The permissions is an array of objects with two keys: origin and allow. The value of origin is expected to be a RegExp, and allow, an array of strings. +The storage option can be one of `window.localStorage` +or `window.sessionStorage`. Default is window.localStorage (if supported). The cross storage hub is then initialized to accept requests from any of the matching origins, allowing access to the associated lists of methods. Methods may include any of: get, set, del, getKeys and clear. A 'ready' @@ -222,7 +225,7 @@ storage.onConnect().then(function() { #### CrossStorageClient.prototype.clear() -Returns a promise that, when resolved, indicates that all localStorage +Returns a promise that, when resolved, indicates that all storage data has been cleared. ``` javascript @@ -283,7 +286,7 @@ cookies for those user agents, or requesting the data from a server-side store. ## Compression -Most localStorage-compatible browsers offer at least ~5Mb of storage. But keys +Most localStorage/sessionStorage-compatible browsers offer at least ~5Mb of storage. But keys and values are defined as DOMStrings, which are UTF-8 encoded using single 16-bit sequences. That means a string of ~2.5 million ASCII characters will use up ~5Mb, since they're 2 bytes per char. diff --git a/dist/client.js b/dist/client.js index 51e804d..4a9cc48 100644 --- a/dist/client.js +++ b/dist/client.js @@ -217,7 +217,7 @@ }; /** - * Returns a promise that, when resolved, indicates that all localStorage + * Returns a promise that, when resolved, indicates that all storage * data has been cleared. * * @returns {Promise} A promise that is settled on hub response or timeout @@ -284,12 +284,12 @@ // Ignore messages not from the correct origin if (origin !== client._origin) return; - // LocalStorage isn't available in the hub + // Underlying storage isn't available in the hub if (message.data === 'cross-storage:unavailable') { if (!client._closed) client.close(); if (!client._requests.connect) return; - error = new Error('Closing client. Could not access localStorage in hub.'); + error = new Error('Closing client. Could not access underlying storage in hub.'); for (i = 0; i < client._requests.connect.length; i++) { client._requests.connect[i](error); } diff --git a/dist/client.min.js b/dist/client.min.js index c78e991..bf510c3 100644 --- a/dist/client.min.js +++ b/dist/client.min.js @@ -8,4 +8,4 @@ * @license Apache-2.0 */ -!function(e){function t(e,r){r=r||{},this._id=t._generateUUID(),this._promise=r.promise||Promise,this._frameId=r.frameId||"CrossStorageClient-"+this._id,this._origin=t._getOrigin(e),this._requests={},this._connected=!1,this._closed=!1,this._count=0,this._timeout=r.timeout||5e3,this._listener=null,this._installListener();var o;r.frameId&&(o=document.getElementById(r.frameId)),o&&this._poll(),o=o||this._createFrame(e),this._hub=o.contentWindow}t.frameStyle={display:"none",position:"absolute",top:"-999px",left:"-999px"},t._getOrigin=function(e){var t,r,o;return t=document.createElement("a"),t.href=e,t.host||(t=window.location),r=t.protocol&&":"!==t.protocol?t.protocol:window.location.protocol,o=r+"//"+t.host,o=o.replace(/:80$|:443$/,"")},t._generateUUID=function(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(e){var t=16*Math.random()|0,r="x"==e?t:3&t|8;return r.toString(16)})},t.prototype.onConnect=function(){var e=this;return this._connected?this._promise.resolve():this._closed?this._promise.reject(new Error("CrossStorageClient has closed")):(this._requests.connect||(this._requests.connect=[]),new this._promise(function(t,r){var o=setTimeout(function(){r(new Error("CrossStorageClient could not connect"))},e._timeout);e._requests.connect.push(function(e){return clearTimeout(o),e?r(e):(t(),void 0)})}))},t.prototype.set=function(e,t){return this._request("set",{key:e,value:t})},t.prototype.get=function(){var e=Array.prototype.slice.call(arguments);return this._request("get",{keys:e})},t.prototype.del=function(){var e=Array.prototype.slice.call(arguments);return this._request("del",{keys:e})},t.prototype.clear=function(){return this._request("clear")},t.prototype.getKeys=function(){return this._request("getKeys")},t.prototype.close=function(){var e=document.getElementById(this._frameId);e&&e.parentNode.removeChild(e),window.removeEventListener?window.removeEventListener("message",this._listener,!1):window.detachEvent("onmessage",this._listener),this._connected=!1,this._closed=!0},t.prototype._installListener=function(){var e=this;this._listener=function(t){var r,o,n,s;if(!e._closed&&t.data&&"string"==typeof t.data&&(o="null"===t.origin?"file://":t.origin,o===e._origin))if("cross-storage:unavailable"!==t.data){if(-1!==t.data.indexOf("cross-storage:")&&!e._connected){if(e._connected=!0,!e._requests.connect)return;for(r=0;r1?r:r[0]},t._del=function(e){for(var t=0;te;e++)r.push(window.localStorage.key(e));return r},t._inArray=function(e,t){for(var r=0;r1?n:n[0]},t._del=function(e){for(var r=0;re;e++)n.push(t._storage.key(e));return n},t._inArray=function(e,t){for(var r=0;r diff --git a/test/invalidOriginHub.html b/test/invalidOriginHub.html index 842c30e..972f1b8 100644 --- a/test/invalidOriginHub.html +++ b/test/invalidOriginHub.html @@ -9,6 +9,6 @@ {origin: /^someOtherOrigin$/, allow: ['get', 'set', 'del']} ]); - window.localStorage.setItem('key1', 'original'); + CrossStorageHub._storage.setItem('key1', 'original'); From 318bcece10e8160bd1d3a8a41449f583a5f6e58d Mon Sep 17 00:00:00 2001 From: Cyril CHAPON Date: Wed, 10 Oct 2018 10:59:23 +0200 Subject: [PATCH 2/3] Fix test for storageHub options --- test/getOnlyHub.html | 8 +++++--- test/hub.html | 8 +++++--- test/invalidOriginHub.html | 8 +++++--- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/test/getOnlyHub.html b/test/getOnlyHub.html index 95fef74..17dc7ae 100644 --- a/test/getOnlyHub.html +++ b/test/getOnlyHub.html @@ -5,9 +5,11 @@ diff --git a/test/hub.html b/test/hub.html index 0895165..84ab6bf 100644 --- a/test/hub.html +++ b/test/hub.html @@ -5,8 +5,10 @@ diff --git a/test/invalidOriginHub.html b/test/invalidOriginHub.html index 972f1b8..cd45741 100644 --- a/test/invalidOriginHub.html +++ b/test/invalidOriginHub.html @@ -5,9 +5,11 @@ From 22de74838ecf82d9b60c6f7a560abb077eb651f4 Mon Sep 17 00:00:00 2001 From: Cyril CHAPON Date: Wed, 10 Oct 2018 10:59:53 +0200 Subject: [PATCH 3/3] Add tests for sessionHub --- test/sessionHub.html | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 test/sessionHub.html diff --git a/test/sessionHub.html b/test/sessionHub.html new file mode 100644 index 0000000..7d825c5 --- /dev/null +++ b/test/sessionHub.html @@ -0,0 +1,15 @@ + + + Cross Storage Hub + + + + +