In this document client storage approach is described in detail.
- Application developers must be able to store information on browser level.
- Application developers must be able to store sensitive data in a secure way.
- Application developers must be able to share data across multiple pages.
- Application developers must be able to clear the storage on demand.
- Application developers must be able to persist the storage on demand.
- Application developers must be able to intercept the storage events.
- ClientStorage must guarantee that private storage is isolated and can not be overriden by other components.
Two or more pages might need to change data between them. Imagine a wizard or a checkout process. Many frameworks achieve this goal using a server side storage (usually session). Of course it’s also possible to pass the parameters between pages using GET / POST requests. This becomes annoying when you manually change the url (in GET case) or you do a refresh (POST).
In RAIN we want to provide a lightweight solution to this problem (HTML5 storage / dojo storage).
One solution for this is that a set of pages to share a region of session. The reason for this is that in the end we expect the shared region to be cleared.
Same problem as linked pages.
Imagine the “Compose email” page from gmail. You might spend a lot of time on that page. While you type and create a very nice email your internet connection fails. If the content was not previously saved in a storage and you get temporary unavailable you would have lost your work.
In RAIN we’ll provide a local storage mechanism that allows you to save the state of your application. In addition we can provide helper methods that provide auto save mechanism for instance.
Imagine you have a page in which you display user information (into a div). Next to it you display the shopping cart content (in another div with title attribute = to user name). In addition you also have another section in which you display ordering history (in a separate div where you also display user name). In this scenario in the first div you can change user name.
We must be able to propagate user name change in all places where it appears in the page.
Imagine the scenario presented above except shopping cart is presented into a new window.
We want user name changed within a window to be propagated to other windows as well. amplify.request
The storage that keep the user name value should provide a notification mechanism. It will use listeners for this goal.
From the use cases presented above result two major storage mechanism:
- a persistent storage
- a transient storage
Each storage must provide the following partitions:
- a private / dedicated partition - a shared scope for a limited number of pages / objects.
- a global partition - a global scope accessible by everyone.
As you can see in the above diagram the concepts described in this document are abstracted into an API. Our goal is that underline this API HTML 5 localStorage and sessionStorage objects are used transparently.
For having access to a private storage or to be able to create a new private storage a client side controller must provide the view context under which is running.
As you can see in the above diagram the global storage from ClientRuntime is designed to be hierarchical. Most of the time applications will use dedicated storage on which they operate. Of course they can also use global storage if they want.
1 2 3 4 5 6 7 8 9 | <script type="text/javascript">
/**
Wizard create user - page1.html
**/
var clientRuntime = new ClientRuntime();
var clientStorage = clientRuntime.storage.createPrivateStorage("wizardUser", true);
clientStorage.setValue("username", "radu");
clientStorage.setValue("password", "mydummypassword");
|
1 2 3 4 5 6 7 8 | <script type="text/javascript">
/**
Wizard create user - page2.html
**/
var clientRuntime = new ClientRuntime();
var clientStorage = clientRuntime.storage.getPrivateStorage("wizardUser", true);
alert(clientStorage.getValue("username"));
|
This code will work perfectly also for persistent storage.
1 2 3 4 5 6 7 8 9 10 11 | <script type="text/javascript">
/**
Page view user info - user_view.html
**/
var clientRuntime = new ClientRuntime();
var clientStorage = clientRuntime.storage.getPrivateStorage("userinfo", false);
clientStorage.addListener(function(evt) {
if(evt.key == "username") {
$("#username") = evt.newvalue;
}
});
|
1 2 3 4 5 6 7 | <script type="text/javascript">
/**
Page customize user info - user_edit.html
**/
var clientRuntime = new ClientRuntime();
var clientStorage = clientRuntime.storage.getPrivateStorage("userinfo", false);
clientStorage.setValue("username", "Radu Cosnita"); // this triggers listener registered in user_view.html page.
|
- The above mentioned limitation applies also to listeners.
The intention is to provide a proof of concept for this feature as soon as possible. Before we decide on this there are some frameworks that guarantee graceful degrade in case storage is not supported by browsers. Below you can find a list of such frameworks:
- Amplifyjs - http://amplifyjs.com/api/store/
- Dojo storage - http://google-opensource.blogspot.com/2008/03/dojo-storage.html - I think this will bring an overhead (we already use jQuery).
An alternative to the frameworks mentioned about would be to simply assume all browsers that access RAIN specific applications have HTML 5 support and we do not provide gracefully degrading support.