[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/yuilib/3.17.2/model-sync-local/ -> model-sync-local-debug.js (source)

   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              Y.log("Could not access localStorage.", "warn");
 144          }
 145  
 146          // Pull in existing data from localStorage, if possible.
 147          // Otherwise, see if there's existing data on the local cache.
 148          if (store) {
 149              LocalSync._store[this.root] = store.split('|') || [];
 150  
 151              Y.Array.each(LocalSync._store[this.root], function (id) {
 152                  LocalSync._data[id] = Y.JSON.parse(this.storage.getItem(id));
 153              }, this);
 154          } else {
 155              LocalSync._store[this.root] || (LocalSync._store[this.root] = []);
 156          }
 157      },
 158      
 159      // -- Public Methods -----------------------------------------------------------
 160      
 161      /**
 162      Creates a synchronization layer with the localStorage API, if available.
 163      Otherwise, falls back to a in-memory data store.
 164  
 165      This method is called internally by load(), save(), and destroy().
 166  
 167      @method sync
 168      @param {String} action Sync action to perform. May be one of the following:
 169  
 170        * **create**: Store a newly-created model for the first time.
 171        * **read**  : Load an existing model.
 172        * **update**: Update an existing model.
 173        * **delete**: Delete an existing model.
 174  
 175      @param {Object} [options] Sync options
 176      @param {Function} [callback] Called when the sync operation finishes.
 177        @param {Error|null} callback.err If an error occurred, this parameter will
 178          contain the error. If the sync operation succeeded, _err_ will be
 179          falsey.
 180        @param {Any} [callback.response] The response from our sync. This value will
 181          be passed to the parse() method, which is expected to parse it and
 182          return an attribute hash.
 183      **/
 184      sync: function (action, options, callback) {
 185          options || (options = {});
 186          var response, errorInfo;
 187  
 188          try {
 189              switch (action) {
 190                  case 'read':
 191                      if (this._isYUIModelList) {
 192                          response = this._index(options);
 193                      } else {
 194                          response = this._show(options);
 195                      }
 196                      break;
 197                  case 'create':
 198                      response = this._create(options);
 199                      break;
 200                  case 'update':
 201                      response = this._update(options);
 202                      break;
 203                  case 'delete':
 204                      response = this._destroy(options);
 205                      break;
 206              }
 207          } catch (error) {
 208              errorInfo = error.message;
 209          }
 210  
 211          if (response) {
 212              callback(null, response);
 213          } else if (errorInfo) {
 214              callback(errorInfo);
 215          } else {
 216              callback("Data not found in LocalStorage");
 217          }
 218      },
 219  
 220      /**
 221      Generate a random GUID for our Models. This can be overriden if you have
 222      another method of generating different IDs.
 223      
 224      @method generateID
 225      @protected
 226      @param {String} pre Optional GUID prefix
 227      **/
 228      generateID: function (pre) {
 229          return Y.guid(pre + '_');
 230      },
 231  
 232      // -- Protected Methods ----------------------------------------------------
 233  
 234      /**
 235      Sync method correlating to the "read" operation, for a Model List
 236      
 237      @method _index
 238      @return {Object[]} Array of objects found for that root key
 239      @protected
 240      @since 3.13.0
 241      **/
 242      _index: function () {
 243          var store = LocalSync._store[this.root],
 244              data  = Y.Array.map(store, function (id) {
 245                  return LocalSync._data[id];
 246              });
 247  
 248          return data;
 249      },
 250  
 251      /**
 252      Sync method correlating to the "read" operation, for a Model
 253      
 254      @method _show
 255      @return {Object} Object found for that root key and model ID
 256      @protected
 257      @since 3.13.0
 258      **/
 259      _show: function () {
 260          return LocalSync._data[this.get('id')] || null;
 261      },
 262      
 263      /**
 264      Sync method correlating to the "create" operation
 265      
 266      @method _show
 267      @return {Object} The new object created.
 268      @protected
 269      @since 3.13.0
 270      **/
 271      _create: function () {
 272          var hash  = this.toJSON();
 273  
 274          hash.id = this.generateID(this.root);
 275  
 276          LocalSync._data[hash.id] = hash;
 277          if (this.storage) {
 278              this.storage.setItem(hash.id, Y.JSON.stringify(hash));
 279          }
 280  
 281          LocalSync._store[this.root].push(hash.id);
 282  
 283          this._save();
 284          return hash;
 285      },
 286  
 287      /**
 288      Sync method correlating to the "update" operation
 289  
 290      @method _update
 291      @return {Object} The updated object.
 292      @protected
 293      @since 3.13.0
 294      **/
 295      _update: function () {
 296          var hash = this.toJSON(),
 297              id = this.get('id');
 298  
 299          LocalSync._data[id] = hash;
 300          
 301          if (this.storage) {
 302              this.storage.setItem(id, hash);
 303          }
 304  
 305          if (Y.Array.indexOf(LocalSync._store[this.root], id) === -1) {
 306              LocalSync._store[this.root].push(id);
 307          }
 308  
 309          this._save();
 310  
 311          return hash;
 312      },
 313  
 314      /**
 315      Sync method correlating to the "delete" operation.  Deletes the data
 316      from the in-memory object, and saves into localStorage if available.
 317      
 318      @method _destroy
 319      @protected
 320      @since 3.13.0
 321      **/
 322      _destroy: function () {
 323          var id = this.get('id'),
 324              storage = this.storage;
 325  
 326          if (!LocalSync._data[id]) {
 327              return;
 328          }
 329  
 330          delete LocalSync._data[id];
 331  
 332          if (storage) {
 333              storage.removeItem(id);
 334          }
 335  
 336          LocalSync._store[this.root] = Y.Array.filter(LocalSync._store[this.root], function (item) {
 337              return item.id != id;
 338          });
 339  
 340          this._save();
 341          return this.toJSON();
 342      },
 343      
 344      /**
 345      Saves the current in-memory store into a localStorage key/value pair
 346      if localStorage is available; otherwise, does nothing.
 347      
 348      @method _save
 349      @protected
 350      @since 3.13.0
 351      **/
 352      _save: function () {
 353          if (LocalSync._hasLocalStorage && this.storage) {
 354              this.storage.setItem(
 355                  this.root,
 356                  LocalSync._store[this.root].join('|')
 357              );
 358          }
 359      }
 360  };
 361  
 362  // -- Namespace ---------------------------------------------------------------
 363  
 364  Y.namespace('ModelSync').Local = LocalSync;
 365  
 366  
 367  }, '3.17.2', {"requires": ["model", "json-stringify"]});


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1