text: // Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
  // Use of this source code is governed by a BSD-style license that can be
  // found in the LICENSE file.
  
  'use strict';
  
  /**
   * chrome.storage based class with an async interface that is interchangeable
   * with other lib.Storage.* implementations.
   */
  lib.Storage.Chrome = function(storage) {
    this.storage_ = storage;
    this.observers_ = [];
  
    chrome.storage.onChanged.addListener(this.onChanged_.bind(this));
  };
  
  /**
   * Called by the storage implementation when the storage is modified.
   */
  lib.Storage.Chrome.prototype.onChanged_ = function(changes, areaname) {
    if (chrome.storage[areaname] != this.storage_)
      return;
  
    for (var i = 0; i < this.observers_.length; i++) {
      this.observers_[i](changes);
    }
  };
  
  /**
   * Register a function to observe storage changes.
   *
   * @param {function(map)} callback The function to invoke when the storage
   *     changes.
   */
  lib.Storage.Chrome.prototype.addObserver = function(callback) {
    this.observers_.push(callback);
  };
  
  /**
   * Unregister a change observer.
   *
   * @param {function} observer A previously registered callback.
   */
  lib.Storage.Chrome.prototype.removeObserver = function(callback) {
    var i = this.observers_.indexOf(callback);
    if (i != -1)
      this.observers_.splice(i, 1);
  };
  
  /**
   * Delete everything in this storage.
   *
   * @param {function(map)} callback The function to invoke when the delete
   *     has completed.
   */
  lib.Storage.Chrome.prototype.clear = function(opt_callback) {
    this.storage_.clear();
  
    if (opt_callback)
      setTimeout(opt_callback, 0);
  };
  
  /**
   * Return the current value of a storage item.
   *
   * @param {string} key The key to look up.
   * @param {function(value) callback The function to invoke when the value has
   *     been retrieved.
   */
  lib.Storage.Chrome.prototype.getItem = function(key, callback) {
    this.storage_.get(key, callback);
  };
  /**
   * Fetch the values of multiple storage items.
   *
   * @param {Array} keys The keys to look up.
   * @param {function(map) callback The function to invoke when the values have
   *     been retrieved.
   */
  
  lib.Storage.Chrome.prototype.getItems = function(keys, callback) {
    this.storage_.get(keys, callback);
  };
  
  /**
   * Set a value in storage.
   *
   * @param {string} key The key for the value to be stored.
   * @param {*} value The value to be stored.  Anything that can be serialized
   *     with JSON is acceptable.
   * @param {function()} opt_callback Optional function to invoke when the
   *     set is complete.  You don't have to wait for the set to complete in order
   *     to read the value, since the local cache is updated synchronously.
   */
  lib.Storage.Chrome.prototype.setItem = function(key, value, opt_callback) {
    var obj = {};
    obj[key] = value;
    this.storage_.set(obj, opt_callback);
  };
  
  /**
   * Set multiple values in storage.
   *
   * @param {Object} map A map of key/values to set in storage.
   * @param {function()} opt_callback Optional function to invoke when the
   *     set is complete.  You don't have to wait for the set to complete in order
   *     to read the value, since the local cache is updated synchronously.
   */
  lib.Storage.Chrome.prototype.setItems = function(obj, opt_callback) {
    this.storage_.set(obj, opt_callback);
  };
  
  /**
   * Remove an item from storage.
   *
   * @param {string} key The key to be removed.
   * @param {function()} opt_callback Optional function to invoke when the
   *     remove is complete.  You don't have to wait for the set to complete in
   *     order to read the value, since the local cache is updated synchronously.
   */
  lib.Storage.Chrome.prototype.removeItem = function(key, opt_callback) {
    this.storage_.remove(key, opt_callback);
  };
  
  /**
   * Remove multiple items from storage.
   *
   * @param {Array} keys The keys to be removed.
   * @param {function()} opt_callback Optional function to invoke when the
   *     remove is complete.  You don't have to wait for the set to complete in
   *     order to read the value, since the local cache is updated synchronously.
   */
  lib.Storage.Chrome.prototype.removeItems = function(keys, opt_callback) {
    this.storage_.remove(keys, opt_callback);
  };
  