1 /**
  2  * The Render Engine
  3  * WindowStorage
  4  *
  5  * @fileoverview A storage object where data is maintained on "window.name" that stores data
  6  *               as a JSON object.
  7  *
  8  * @author: Brett Fattori (brettf@renderengine.com)
  9  * @author: $Author: bfattori@gmail.com $
 10  * @version: $Revision: 1567 $
 11  *
 12  * Copyright (c) 2011 Brett Fattori (brettf@renderengine.com)
 13  *
 14  * Permission is hereby granted, free of charge, to any person obtaining a copy
 15  * of this software and associated documentation files (the "Software"), to deal
 16  * in the Software without restriction, including without limitation the rights
 17  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 18  * copies of the Software, and to permit persons to whom the Software is
 19  * furnished to do so, subject to the following conditions:
 20  *
 21  * The above copyright notice and this permission notice shall be included in
 22  * all copies or substantial portions of the Software.
 23  *
 24  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 25  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 26  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 27  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 28  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 29  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 30  * THE SOFTWARE.
 31  *
 32  */
 33 
 34 // The class this file defines and its required classes
 35 R.Engine.define({
 36     "class":"R.storage.WindowStorage",
 37     "requires":[
 38         "R.storage.AbstractStorage"
 39     ]
 40 });
 41 
 42 /**
 43  * @class <tt>R.storage.WindowStorage</tt> is used to maintain data in "window.name"
 44  *    using a JSON object.  This type of storage is transient and should be used as a
 45  *    last resort when trying to store data.
 46  *
 47  * @extends R.storage.AbstractStorage
 48  * @constructor
 49  * @description This class of storage is used to persist data on the window object's <tt>name</tt>
 50  *    attribute.
 51  */
 52 R.storage.WindowStorage = function () {
 53     return R.storage.AbstractStorage.extend(/** @scope R.storage.WindowStorage.prototype */{
 54 
 55         hash:null,
 56 
 57         /** @private */
 58         constructor:function (name, options) {
 59             this.base(name);
 60             this.hash = {};
 61             this.loadData();
 62         },
 63 
 64         destroy:function () {
 65             this.dispose();
 66             this.base();
 67         },
 68 
 69         /**
 70          * Release the object back into the object pool.
 71          */
 72         release:function () {
 73             this.base();
 74             this.hash = null;
 75         },
 76 
 77         /**
 78          * Initialize the storage object to the document.cookie object
 79          * @return {Object} The <tt>localStorage</tt> object
 80          */
 81         initStorageObject:function () {
 82             return window.name;
 83         },
 84 
 85         /**
 86          * Save a value to the window's <tt>name</tt> attribute storage.
 87          * @param key {String} The key to store the data with
 88          * @param value {Object} The value to store with the key
 89          */
 90         save:function (key, value) {
 91             if (!this.enabled) {
 92                 return;
 93             }
 94 
 95             if (typeof key === "object" && !R.isArray(key)) {
 96                 // Set the entire hash
 97                 this.hash = key;
 98             } else {
 99                 this.hash[key] = value;
100             }
101             this.saveData(JSON.stringify(this.hash));
102         },
103 
104         /**
105          * Get the value associated with the key from the window's <tt>name</tt> attribute storage.
106          * @param key {String} The key to retrieve data for
107          * @return {Object} The value that was stored with the key, or <tt>null</tt>
108          */
109         load:function (key) {
110             if (!this.enabled) {
111                 return null;
112             }
113 
114             if (!key) {
115                 return this.hash();
116             }
117             return this.hash[key];
118         },
119 
120         /**
121          * Dispose of all of the data
122          */
123         dispose:function () {
124             if (!this.enabled) {
125                 return;
126             }
127 
128             this.saveData(null);
129         },
130 
131         /**
132          * Clear all of the data
133          */
134         clear:function () {
135             if (!this.enabled) {
136                 return;
137             }
138 
139             this.saveData("{}");
140         },
141 
142         /**
143          * Save the data to the window's <tt>name</tt> attribute.  We don't want to
144          * overwrite what might already be there, so we mark it up.
145          * @param data
146          * @private
147          */
148         saveData:function (data) {
149             if (data != null) {
150                 // First we remove it from window.name
151                 this.loadData();
152                 // Then we reattach it
153                 this.getStorageObject() += "/*TRE_S*/" + data + "/*TRE_E*/";
154             }
155         },
156 
157         /**
158          * Load the data from the window's <tt>name</tt> attribute
159          * @private
160          */
161         loadData:function () {
162             // Find our object
163             var m = /\/\*TRE_S\*\/(\{.*\})\/\*TRE_E\*\//,
164                 res = m.exec(this.getStorageObject());
165 
166             if (res && res[1] != null) {
167                 this.getStorageObject().replace(m, "");
168                 return JSON.parse(res[1]);
169             }
170 
171             return {};
172         }
173 
174     }, /** @scope R.storage.WindowStorage.prototype */ {
175 
176         /**
177          * Get the class name of this object
178          *
179          * @return {String} "R.storage.WindowStorage"
180          */
181         getClassName:function () {
182             return "R.storage.WindowStorage";
183         }
184 
185     });
186 };
187