summaryrefslogtreecommitdiff
path: root/chromium/chrome/browser/resources/chromeos/login/screen_context.js
blob: 6a014a4828365e61576db7ad3f07c5982af7ed6c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

/**
 * @fileoverview Implementation of ScreenContext class: key-value storage for
 * values that are shared between C++ and JS sides.
 */
cr.define('login', function() {
  function require(condition, message) {
    if (!condition) {
      throw Error(message);
    }
  }

  function checkKeyIsValid(key) {
    var keyType = typeof key;
    require(keyType === 'string', 'Invalid type of key: "' + keyType + '".');
  }

  function checkValueIsValid(value) {
    var valueType = typeof value;
    require(['string', 'boolean', 'number'].indexOf(valueType) != -1,
        'Invalid type of value: "' + valueType + '".');
  }

  function ScreenContext() {
    this.storage_ = {};
    this.changes_ = {};
  }

  ScreenContext.prototype = {
    /**
     * Returns stored value for |key| or |defaultValue| if key not found in
     * storage. Throws Error if key not found and |defaultValue| omitted.
     */
    get: function(key, defaultValue) {
      checkKeyIsValid(key);
      if (this.hasKey(key)) {
        return this.storage_[key];
      } else if (typeof defaultValue !== 'undefined') {
        return defaultValue;
      } else {
        throw Error('Key "' + key + '" not found.');
      }
    },

    /**
     * Sets |value| for |key|. Returns true if call changes state of context,
     * false otherwise.
     */
    set: function(key, value) {
      checkKeyIsValid(key);
      checkValueIsValid(value);
      if (this.hasKey(key) && this.storage_[key] === value)
        return false;
      this.changes_[key] = value;
      this.storage_[key] = value;
      return true;
    },

    hasKey: function(key) {
      checkKeyIsValid(key);
      return this.storage_.hasOwnProperty(key);
    },

    hasChanges: function() {
      return Object.keys(this.changes_).length > 0;
    },

    /**
     * Applies |changes| to context. Returns Array of changed keys' names.
     */
    applyChanges: function(changes) {
      require(!this.hasChanges(), 'Context has changes.');
      Object.keys(changes).forEach(function(key) {
        checkKeyIsValid(key);
        checkValueIsValid(changes[key]);
        this.storage_[key] = changes[key];
      }, this);
      return Object.keys(changes);
    },

    /**
     * Returns changes made on context since previous call.
     */
    getChangesAndReset: function() {
      var result = this.changes_;
      this.changes_ = {};
      return result;
    }
  };

  return {
    ScreenContext: ScreenContext
  };
});