Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(98)

Side by Side Diff: chrome/browser/resources/print_preview/data/app_state.js

Issue 2346153002: Save most recent 3 destinations across multiple sessions (Closed)
Patch Set: Fix readability and extra checks Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 cr.define('print_preview', function() { 5 cr.define('print_preview', function() {
6 'use strict'; 6 'use strict';
7 7
8 /** 8 /**
9 * Object used to get and persist the print preview application state. 9 * Object used to get and persist the print preview application state.
10 * @constructor 10 * @constructor
(...skipping 11 matching lines...) Expand all
22 /** 22 /**
23 * Whether the app state has been initialized. The app state will ignore all 23 * Whether the app state has been initialized. The app state will ignore all
24 * writes until it has been initialized. 24 * writes until it has been initialized.
25 * @type {boolean} 25 * @type {boolean}
26 * @private 26 * @private
27 */ 27 */
28 this.isInitialized_ = false; 28 this.isInitialized_ = false;
29 }; 29 };
30 30
31 /** 31 /**
32 * Number of recent print destinations to store across browser sessions.
33 * @const {number}
34 */
35 AppState.NUM_DESTINATIONS_ = 3;
36
37
38 /**
32 * Enumeration of field names for serialized app state. 39 * Enumeration of field names for serialized app state.
33 * @enum {string} 40 * @enum {string}
34 */ 41 */
35 AppState.Field = { 42 AppState.Field = {
36 VERSION: 'version', 43 VERSION: 'version',
37 SELECTED_DESTINATION_ID: 'selectedDestinationId', 44 RECENT_DESTINATION_IDS: 'recentDestinationIds',
38 SELECTED_DESTINATION_ACCOUNT: 'selectedDestinationAccount', 45 RECENT_DESTINATION_ACCOUNTS: 'recentDestinationAccounts',
39 SELECTED_DESTINATION_ORIGIN: 'selectedDestinationOrigin', 46 RECENT_DESTINATION_ORIGINS: 'recentDestinationOrigins',
40 SELECTED_DESTINATION_CAPABILITIES: 'selectedDestinationCapabilities', 47 RECENT_DESTINATION_CAPABILITIES: 'recentDestinationCapabilities',
41 SELECTED_DESTINATION_NAME: 'selectedDestinationName', 48 RECENT_DESTINATION_NAMES: 'recentDestinationNames',
42 SELECTED_DESTINATION_EXTENSION_ID: 'selectedDestinationExtensionId', 49 RECENT_DESTINATION_EXTENSION_IDS: 'recentDestinationExtensionIds',
43 SELECTED_DESTINATION_EXTENSION_NAME: 'selectedDestinationExtensionName', 50 RECENT_DESTINATION_EXTENSION_NAMES: 'recentDestinationExtensionNames',
44 IS_GCP_PROMO_DISMISSED: 'isGcpPromoDismissed', 51 IS_GCP_PROMO_DISMISSED: 'isGcpPromoDismissed',
45 DPI: 'dpi', 52 DPI: 'dpi',
46 MEDIA_SIZE: 'mediaSize', 53 MEDIA_SIZE: 'mediaSize',
47 MARGINS_TYPE: 'marginsType', 54 MARGINS_TYPE: 'marginsType',
48 CUSTOM_MARGINS: 'customMargins', 55 CUSTOM_MARGINS: 'customMargins',
49 IS_COLOR_ENABLED: 'isColorEnabled', 56 IS_COLOR_ENABLED: 'isColorEnabled',
50 IS_DUPLEX_ENABLED: 'isDuplexEnabled', 57 IS_DUPLEX_ENABLED: 'isDuplexEnabled',
51 IS_HEADER_FOOTER_ENABLED: 'isHeaderFooterEnabled', 58 IS_HEADER_FOOTER_ENABLED: 'isHeaderFooterEnabled',
52 IS_LANDSCAPE_ENABLED: 'isLandscapeEnabled', 59 IS_LANDSCAPE_ENABLED: 'isLandscapeEnabled',
53 IS_COLLATE_ENABLED: 'isCollateEnabled', 60 IS_COLLATE_ENABLED: 'isCollateEnabled',
(...skipping 13 matching lines...) Expand all
67 74
68 /** 75 /**
69 * Name of C++ layer function to persist app state. 76 * Name of C++ layer function to persist app state.
70 * @type {string} 77 * @type {string}
71 * @const 78 * @const
72 * @private 79 * @private
73 */ 80 */
74 AppState.NATIVE_FUNCTION_NAME_ = 'saveAppState'; 81 AppState.NATIVE_FUNCTION_NAME_ = 'saveAppState';
75 82
76 AppState.prototype = { 83 AppState.prototype = {
84
85 /**
86 * Helper function to get the most recent value of one of the destination
87 * fields in the app state.
88 * @param {?print_preview.AppState.Field} fieldName The state field to
89 * return the value of.
90 * @return {?string|?print_preview.Cdd} The most recent value of the
91 * destination state field. ?print_preview.Cdd if the state field is
92 * RECENT_DESTINATION_CAPABILIITIES, ?string otherwise.
93 */
94 getStateValue_: function(fieldName) {
95 return (this.state_[fieldName] && this.state_[fieldName].length > 0) ?
96 this.state_[fieldName][0] : null;
97 },
98
77 /** @return {?string} ID of the selected destination. */ 99 /** @return {?string} ID of the selected destination. */
78 get selectedDestinationId() { 100 get selectedDestinationId() {
79 return this.state_[AppState.Field.SELECTED_DESTINATION_ID]; 101 return this.getStateValue_(AppState.Field.RECENT_DESTINATION_IDS);
80 }, 102 },
81 103
82 /** @return {?string} Account the selected destination is registered for. */ 104 /** @return {?string} Account the selected destination is registered for. */
83 get selectedDestinationAccount() { 105 get selectedDestinationAccount() {
84 return this.state_[AppState.Field.SELECTED_DESTINATION_ACCOUNT]; 106 return this.getStateValue_(AppState.Field.RECENT_DESTINATION_ACCOUNTS);
85 }, 107 },
86 108
87 /** 109 /**
88 * @return {?print_preview.Destination.Origin<string>} Origin of the 110 * @return {?print_preview.Destination.Origin<string>} Origin of the
89 * selected destination. 111 * selected destination.
90 */ 112 */
91 get selectedDestinationOrigin() { 113 get selectedDestinationOrigin() {
92 return this.state_[AppState.Field.SELECTED_DESTINATION_ORIGIN]; 114 return this.getStateValue_(AppState.Field.RECENT_DESTINATION_ORIGINS);
93 }, 115 },
94 116
95 /** @return {?print_preview.Cdd} CDD of the selected destination. */ 117 /** @return {?print_preview.Cdd} CDD of the selected destination. */
96 get selectedDestinationCapabilities() { 118 get selectedDestinationCapabilities() {
97 return this.state_[AppState.Field.SELECTED_DESTINATION_CAPABILITIES]; 119 return this.getStateValue_(
120 AppState.Field.RECENT_DESTINATION_CAPABILITIES);
98 }, 121 },
99 122
100 /** @return {?string} Name of the selected destination. */ 123 /** @return {?string} Name of the selected destination. */
101 get selectedDestinationName() { 124 get selectedDestinationName() {
102 return this.state_[AppState.Field.SELECTED_DESTINATION_NAME]; 125 return this.getStateValue_(AppState.Field.RECENT_DESTINATION_NAMES);
103 }, 126 },
104 127
105 /** 128 /**
106 * @return {?string} Extension ID associated with the selected destination. 129 * @return {?string} Extension ID associated with the selected destination.
107 */ 130 */
108 get selectedDestinationExtensionId() { 131 get selectedDestinationExtensionId() {
109 return this.state_[AppState.Field.SELECTED_DESTINATION_EXTENSION_ID]; 132 return this.getStateValue_(
133 AppState.Field.RECENT_DESTINATION_EXTENSION_IDS);
110 }, 134 },
111 135
112 /** 136 /**
113 * @return {?string} Extension name associated with the selected 137 * @return {?string} Extension name associated with the selected
114 * destination. 138 * destination.
115 */ 139 */
116 get selectedDestinationExtensionName() { 140 get selectedDestinationExtensionName() {
117 return this.state_[AppState.Field.SELECTED_DESTINATION_EXTENSION_NAME]; 141 return this.getStateValue_(
142 AppState.Field.RECENT_DESTINATION_EXTENSION_NAMES);
143 },
144
145 /** @return {?Array<string>} IDs of the recent destinations. */
146 get recentDestinationIds() {
147 return this.state_[AppState.Field.RECENT_DESTINATION_IDS];
148 },
149
150 /**
151 * @return {?Array<string>} Accounts the recent destinations are registered
152 * for.
153 */
154 get recentDestinationAccounts() {
155 return this.state_[AppState.Field.RECENT_DESTINATION_ACCOUNTS];
156 },
157
158 /** @return {?Array<string>} Origins of the recent destinations. */
159 get recentDestinationOrigins() {
160 return this.state_[AppState.Field.RECENT_DESTINATION_ORIGINS];
161 },
162
163 /** @return {?Array<print_preview.Cdd>} CDDs of the recent destinations. */
164 get recentDestinationCapabilities() {
165 return this.state_[AppState.Field.RECENT_DESTINATION_CAPABILITIES];
166 },
167
168 /** @return {?Array<string>} Names of the recent destinations. */
169 get recentDestinationNames() {
170 return this.state_[AppState.Field.RECENT_DESTINATION_NAMES];
171 },
172
173 /**
174 * @return {?Array<string>} Extension IDs associated with the recent
175 * destinations.
176 */
177 get recentDestinationExtensionIds() {
178 return this.state_[AppState.Field.RECENT_DESTINATION_EXTENSION_IDS];
179 },
180
181 /**
182 * @return {?Array<string>} Extension names associated with the recent
183 * destinations.
184 */
185 get recentDestinationExtensionNames() {
186 return this.state_[AppState.Field.RECENT_DESTINATION_EXTENSION_NAMES];
118 }, 187 },
119 188
120 /** @return {boolean} Whether the GCP promotion has been dismissed. */ 189 /** @return {boolean} Whether the GCP promotion has been dismissed. */
121 get isGcpPromoDismissed() { 190 get isGcpPromoDismissed() {
122 return this.state_[AppState.Field.IS_GCP_PROMO_DISMISSED]; 191 return this.state_[AppState.Field.IS_GCP_PROMO_DISMISSED];
123 }, 192 },
124 193
125 /** 194 /**
126 * @param {!print_preview.AppState.Field} field App state field to check if 195 * @param {!print_preview.AppState.Field} field App state field to check if
127 * set. 196 * set.
(...skipping 10 matching lines...) Expand all
138 getField: function(field) { 207 getField: function(field) {
139 if (field == AppState.Field.CUSTOM_MARGINS) { 208 if (field == AppState.Field.CUSTOM_MARGINS) {
140 return this.state_[field] ? 209 return this.state_[field] ?
141 print_preview.Margins.parse(this.state_[field]) : null; 210 print_preview.Margins.parse(this.state_[field]) : null;
142 } else { 211 } else {
143 return this.state_[field]; 212 return this.state_[field];
144 } 213 }
145 }, 214 },
146 215
147 /** 216 /**
217 * Helper function to set up the recent destination fields in case they are
218 * empty or only contain one value.
219 * @param {print_preview.AppState.Field} stateFieldName The state field to
220 * be set up.
221 */
222 setUpState_: function(stateFieldName) {
223 if (!this.state_[AppState.Field.RECENT_DESTINATION_IDS] ||
224 this.state_[AppState.Field.RECENT_DESTINATION_IDS].length == 0) {
225 // Ids must be a nonempty string or an Array instance. If it is null or
226 // an empty array, no destinations were saved.
227 this.state_[stateFieldName] = [];
228 } else if (!(this.state_[stateFieldName] instanceof Array)) {
229 var tmp = this.state_[stateFieldName];
230 this.state_[stateFieldName] = [tmp];
231 } else if (this.state_[stateFieldName].length >
232 AppState.NUM_DESTINATIONS_) {
233 this.state_[stateFieldName].length = AppState.NUM_DESTINATIONS_;
234 }
235 },
236
237 /**
148 * Initializes the app state from a serialized string returned by the native 238 * Initializes the app state from a serialized string returned by the native
149 * layer. 239 * layer.
150 * @param {?string} serializedAppStateStr Serialized string representation 240 * @param {?string} serializedAppStateStr Serialized string representation
151 * of the app state. 241 * of the app state.
152 */ 242 */
153 init: function(serializedAppStateStr) { 243 init: function(serializedAppStateStr) {
154 if (serializedAppStateStr) { 244 if (serializedAppStateStr) {
155 try { 245 try {
156 var state = JSON.parse(serializedAppStateStr); 246 var state = JSON.parse(serializedAppStateStr);
157 if (state[AppState.Field.VERSION] == AppState.VERSION_) { 247 if (state[AppState.Field.VERSION] == AppState.VERSION_) {
158 this.state_ = state; 248 this.state_ = state;
159 } 249 }
160 } catch(e) { 250 } catch(e) {
161 console.error('Unable to parse state: ' + e); 251 console.error('Unable to parse state: ' + e);
162 // Proceed with default state. 252 // Proceed with default state.
163 } 253 }
164 } else { 254 } else {
165 // Set some state defaults. 255 // Set some state defaults.
166 this.state_[AppState.Field.IS_GCP_PROMO_DISMISSED] = false; 256 this.state_[AppState.Field.IS_GCP_PROMO_DISMISSED] = false;
257 this.state_[AppState.Field.RECENT_DESTINATION_IDS] = [];
167 } 258 }
259
260 this.setUpState_(AppState.Field.RECENT_DESTINATION_IDS);
261 this.setUpState_(AppState.Field.RECENT_DESTINATION_ACCOUNTS);
262 this.setUpState_(AppState.Field.RECENT_DESTINATION_ORIGINS);
263 this.setUpState_(AppState.Field.RECENT_DESTINATION_CAPABILITIES);
264 this.setUpState_(AppState.Field.RECENT_DESTINATION_NAMES);
265 this.setUpState_(AppState.Field.RECENT_DESTINATION_EXTENSION_IDS);
266 this.setUpState_(AppState.Field.RECENT_DESTINATION_EXTENSION_NAMES);
168 }, 267 },
169 268
170 /** 269 /**
171 * Sets to initialized state. Now object will accept persist requests. 270 * Sets to initialized state. Now object will accept persist requests.
172 */ 271 */
173 setInitialized: function() { 272 setInitialized: function() {
174 this.isInitialized_ = true; 273 this.isInitialized_ = true;
175 }, 274 },
176 275
177 /** 276 /**
178 * Persists the given value for the given field. 277 * Persists the given value for the given field.
179 * @param {!print_preview.AppState.Field} field Field to persist. 278 * @param {!print_preview.AppState.Field} field Field to persist.
180 * @param {?} value Value of field to persist. 279 * @param {?} value Value of field to persist.
181 */ 280 */
182 persistField: function(field, value) { 281 persistField: function(field, value) {
183 if (!this.isInitialized_) 282 if (!this.isInitialized_)
184 return; 283 return;
185 if (field == AppState.Field.CUSTOM_MARGINS) { 284 if (field == AppState.Field.CUSTOM_MARGINS) {
186 this.state_[field] = value ? value.serialize() : null; 285 this.state_[field] = value ? value.serialize() : null;
187 } else { 286 } else {
188 this.state_[field] = value; 287 this.state_[field] = value;
189 } 288 }
190 this.persist_(); 289 this.persist_();
191 }, 290 },
192 291
193 /** 292 /**
293 * Shifts the desired recent destination field's values as needed and places
294 * the most recent value, destVal, in position 0 in the array.
295 * @param {number} indexFound The index where the destination already exists
296 * in the array, or -1 if it is not in the array.
297 * @param {!print_preview.AppState.Field} fieldName The field array to
298 * adjust
299 * @param {string or print_preview.Cdd} destVal The value that should be
300 * added as the most recent value in the array.
301 */
302 shiftStateField_: function(indexFound, fieldName, destVal) {
303 if (indexFound == -1 &&
304 this.state_[fieldName].length == AppState.NUM_DESTINATIONS_)
305 indexFound = AppState.NUM_DESTINATIONS_ - 1;
306 if (indexFound != -1)
307 this.state_[fieldName].splice(indexFound, 1);
308 this.state_[fieldName].splice(0, 0, destVal);
309 },
310
311 /**
194 * Persists the selected destination. 312 * Persists the selected destination.
195 * @param {!print_preview.Destination} dest Destination to persist. 313 * @param {!print_preview.Destination} dest Destination to persist.
196 */ 314 */
197 persistSelectedDestination: function(dest) { 315 persistSelectedDestination: function(dest) {
198 if (!this.isInitialized_) 316 if (!this.isInitialized_)
199 return; 317 return;
200 this.state_[AppState.Field.SELECTED_DESTINATION_ID] = dest.id; 318
201 this.state_[AppState.Field.SELECTED_DESTINATION_ACCOUNT] = dest.account; 319 // Determine if this destination is already in the recent destinations,
202 this.state_[AppState.Field.SELECTED_DESTINATION_ORIGIN] = dest.origin; 320 // and where in the array it is located.
203 this.state_[AppState.Field.SELECTED_DESTINATION_CAPABILITIES] = 321 var idIndexFound = this.state_[
204 dest.capabilities; 322 AppState.Field.RECENT_DESTINATION_IDS].indexOf(dest.id);
205 this.state_[AppState.Field.SELECTED_DESTINATION_NAME] = dest.displayName; 323 var originIndexFound = this.state_[
206 this.state_[AppState.Field.SELECTED_DESTINATION_EXTENSION_ID] = 324 AppState.Field.RECENT_DESTINATION_ORIGINS].indexOf(dest.origin);
207 dest.extensionId; 325
208 this.state_[AppState.Field.SELECTED_DESTINATION_EXTENSION_NAME] = 326 if (idIndexFound != originIndexFound ||
209 dest.extensionName; 327 idIndexFound >= AppState.NUM_DESTINATIONS_)
328 idIndexFound = -1;
329
330 if (idIndexFound == 0) {
331 this.persist_();
332 return;
333 }
334
335 // Shift all the destination state fields so that the are always ordered
336 // from most recent (entry 0) to least recent.
337 this.shiftStateField_(idIndexFound,
338 AppState.Field.RECENT_DESTINATION_IDS, dest.id);
339 this.shiftStateField_(idIndexFound,
340 AppState.Field.RECENT_DESTINATION_ACCOUNTS, dest.account || '');
341 this.shiftStateField_(idIndexFound,
342 AppState.Field.RECENT_DESTINATION_ORIGINS, dest.origin);
343 this.shiftStateField_(idIndexFound,
344 AppState.Field.RECENT_DESTINATION_CAPABILITIES,
345 dest.capabilities);
346 this.shiftStateField_(idIndexFound,
347 AppState.Field.RECENT_DESTINATION_NAMES, dest.name || '');
348 this.shiftStateField_(idIndexFound,
349 AppState.Field.RECENT_DESTINATION_EXTENSION_IDS,
350 dest.extension_id || '');
351 this.shiftStateField_(idIndexFound,
352 AppState.Field.RECENT_DESTINATION_EXTENSION_NAMES,
353 dest.extension_name || '');
354
210 this.persist_(); 355 this.persist_();
211 }, 356 },
212 357
213 /** 358 /**
214 * Persists whether the GCP promotion has been dismissed. 359 * Persists whether the GCP promotion has been dismissed.
215 * @param {boolean} isGcpPromoDismissed Whether the GCP promotion has been 360 * @param {boolean} isGcpPromoDismissed Whether the GCP promotion has been
216 * dismissed. 361 * dismissed.
217 */ 362 */
218 persistIsGcpPromoDismissed: function(isGcpPromoDismissed) { 363 persistIsGcpPromoDismissed: function(isGcpPromoDismissed) {
219 if (!this.isInitialized_) 364 if (!this.isInitialized_)
220 return; 365 return;
221 this.state_[AppState.Field.IS_GCP_PROMO_DISMISSED] = isGcpPromoDismissed; 366 this.state_[AppState.Field.IS_GCP_PROMO_DISMISSED] = isGcpPromoDismissed;
222 this.persist_(); 367 this.persist_();
223 }, 368 },
224 369
225 /** 370 /**
226 * Calls into the native layer to persist the application state. 371 * Calls into the native layer to persist the application state.
227 * @private 372 * @private
228 */ 373 */
229 persist_: function() { 374 persist_: function() {
230 chrome.send(AppState.NATIVE_FUNCTION_NAME_, 375 chrome.send(AppState.NATIVE_FUNCTION_NAME_,
231 [JSON.stringify(this.state_)]); 376 [JSON.stringify(this.state_)]);
232 } 377 }
233 }; 378 };
234 379
235 return { 380 return {
236 AppState: AppState 381 AppState: AppState
237 }; 382 };
238 }); 383 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698