[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/yuilib/3.17.2/model-sync-local/ -> model-sync-local.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          }
 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"]});


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