[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
1 /* 2 YUI 3.17.2 (build 9c3c78e) 3 Copyright 2014 Yahoo! Inc. All rights reserved. 4 Licensed under the BSD License. 5 http://yuilibrary.com/license/ 6 */ 7 8 YUI.add('model-sync-local', function (Y, NAME) { 9 10 /* 11 An extension which provides a sync implementation through locally stored 12 key value pairs, either through the HTML localStorage API or falling back 13 onto an in-memory cache, that can be mixed into a Model or ModelList subclass. 14 15 @module app 16 @submodule model-sync-local 17 @since 3.13.0 18 **/ 19 20 /** 21 An extension which provides a sync implementation through locally stored 22 key value pairs, either through the HTML localStorage API or falling back 23 onto an in-memory cache, that can be mixed into a Model or ModelList subclass. 24 25 A group of Models/ModelLists is serialized in localStorage by either its 26 class name, or a specified 'root' that is provided. 27 28 var User = Y.Base.create('user', Y.Model, [Y.ModelSync.Local], { 29 root: 'user' 30 }); 31 32 var Users = Y.Base.create('users', Y.ModelList, [Y.ModelSync.Local], { 33 model: User, 34 }); 35 36 @class ModelSync.Local 37 @extensionfor Model 38 @extensionfor ModelList 39 @since 3.13.0 40 **/ 41 function LocalSync() {} 42 43 /** 44 Properties that shouldn't be turned into ad-hoc attributes when passed to a 45 Model or ModelList constructor. 46 47 @property _NON_ATTRS_CFG 48 @type Array 49 @default ['root'] 50 @static 51 @protected 52 @since 3.13.0 53 **/ 54 LocalSync._NON_ATTRS_CFG = ['root']; 55 56 /** 57 Feature testing for `localStorage` availability. 58 Will return falsey for browsers with `localStorage`, but that don't 59 actually work, such as iOS Safari in private browsing mode. 60 61 @property _hasLocalStorage 62 @type Boolean 63 @private 64 **/ 65 LocalSync._hasLocalStorage = (function () { 66 var LS = Y.config.win.localStorage, 67 test = Y.guid(); 68 69 try { 70 LS.setItem(test, test); 71 LS.removeItem(test); 72 return true; 73 } catch (e) { 74 return false; 75 } 76 })(), 77 78 /** 79 Object of key/value pairs to fall back on when localStorage is not available. 80 81 @property _data 82 @type Object 83 @private 84 **/ 85 86 LocalSync._data = LocalSync._data || {}; 87 88 /** 89 Cache to quickly access a specific object with a given ID. 90 91 @property _store 92 @type Array 93 @private 94 **/ 95 96 LocalSync._store = LocalSync._store || {}; 97 98 LocalSync.prototype = { 99 100 // -- Public Methods ------------------------------------------------------- 101 102 /** 103 Root used as the key inside of localStorage and/or the in-memory store. 104 105 @property root 106 @type String 107 @default "" 108 @since 3.13.0 109 **/ 110 root: '', 111 112 /** 113 Shortcut for access to localStorage. 114 115 @property storage 116 @type Storage 117 @default null 118 @since 3.13.0 119 **/ 120 storage: null, 121 122 // -- Lifecycle Methods ----------------------------------------------------- 123 initializer: function (config) { 124 var store, data; 125 126 config || (config = {}); 127 128 if ('root' in config) { 129 this.root = config.root || ''; 130 } 131 132 // This is checking to see if the sync layer is being applied to 133 // a ModelList, and if so, is looking for a `root` property on its 134 // Model's prototype instead. 135 if (!this.root && this.model && this.model.prototype.root) { 136 this.root = this.model.prototype.root; 137 } 138 139 if (LocalSync._hasLocalStorage) { 140 this.storage = Y.config.win.localStorage; 141 store = this.storage.getItem(this.root); 142 } else { 143 } 144 145 // Pull in existing data from localStorage, if possible. 146 // Otherwise, see if there's existing data on the local cache. 147 if (store) { 148 LocalSync._store[this.root] = store.split('|') || []; 149 150 Y.Array.each(LocalSync._store[this.root], function (id) { 151 LocalSync._data[id] = Y.JSON.parse(this.storage.getItem(id)); 152 }, this); 153 } else { 154 LocalSync._store[this.root] || (LocalSync._store[this.root] = []); 155 } 156 }, 157 158 // -- Public Methods ----------------------------------------------------------- 159 160 /** 161 Creates a synchronization layer with the localStorage API, if available. 162 Otherwise, falls back to a in-memory data store. 163 164 This method is called internally by load(), save(), and destroy(). 165 166 @method sync 167 @param {String} action Sync action to perform. May be one of the following: 168 169 * **create**: Store a newly-created model for the first time. 170 * **read** : Load an existing model. 171 * **update**: Update an existing model. 172 * **delete**: Delete an existing model. 173 174 @param {Object} [options] Sync options 175 @param {Function} [callback] Called when the sync operation finishes. 176 @param {Error|null} callback.err If an error occurred, this parameter will 177 contain the error. If the sync operation succeeded, _err_ will be 178 falsey. 179 @param {Any} [callback.response] The response from our sync. This value will 180 be passed to the parse() method, which is expected to parse it and 181 return an attribute hash. 182 **/ 183 sync: function (action, options, callback) { 184 options || (options = {}); 185 var response, errorInfo; 186 187 try { 188 switch (action) { 189 case 'read': 190 if (this._isYUIModelList) { 191 response = this._index(options); 192 } else { 193 response = this._show(options); 194 } 195 break; 196 case 'create': 197 response = this._create(options); 198 break; 199 case 'update': 200 response = this._update(options); 201 break; 202 case 'delete': 203 response = this._destroy(options); 204 break; 205 } 206 } catch (error) { 207 errorInfo = error.message; 208 } 209 210 if (response) { 211 callback(null, response); 212 } else if (errorInfo) { 213 callback(errorInfo); 214 } else { 215 callback("Data not found in LocalStorage"); 216 } 217 }, 218 219 /** 220 Generate a random GUID for our Models. This can be overriden if you have 221 another method of generating different IDs. 222 223 @method generateID 224 @protected 225 @param {String} pre Optional GUID prefix 226 **/ 227 generateID: function (pre) { 228 return Y.guid(pre + '_'); 229 }, 230 231 // -- Protected Methods ---------------------------------------------------- 232 233 /** 234 Sync method correlating to the "read" operation, for a Model List 235 236 @method _index 237 @return {Object[]} Array of objects found for that root key 238 @protected 239 @since 3.13.0 240 **/ 241 _index: function () { 242 var store = LocalSync._store[this.root], 243 data = Y.Array.map(store, function (id) { 244 return LocalSync._data[id]; 245 }); 246 247 return data; 248 }, 249 250 /** 251 Sync method correlating to the "read" operation, for a Model 252 253 @method _show 254 @return {Object} Object found for that root key and model ID 255 @protected 256 @since 3.13.0 257 **/ 258 _show: function () { 259 return LocalSync._data[this.get('id')] || null; 260 }, 261 262 /** 263 Sync method correlating to the "create" operation 264 265 @method _show 266 @return {Object} The new object created. 267 @protected 268 @since 3.13.0 269 **/ 270 _create: function () { 271 var hash = this.toJSON(); 272 273 hash.id = this.generateID(this.root); 274 275 LocalSync._data[hash.id] = hash; 276 if (this.storage) { 277 this.storage.setItem(hash.id, Y.JSON.stringify(hash)); 278 } 279 280 LocalSync._store[this.root].push(hash.id); 281 282 this._save(); 283 return hash; 284 }, 285 286 /** 287 Sync method correlating to the "update" operation 288 289 @method _update 290 @return {Object} The updated object. 291 @protected 292 @since 3.13.0 293 **/ 294 _update: function () { 295 var hash = this.toJSON(), 296 id = this.get('id'); 297 298 LocalSync._data[id] = hash; 299 300 if (this.storage) { 301 this.storage.setItem(id, hash); 302 } 303 304 if (Y.Array.indexOf(LocalSync._store[this.root], id) === -1) { 305 LocalSync._store[this.root].push(id); 306 } 307 308 this._save(); 309 310 return hash; 311 }, 312 313 /** 314 Sync method correlating to the "delete" operation. Deletes the data 315 from the in-memory object, and saves into localStorage if available. 316 317 @method _destroy 318 @protected 319 @since 3.13.0 320 **/ 321 _destroy: function () { 322 var id = this.get('id'), 323 storage = this.storage; 324 325 if (!LocalSync._data[id]) { 326 return; 327 } 328 329 delete LocalSync._data[id]; 330 331 if (storage) { 332 storage.removeItem(id); 333 } 334 335 LocalSync._store[this.root] = Y.Array.filter(LocalSync._store[this.root], function (item) { 336 return item.id != id; 337 }); 338 339 this._save(); 340 return this.toJSON(); 341 }, 342 343 /** 344 Saves the current in-memory store into a localStorage key/value pair 345 if localStorage is available; otherwise, does nothing. 346 347 @method _save 348 @protected 349 @since 3.13.0 350 **/ 351 _save: function () { 352 if (LocalSync._hasLocalStorage && this.storage) { 353 this.storage.setItem( 354 this.root, 355 LocalSync._store[this.root].join('|') 356 ); 357 } 358 } 359 }; 360 361 // -- Namespace --------------------------------------------------------------- 362 363 Y.namespace('ModelSync').Local = LocalSync; 364 365 366 }, '3.17.2', {"requires": ["model", "json-stringify"]});
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |