1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
6 * @fileoverview Implementation of ScreenContext class: key-value storage for
7 * values that are shared between C++ and JS sides.
9 cr.define('login', function() {
12 function require(condition, message) {
18 function checkKeyIsValid(key) {
19 var keyType = typeof key;
20 require(keyType === 'string', 'Invalid type of key: "' + keyType + '".');
23 function checkValueIsValid(value) {
24 var valueType = typeof value;
25 require((['string', 'boolean', 'number'].indexOf(valueType) != -1 ||
26 Array.isArray(value)),
27 'Invalid type of value: "' + valueType + '".');
30 function ScreenContext() {
36 ScreenContext.prototype = {
38 * Returns stored value for |key| or |defaultValue| if key not found in
39 * storage. Throws Error if key not found and |defaultValue| omitted.
41 get: function(key, defaultValue) {
43 if (this.hasKey(key)) {
44 return this.storage_[key];
45 } else if (typeof defaultValue !== 'undefined') {
48 throw Error('Key "' + key + '" not found.');
53 * Sets |value| for |key|. Returns true if call changes state of context,
56 set: function(key, value) {
58 checkValueIsValid(value);
59 if (this.hasKey(key) && this.storage_[key] === value)
61 this.changes_[key] = value;
62 this.storage_[key] = value;
66 hasKey: function(key) {
68 return this.storage_.hasOwnProperty(key);
71 hasChanges: function() {
72 return Object.keys(this.changes_).length > 0;
76 * Applies |changes| to context. Returns Array of changed keys' names.
78 applyChanges: function(changes) {
79 require(!this.hasChanges(), 'Context has changes.');
81 for (var key in changes) {
83 checkValueIsValid(changes[key]);
84 oldValues[key] = this.storage_[key];
85 this.storage_[key] = changes[key];
87 var observers = this.cloneObservers_();
88 for (var key in changes) {
89 if (observers.hasOwnProperty(key)) {
90 var keyObservers = observers[key];
91 for (var observerIndex in keyObservers)
92 keyObservers[observerIndex](changes[key], oldValues[key], key);
95 return Object.keys(changes);
99 * Returns changes made on context since previous call.
101 getChangesAndReset: function() {
102 var result = this.changes_;
107 addObserver: function(key, observer) {
108 if (!this.observers_.hasOwnProperty(key))
109 this.observers_[key] = [];
110 if (this.observers_[key].indexOf(observer) !== -1) {
111 console.warn('Observer already registered.');
114 this.observers_[key].push(observer);
117 removeObserver: function(observer) {
118 for (var key in this.observers_) {
119 var observerIndex = this.observers_[key].indexOf(observer);
120 if (observerIndex != -1)
121 this.observers_[key].splice(observerIndex, 1);
126 * Creates deep copy of observers lists.
129 cloneObservers_: function() {
131 for (var key in this.observers_)
132 result[key] = this.observers_[key].slice();
138 ScreenContext: ScreenContext