app_state.js revision 5c02ac1a9c1b504631c0a3d2b6e737b5d738bae1
1// Copyright (c) 2012 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.
4
5cr.define('print_preview', function() {
6  'use strict';
7
8  /**
9   * Object used to get and persist the print preview application state.
10   * @constructor
11   */
12  function AppState() {
13    /**
14     * Internal representation of application state.
15     * @type {Object.<string: Object>}
16     * @private
17     */
18    this.state_ = {};
19    this.state_[AppState.Field.VERSION] = AppState.VERSION_;
20    this.state_[AppState.Field.IS_GCP_PROMO_DISMISSED] = true;
21
22    /**
23     * Whether the app state has been initialized. The app state will ignore all
24     * writes until it has been initialized.
25     * @type {boolean}
26     * @private
27     */
28    this.isInitialized_ = false;
29  };
30
31  /**
32   * Enumeration of field names for serialized app state.
33   * @enum {string}
34   */
35  AppState.Field = {
36    VERSION: 'version',
37    SELECTED_DESTINATION_ID: 'selectedDestinationId',
38    SELECTED_DESTINATION_ACCOUNT: 'selectedDestinationAccount',
39    SELECTED_DESTINATION_ORIGIN: 'selectedDestinationOrigin',
40    SELECTED_DESTINATION_CAPABILITIES: 'selectedDestinationCapabilities',
41    SELECTED_DESTINATION_NAME: 'selectedDestinationName',
42    IS_GCP_PROMO_DISMISSED: 'isGcpPromoDismissed',
43    MEDIA_SIZE: 'mediaSize',
44    MARGINS_TYPE: 'marginsType',
45    CUSTOM_MARGINS: 'customMargins',
46    IS_COLOR_ENABLED: 'isColorEnabled',
47    IS_DUPLEX_ENABLED: 'isDuplexEnabled',
48    IS_HEADER_FOOTER_ENABLED: 'isHeaderFooterEnabled',
49    IS_LANDSCAPE_ENABLED: 'isLandscapeEnabled',
50    IS_COLLATE_ENABLED: 'isCollateEnabled',
51    IS_CSS_BACKGROUND_ENABLED: 'isCssBackgroundEnabled'
52  };
53
54  /**
55   * Current version of the app state. This value helps to understand how to
56   * parse earlier versions of the app state.
57   * @type {number}
58   * @const
59   * @private
60   */
61  AppState.VERSION_ = 2;
62
63  /**
64   * Name of C++ layer function to persist app state.
65   * @type {string}
66   * @const
67   * @private
68   */
69  AppState.NATIVE_FUNCTION_NAME_ = 'saveAppState';
70
71  AppState.prototype = {
72    /** @return {?string} ID of the selected destination. */
73    get selectedDestinationId() {
74      return this.state_[AppState.Field.SELECTED_DESTINATION_ID];
75    },
76
77    /** @return {?string} Account the selected destination is registered for. */
78    get selectedDestinationAccount() {
79      return this.state_[AppState.Field.SELECTED_DESTINATION_ACCOUNT];
80    },
81
82    /** @return {?string} Origin of the selected destination. */
83    get selectedDestinationOrigin() {
84      return this.state_[AppState.Field.SELECTED_DESTINATION_ORIGIN];
85    },
86
87    /** @return {?print_preview.Cdd} CDD of the selected destination. */
88    get selectedDestinationCapabilities() {
89      return this.state_[AppState.Field.SELECTED_DESTINATION_CAPABILITIES];
90    },
91
92    /** @return {?string} Name of the selected destination. */
93    get selectedDestinationName() {
94      return this.state_[AppState.Field.SELECTED_DESTINATION_NAME];
95    },
96
97    /** @return {boolean} Whether the GCP promotion has been dismissed. */
98    get isGcpPromoDismissed() {
99      return this.state_[AppState.Field.IS_GCP_PROMO_DISMISSED];
100    },
101
102    /**
103     * @param {!print_preview.AppState.Field} field App state field to check if
104     *     set.
105     * @return {boolean} Whether a field has been set in the app state.
106     */
107    hasField: function(field) {
108      return this.state_.hasOwnProperty(field);
109    },
110
111    /**
112     * @param {!print_preview.AppState.Field} field App state field to get.
113     * @return {Object} Value of the app state field.
114     */
115    getField: function(field) {
116      if (field == AppState.Field.CUSTOM_MARGINS) {
117        return this.state_[field] ?
118            print_preview.Margins.parse(this.state_[field]) : null;
119      } else {
120        return this.state_[field];
121      }
122    },
123
124    /**
125     * Initializes the app state from a serialized string returned by the native
126     * layer.
127     * @param {?string} serializedAppStateStr Serialized string representation
128     *     of the app state.
129     * @param {?string} systemDefaultDestinationId ID of the system default
130     *     destination.
131     */
132    init: function(serializedAppStateStr, systemDefaultDestinationId) {
133      if (serializedAppStateStr) {
134        var state = JSON.parse(serializedAppStateStr);
135        if (state[AppState.Field.VERSION] == AppState.VERSION_) {
136          this.state_ = state;
137        }
138      } else {
139        // Set some state defaults.
140        this.state_[AppState.Field.IS_GCP_PROMO_DISMISSED] = false;
141      }
142      // Default to system destination, if no destination was selected.
143      if (!this.state_[AppState.Field.SELECTED_DESTINATION_ID] ||
144          !this.state_[AppState.Field.SELECTED_DESTINATION_ORIGIN]) {
145        if (systemDefaultDestinationId) {
146          this.state_[AppState.Field.SELECTED_DESTINATION_ID] =
147              systemDefaultDestinationId;
148          this.state_[AppState.Field.SELECTED_DESTINATION_ORIGIN] =
149              print_preview.Destination.Origin.LOCAL;
150        }
151      }
152    },
153
154    /**
155     * Sets to initialized state. Now object will accept persist requests.
156     */
157    setInitialized: function() {
158      this.isInitialized_ = true;
159    },
160
161    /**
162     * Persists the given value for the given field.
163     * @param {!print_preview.AppState.Field} field Field to persist.
164     * @param {Object} value Value of field to persist.
165     */
166    persistField: function(field, value) {
167      if (!this.isInitialized_)
168        return;
169      if (field == AppState.Field.CUSTOM_MARGINS) {
170        this.state_[field] = value ? value.serialize() : null;
171      } else {
172        this.state_[field] = value;
173      }
174      this.persist_();
175    },
176
177    /**
178     * Persists the selected destination.
179     * @param {!print_preview.Destination} dest Destination to persist.
180     */
181    persistSelectedDestination: function(dest) {
182      if (!this.isInitialized_)
183        return;
184      this.state_[AppState.Field.SELECTED_DESTINATION_ID] = dest.id;
185      this.state_[AppState.Field.SELECTED_DESTINATION_ACCOUNT] = dest.account;
186      this.state_[AppState.Field.SELECTED_DESTINATION_ORIGIN] = dest.origin;
187      this.state_[AppState.Field.SELECTED_DESTINATION_CAPABILITIES] =
188          dest.capabilities;
189      this.state_[AppState.Field.SELECTED_DESTINATION_NAME] = dest.displayName;
190      this.persist_();
191    },
192
193    /**
194     * Persists whether the GCP promotion has been dismissed.
195     * @param {boolean} isGcpPromoDismissed Whether the GCP promotion has been
196     *     dismissed.
197     */
198    persistIsGcpPromoDismissed: function(isGcpPromoDismissed) {
199      if (!this.isInitialized_)
200        return;
201      this.state_[AppState.Field.IS_GCP_PROMO_DISMISSED] = isGcpPromoDismissed;
202      this.persist_();
203    },
204
205    /**
206     * Calls into the native layer to persist the application state.
207     * @private
208     */
209    persist_: function() {
210      chrome.send(AppState.NATIVE_FUNCTION_NAME_,
211                  [JSON.stringify(this.state_)]);
212    }
213  };
214
215  return {
216    AppState: AppState
217  };
218});
219