1 /** 2 * The Render Engine 3 * CookieStorage 4 * 5 * @fileoverview A storage object where data is maintained in a cookie 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.CookieStorage", 37 "requires":[ 38 "R.storage.AbstractStorage" 39 ] 40 }); 41 42 /** 43 * @class <tt>R.storage.CookieStorage</tt> is used to maintain data in a 44 * cookie using a JSON object. If cookies are not supported, the methods 45 * will have no effect. 46 * 47 * @param name {String} The name of the cookie 48 * @param options {Object} An object which contains any of the following: path, domain, secure (boolean), 49 * and expires (number). Any of the values can be left off, in which case defaults will be used. 50 * @extends R.storage.AbstractStorage 51 * @constructor 52 * @description This class of storage is used to persist data in a cookie. 53 */ 54 R.storage.CookieStorage = function () { 55 return R.storage.AbstractStorage.extend(/** @scope R.storage.CookieStorage.prototype */{ 56 57 enabled:null, 58 cookieName:null, 59 options:null, 60 hash:null, 61 62 /** @private */ 63 constructor:function (name, options) { 64 this.enabled = R.engine.Support.sysInfo().support.storage.cookie; 65 AssertWarn(this.enabled, "CookieStorage is not supported by browser - DISABLED"); 66 this.base(name); 67 this.cookieName = name; 68 this.options = $.extend({ 69 path:"/", 70 domain:null, 71 secure:null, 72 expires:null 73 }, options); 74 this.hash = this.loadData() || {}; 75 }, 76 77 destroy:function () { 78 this.dispose(); 79 this.base(); 80 }, 81 82 /** 83 * Release the object back into the object pool. 84 */ 85 release:function () { 86 this.base(); 87 this.cookieName = null; 88 this.options = null; 89 this.hash = null; 90 }, 91 92 /** 93 * Initialize the storage object to the document.cookie object 94 * @return {Object} The <tt>localStorage</tt> object 95 */ 96 initStorageObject:function () { 97 return window.document.cookie; 98 }, 99 100 /** 101 * Save a value to cookie storage. 102 * @param key {String} The key to store the data with 103 * @param value {Object} The value to store with the key 104 */ 105 save:function (key, value) { 106 if (!this.enabled) { 107 return; 108 } 109 110 if (typeof key === "object" && !R.isArray(key)) { 111 // Set the entire hash 112 this.hash = key; 113 } else { 114 this.hash[key] = value; 115 } 116 this.saveData(JSON.stringify(this.hash)); 117 }, 118 119 /** 120 * Get the value associated with the key from cookie storage. 121 * @param key {String} The key to retrieve data for 122 * @return {Object} The value that was stored with the key, or <tt>null</tt> 123 */ 124 load:function (key) { 125 if (!this.enabled) { 126 return null; 127 } 128 129 if (!key) { 130 return this.hash(); 131 } 132 return this.hash[key]; 133 }, 134 135 /** 136 * Dispose of the cookie (remove it from the user's browser). 137 */ 138 dispose:function () { 139 if (!this.enabled) { 140 return; 141 } 142 143 var oldExpires = this.options.expires; 144 $.extend(this.options, { 145 expires:-1 146 }); 147 this.saveData(""); 148 $.extend(this.options, { 149 expires:oldExpires 150 }); 151 }, 152 153 /** 154 * Clear all of the data stored in the cookie. 155 */ 156 clear:function () { 157 if (!this.enabled) { 158 return; 159 } 160 161 this.saveData("{}"); 162 }, 163 164 /** 165 * Saves the data object into the cookie. 166 * @param data 167 * @private 168 */ 169 saveData:function (data) { 170 AssertWarn(data.length < R.engine.Support.sysInfo().support.storage.cookie.maxLength, 171 "Data to save to cookie is larger than supported size - will be truncated"); 172 173 var p = ""; 174 $.each(this.options, function (k, v) { 175 if (v) { 176 p += (p.length > 0 ? ";" : "") + k + (function (o) { 177 switch (o) { 178 case "secure": 179 return ""; 180 case "expires": 181 return "=" + new Date(R.now() + v).toGMTString(); 182 default: 183 return "=" + v; 184 } 185 })(k); 186 } 187 }); 188 189 // Save the cookie 190 this.getStorageObject() = this.cookieName + "=" + data + ";" + p; 191 }, 192 193 /** 194 * Loads the data object from the cookie 195 * @private 196 */ 197 loadData:function () { 198 if (!this.enabled) { 199 return null; 200 } 201 202 var va = this.getStorageObject().match('(?:^|;)\\s*' + this.cookieName + '=([^;]*)'); 203 var value = (va) ? va[1] : null; 204 return JSON.parse(value); 205 } 206 207 }, /** @scope R.storage.CookieStorage.prototype */ { 208 209 /** 210 * Get the class name of this object 211 * 212 * @return {String} "R.storage.CookieStorage" 213 */ 214 getClassName:function () { 215 return "R.storage.CookieStorage"; 216 } 217 218 }); 219 }; 220