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

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 errors, remove commented code 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. */
dpapad 2016/09/21 00:34:30 Nit: Indentation off by 1.
rbpotter 2016/09/21 01:43:07 Done.
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) {
dpapad 2016/09/21 00:34:30 Should these comparisons use stateFieldName instea
rbpotter 2016/09/21 01:43:07 This is intentional. The other states can have emp
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].splice(AppState.NUM_DESTINATIONS_,
dpapad 2016/09/21 00:34:30 Could you simply truncate the array by setting the
rbpotter 2016/09/21 01:43:07 Done.
234 this.state_[stateFieldName].length - AppState.NUM_DESTINATIONS_);
235 }
236 },
237
238 /**
148 * Initializes the app state from a serialized string returned by the native 239 * Initializes the app state from a serialized string returned by the native
149 * layer. 240 * layer.
150 * @param {?string} serializedAppStateStr Serialized string representation 241 * @param {?string} serializedAppStateStr Serialized string representation
151 * of the app state. 242 * of the app state.
152 */ 243 */
153 init: function(serializedAppStateStr) { 244 init: function(serializedAppStateStr) {
154 if (serializedAppStateStr) { 245 if (serializedAppStateStr) {
155 try { 246 try {
156 var state = JSON.parse(serializedAppStateStr); 247 var state = JSON.parse(serializedAppStateStr);
157 if (state[AppState.Field.VERSION] == AppState.VERSION_) { 248 if (state[AppState.Field.VERSION] == AppState.VERSION_) {
158 this.state_ = state; 249 this.state_ = state;
159 } 250 }
160 } catch(e) { 251 } catch(e) {
161 console.error('Unable to parse state: ' + e); 252 console.error('Unable to parse state: ' + e);
162 // Proceed with default state. 253 // Proceed with default state.
163 } 254 }
164 } else { 255 } else {
165 // Set some state defaults. 256 // Set some state defaults.
166 this.state_[AppState.Field.IS_GCP_PROMO_DISMISSED] = false; 257 this.state_[AppState.Field.IS_GCP_PROMO_DISMISSED] = false;
258 this.state_[AppState.Field.RECENT_DESTINATION_IDS] = [];
167 } 259 }
260
261 this.setUpState_(AppState.Field.RECENT_DESTINATION_IDS);
262 this.setUpState_(AppState.Field.RECENT_DESTINATION_ACCOUNTS);
263 this.setUpState_(AppState.Field.RECENT_DESTINATION_ORIGINS);
264 this.setUpState_(AppState.Field.RECENT_DESTINATION_CAPABILITIES);
265 this.setUpState_(AppState.Field.RECENT_DESTINATION_NAMES);
266 this.setUpState_(AppState.Field.RECENT_DESTINATION_EXTENSION_IDS);
267 this.setUpState_(AppState.Field.RECENT_DESTINATION_EXTENSION_NAMES);
168 }, 268 },
169 269
170 /** 270 /**
171 * Sets to initialized state. Now object will accept persist requests. 271 * Sets to initialized state. Now object will accept persist requests.
172 */ 272 */
173 setInitialized: function() { 273 setInitialized: function() {
174 this.isInitialized_ = true; 274 this.isInitialized_ = true;
175 }, 275 },
176 276
177 /** 277 /**
178 * Persists the given value for the given field. 278 * Persists the given value for the given field.
179 * @param {!print_preview.AppState.Field} field Field to persist. 279 * @param {!print_preview.AppState.Field} field Field to persist.
180 * @param {?} value Value of field to persist. 280 * @param {?} value Value of field to persist.
181 */ 281 */
182 persistField: function(field, value) { 282 persistField: function(field, value) {
183 if (!this.isInitialized_) 283 if (!this.isInitialized_)
184 return; 284 return;
185 if (field == AppState.Field.CUSTOM_MARGINS) { 285 if (field == AppState.Field.CUSTOM_MARGINS) {
186 this.state_[field] = value ? value.serialize() : null; 286 this.state_[field] = value ? value.serialize() : null;
187 } else { 287 } else {
188 this.state_[field] = value; 288 this.state_[field] = value;
189 } 289 }
190 this.persist_(); 290 this.persist_();
191 }, 291 },
192 292
193 /** 293 /**
294 * Shifts the desired recent destination field's values as needed and places
295 * the most recent value, destVal, in position 0 in the array.
296 * @param {number} indexFound the index where the destination already exists
297 * in the array, or -1 if it is not in the array.
298 * @param {!print_preview.AppState.Field} fieldName the field array to
299 * adjust
300 * @param {string or print_preview.Cdd} the value that should be added as
dpapad 2016/09/21 00:34:30 {string|printPreview.Cdd} destVal The value that .
rbpotter 2016/09/21 01:43:07 Done.
301 * the most recent value in the array.
302 */
303 shiftStateField_: function(indexFound, fieldName, destVal) {
304 if (indexFound == -1 &&
305 this.state_[fieldName].length == AppState.NUM_DESTINATIONS_)
306 indexFound = AppState.NUM_DESTINATIONS_ - 1;
307 if (indexFound != -1)
308 this.state_[fieldName].splice(indexFound, 1);
309 this.state_[fieldName].splice(0, 0, destVal);
310 },
311
312 /**
194 * Persists the selected destination. 313 * Persists the selected destination.
195 * @param {!print_preview.Destination} dest Destination to persist. 314 * @param {!print_preview.Destination} dest Destination to persist.
196 */ 315 */
197 persistSelectedDestination: function(dest) { 316 persistSelectedDestination: function(dest) {
198 if (!this.isInitialized_) 317 if (!this.isInitialized_ || !dest)
dpapad 2016/09/21 00:34:30 Can dest be null/undefined? If so line 314 should
rbpotter 2016/09/21 01:43:07 Done - No, it shouldn't be. This was accidentally
199 return; 318 return;
200 this.state_[AppState.Field.SELECTED_DESTINATION_ID] = dest.id; 319
201 this.state_[AppState.Field.SELECTED_DESTINATION_ACCOUNT] = dest.account; 320 // Determine if this destination is already in the recent destinations,
202 this.state_[AppState.Field.SELECTED_DESTINATION_ORIGIN] = dest.origin; 321 // and where in the array it is located.
203 this.state_[AppState.Field.SELECTED_DESTINATION_CAPABILITIES] = 322 var idIndexFound = this.state_[
204 dest.capabilities; 323 AppState.Field.RECENT_DESTINATION_IDS].indexOf(dest.id);
205 this.state_[AppState.Field.SELECTED_DESTINATION_NAME] = dest.displayName; 324 var originIndexFound = this.state_[
206 this.state_[AppState.Field.SELECTED_DESTINATION_EXTENSION_ID] = 325 AppState.Field.RECENT_DESTINATION_ORIGINS].indexOf(dest.origin);
207 dest.extensionId; 326
208 this.state_[AppState.Field.SELECTED_DESTINATION_EXTENSION_NAME] = 327 if (idIndexFound != originIndexFound ||
209 dest.extensionName; 328 idIndexFound >= AppState.NUM_DESTINATIONS_)
329 idIndexFound = -1;
330
331 if (idIndexFound == 0) {
332 this.persist_();
333 return;
334 }
335
336 // Shift all the destination state fields so that the are always ordered
337 // from most recent (entry 0) to least recent.
338 this.shiftStateField_(idIndexFound,
339 AppState.Field.RECENT_DESTINATION_IDS, dest.id);
340 this.shiftStateField_(idIndexFound,
341 AppState.Field.RECENT_DESTINATION_ACCOUNTS, dest.account || '');
342 this.shiftStateField_(idIndexFound,
343 AppState.Field.RECENT_DESTINATION_ORIGINS, dest.origin);
344 this.shiftStateField_(idIndexFound,
345 AppState.Field.RECENT_DESTINATION_CAPABILITIES,
346 dest.capabilities);
347 this.shiftStateField_(idIndexFound,
348 AppState.Field.RECENT_DESTINATION_NAMES, dest.name || '');
349 this.shiftStateField_(idIndexFound,
350 AppState.Field.RECENT_DESTINATION_EXTENSION_IDS,
351 dest.extension_id || '');
352 this.shiftStateField_(idIndexFound,
353 AppState.Field.RECENT_DESTINATION_EXTENSION_NAMES,
354 dest.extension_name || '');
355
210 this.persist_(); 356 this.persist_();
211 }, 357 },
212 358
213 /** 359 /**
214 * Persists whether the GCP promotion has been dismissed. 360 * Persists whether the GCP promotion has been dismissed.
215 * @param {boolean} isGcpPromoDismissed Whether the GCP promotion has been 361 * @param {boolean} isGcpPromoDismissed Whether the GCP promotion has been
216 * dismissed. 362 * dismissed.
217 */ 363 */
218 persistIsGcpPromoDismissed: function(isGcpPromoDismissed) { 364 persistIsGcpPromoDismissed: function(isGcpPromoDismissed) {
219 if (!this.isInitialized_) 365 if (!this.isInitialized_)
220 return; 366 return;
221 this.state_[AppState.Field.IS_GCP_PROMO_DISMISSED] = isGcpPromoDismissed; 367 this.state_[AppState.Field.IS_GCP_PROMO_DISMISSED] = isGcpPromoDismissed;
222 this.persist_(); 368 this.persist_();
223 }, 369 },
224 370
225 /** 371 /**
226 * Calls into the native layer to persist the application state. 372 * Calls into the native layer to persist the application state.
227 * @private 373 * @private
228 */ 374 */
229 persist_: function() { 375 persist_: function() {
230 chrome.send(AppState.NATIVE_FUNCTION_NAME_, 376 chrome.send(AppState.NATIVE_FUNCTION_NAME_,
231 [JSON.stringify(this.state_)]); 377 [JSON.stringify(this.state_)]);
232 } 378 }
233 }; 379 };
234 380
235 return { 381 return {
236 AppState: AppState 382 AppState: AppState
237 }; 383 };
238 }); 384 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698