Add new certificateProvider extension API.
[chromium-blink-merge.git] / chrome / browser / resources / print_preview / data / destination.js
blob9e9c88c3af5c286c61e305234a62d8429dd1933a
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.
5 cr.exportPath('print_preview');
7 /**
8  * The CDD (Cloud Device Description) describes the capabilities of a print
9  * destination.
10  *
11  * @typedef {{
12  *   version: string,
13  *   printer: {
14  *     vendor_capability: !Array<{Object}>,
15  *     collate: ({default: (boolean|undefined)}|undefined),
16  *     color: ({
17  *       option: !Array<{
18  *         type: (string|undefined),
19  *         vendor_id: (string|undefined),
20  *         custom_display_name: (string|undefined),
21  *         is_default: (boolean|undefined)
22  *       }>
23  *     }|undefined),
24  *     copies: ({default: (number|undefined),
25  *               max: (number|undefined)}|undefined),
26  *     duplex: ({option: !Array<{type: (string|undefined),
27  *                               is_default: (boolean|undefined)}>}|undefined),
28  *     page_orientation: ({
29  *       option: !Array<{type: (string|undefined),
30  *                        is_default: (boolean|undefined)}>
31  *     }|undefined)
32  *   }
33  * }}
34  */
35 print_preview.Cdd;
37 cr.define('print_preview', function() {
38   'use strict';
40   /**
41    * Print destination data object that holds data for both local and cloud
42    * destinations.
43    * @param {string} id ID of the destination.
44    * @param {!print_preview.Destination.Type} type Type of the destination.
45    * @param {!print_preview.Destination.Origin} origin Origin of the
46    *     destination.
47    * @param {string} displayName Display name of the destination.
48    * @param {boolean} isRecent Whether the destination has been used recently.
49    * @param {!print_preview.Destination.ConnectionStatus} connectionStatus
50    *     Connection status of the print destination.
51    * @param {{tags: (Array<string>|undefined),
52    *          isOwned: (boolean|undefined),
53    *          account: (string|undefined),
54    *          lastAccessTime: (number|undefined),
55    *          isTosAccepted: (boolean|undefined),
56    *          cloudID: (string|undefined),
57    *          provisionalType:
58    *              (print_preview.Destination.ProvisionalType|undefined),
59    *          extensionId: (string|undefined),
60    *          extensionName: (string|undefined),
61    *          description: (string|undefined)}=} opt_params Optional parameters
62    *     for the destination.
63    * @constructor
64    */
65   function Destination(id, type, origin, displayName, isRecent,
66                        connectionStatus, opt_params) {
67     /**
68      * ID of the destination.
69      * @private {string}
70      */
71     this.id_ = id;
73     /**
74      * Type of the destination.
75      * @private {!print_preview.Destination.Type}
76      */
77     this.type_ = type;
79     /**
80      * Origin of the destination.
81      * @private {!print_preview.Destination.Origin}
82      */
83     this.origin_ = origin;
85     /**
86      * Display name of the destination.
87      * @private {string}
88      */
89     this.displayName_ = displayName || '';
91     /**
92      * Whether the destination has been used recently.
93      * @private {boolean}
94      */
95     this.isRecent_ = isRecent;
97     /**
98      * Tags associated with the destination.
99      * @private {!Array<string>}
100      */
101     this.tags_ = (opt_params && opt_params.tags) || [];
103     /**
104      * Print capabilities of the destination.
105      * @private {?print_preview.Cdd}
106      */
107     this.capabilities_ = null;
109     /**
110      * Whether the destination is owned by the user.
111      * @private {boolean}
112      */
113     this.isOwned_ = (opt_params && opt_params.isOwned) || false;
115     /**
116      * Account this destination is registered for, if known.
117      * @private {string}
118      */
119     this.account_ = (opt_params && opt_params.account) || '';
121     /**
122      * Cache of destination location fetched from tags.
123      * @private {?string}
124      */
125     this.location_ = null;
127     /**
128      * Printer description.
129      * @private {string}
130      */
131     this.description_ = (opt_params && opt_params.description) || '';
133     /**
134      * Connection status of the destination.
135      * @private {!print_preview.Destination.ConnectionStatus}
136      */
137     this.connectionStatus_ = connectionStatus;
139     /**
140      * Number of milliseconds since the epoch when the printer was last
141      * accessed.
142      * @private {number}
143      */
144     this.lastAccessTime_ = (opt_params && opt_params.lastAccessTime) ||
145                            Date.now();
147     /**
148      * Whether the user has accepted the terms-of-service for the print
149      * destination. Only applies to the FedEx Office cloud-based printer.
150      * {@code null} if terms-of-service does not apply to the print destination.
151      * @private {?boolean}
152      */
153     this.isTosAccepted_ = !!(opt_params && opt_params.isTosAccepted);
155     /**
156      * Cloud ID for Privet printers.
157      * @private {string}
158      */
159     this.cloudID_ = (opt_params && opt_params.cloudID) || '';
161     /**
162      * Extension ID for extension managed printers.
163      * @private {string}
164      */
165     this.extensionId_ = (opt_params && opt_params.extensionId) || '';
167     /**
168      * Extension name for extension managed printers.
169      * @private {string}
170      */
171     this.extensionName_ = (opt_params && opt_params.extensionName) || '';
173     /**
174      * Different from {@code Destination.ProvisionalType.NONE} if the
175      * destination is provisional. Provisional destinations cannot be selected
176      * as they are, but have to be resolved first (i.e. extra steps have to be
177      * taken to get actual destination properties, which should replace the
178      * provisional ones). Provisional destination resolvment flow will be
179      * started when the user attempts to select the destination in search UI.
180      * @private {Destination.ProvisionalType}
181      */
182     this.provisionalType_ = (opt_params && opt_params.provisionalType) ||
183                             Destination.ProvisionalType.NONE;
185     assert(this.provisionalType_ !=
186                Destination.ProvisionalType.NEEDS_USB_PERMISSON ||
187            this.isExtension,
188            'Provisional USB destination only supprted with extension origin.');
189   };
191   /**
192    * Prefix of the location destination tag.
193    * @type {!Array<string>}
194    * @const
195    */
196   Destination.LOCATION_TAG_PREFIXES = [
197     '__cp__location=',
198     '__cp__printer-location='
199   ];
201   /**
202    * Enumeration of Google-promoted destination IDs.
203    * @enum {string}
204    */
205   Destination.GooglePromotedId = {
206     DOCS: '__google__docs',
207     FEDEX: '__google__fedex',
208     SAVE_AS_PDF: 'Save as PDF'
209   };
211   /**
212    * Enumeration of the types of destinations.
213    * @enum {string}
214    */
215   Destination.Type = {
216     GOOGLE: 'google',
217     GOOGLE_PROMOTED: 'google_promoted',
218     LOCAL: 'local',
219     MOBILE: 'mobile'
220   };
222   /**
223    * Enumeration of the origin types for cloud destinations.
224    * @enum {string}
225    */
226   Destination.Origin = {
227     LOCAL: 'local',
228     COOKIES: 'cookies',
229     PROFILE: 'profile',
230     DEVICE: 'device',
231     PRIVET: 'privet',
232     EXTENSION: 'extension'
233   };
235   /**
236    * Enumeration of the connection statuses of printer destinations.
237    * @enum {string}
238    */
239   Destination.ConnectionStatus = {
240     DORMANT: 'DORMANT',
241     OFFLINE: 'OFFLINE',
242     ONLINE: 'ONLINE',
243     UNKNOWN: 'UNKNOWN',
244     UNREGISTERED: 'UNREGISTERED'
245   };
247   /**
248    * Enumeration specifying whether a destination is provisional and the reason
249    * the destination is provisional.
250    * @enum {string
251    */
252   Destination.ProvisionalType = {
253     /** Destination is not provisional. */
254     NONE: 'NONE',
255     /**
256      * User has to grant USB access for the destination to its provider.
257      * Used for destinations with extension origin.
258      */
259     NEEDS_USB_PERMISSION: 'NEEDS_USB_PERMISSION'
260   };
262   /**
263    * Enumeration of relative icon URLs for various types of destinations.
264    * @enum {string}
265    * @private
266    */
267   Destination.IconUrl_ = {
268     CLOUD: 'images/printer.png',
269     CLOUD_SHARED: 'images/printer_shared.png',
270     LOCAL: 'images/printer.png',
271     MOBILE: 'images/mobile.png',
272     MOBILE_SHARED: 'images/mobile_shared.png',
273     THIRD_PARTY: 'images/third_party.png',
274     PDF: 'images/pdf.png',
275     DOCS: 'images/google_doc.png',
276     FEDEX: 'images/third_party_fedex.png'
277   };
279   Destination.prototype = {
280     /** @return {string} ID of the destination. */
281     get id() {
282       return this.id_;
283     },
285     /** @return {!print_preview.Destination.Type} Type of the destination. */
286     get type() {
287       return this.type_;
288     },
290     /**
291      * @return {!print_preview.Destination.Origin} Origin of the destination.
292      */
293     get origin() {
294       return this.origin_;
295     },
297     /** @return {string} Display name of the destination. */
298     get displayName() {
299       return this.displayName_;
300     },
302     /** @return {boolean} Whether the destination has been used recently. */
303     get isRecent() {
304       return this.isRecent_;
305     },
307     /**
308      * @param {boolean} isRecent Whether the destination has been used recently.
309      */
310     set isRecent(isRecent) {
311       this.isRecent_ = isRecent;
312     },
314     /**
315      * @return {boolean} Whether the user owns the destination. Only applies to
316      *     cloud-based destinations.
317      */
318     get isOwned() {
319       return this.isOwned_;
320     },
322     /**
323      * @return {string} Account this destination is registered for, if known.
324      */
325     get account() {
326       return this.account_;
327     },
329     /** @return {boolean} Whether the destination is local or cloud-based. */
330     get isLocal() {
331       return this.origin_ == Destination.Origin.LOCAL ||
332              this.origin_ == Destination.Origin.EXTENSION ||
333              (this.origin_ == Destination.Origin.PRIVET &&
334               this.connectionStatus_ !=
335               Destination.ConnectionStatus.UNREGISTERED);
336     },
338     /** @return {boolean} Whether the destination is a Privet local printer */
339     get isPrivet() {
340       return this.origin_ == Destination.Origin.PRIVET;
341     },
343     /**
344      * @return {boolean} Whether the destination is an extension managed
345      *     printer.
346      */
347     get isExtension() {
348       return this.origin_ == Destination.Origin.EXTENSION;
349     },
351     /**
352      * @return {string} The location of the destination, or an empty string if
353      *     the location is unknown.
354      */
355     get location() {
356       if (this.location_ == null) {
357         this.location_ = '';
358         this.tags_.some(function(tag) {
359           return Destination.LOCATION_TAG_PREFIXES.some(function(prefix) {
360             if (tag.indexOf(prefix) == 0) {
361               this.location_ = tag.substring(prefix.length) || '';
362               return true;
363             }
364           }, this);
365         }, this);
366       }
367       return this.location_;
368     },
370     /**
371      * @return {string} The description of the destination, or an empty string,
372      *     if it was not provided.
373      */
374     get description() {
375       return this.description_;
376     },
378     /**
379      * @return {string} Most relevant string to help user to identify this
380      *     destination.
381      */
382     get hint() {
383       if (this.id_ == Destination.GooglePromotedId.DOCS ||
384           this.id_ == Destination.GooglePromotedId.FEDEX) {
385         return this.account_;
386       }
387       return this.location || this.extensionName || this.description;
388     },
390     /** @return {!Array<string>} Tags associated with the destination. */
391     get tags() {
392       return this.tags_.slice(0);
393     },
395     /** @return {string} Cloud ID associated with the destination */
396     get cloudID() {
397       return this.cloudID_;
398     },
400     /**
401      * @return {string} Extension ID associated with the destination. Non-empty
402      *     only for extension managed printers.
403      */
404     get extensionId() {
405       return this.extensionId_;
406     },
408     /**
409      * @return {string} Extension name associated with the destination.
410      *     Non-empty only for extension managed printers.
411      */
412     get extensionName() {
413       return this.extensionName_;
414     },
416     /** @return {?print_preview.Cdd} Print capabilities of the destination. */
417     get capabilities() {
418       return this.capabilities_;
419     },
421     /**
422      * @param {!print_preview.Cdd} capabilities Print capabilities of the
423      *     destination.
424      */
425     set capabilities(capabilities) {
426       this.capabilities_ = capabilities;
427     },
429     /**
430      * @return {!print_preview.Destination.ConnectionStatus} Connection status
431      *     of the print destination.
432      */
433     get connectionStatus() {
434       return this.connectionStatus_;
435     },
437     /**
438      * @param {!print_preview.Destination.ConnectionStatus} status Connection
439      *     status of the print destination.
440      */
441     set connectionStatus(status) {
442       this.connectionStatus_ = status;
443     },
445     /** @return {boolean} Whether the destination is considered offline. */
446     get isOffline() {
447       return arrayContains([print_preview.Destination.ConnectionStatus.OFFLINE,
448                             print_preview.Destination.ConnectionStatus.DORMANT],
449                             this.connectionStatus_);
450     },
452     /** @return {string} Human readable status for offline destination. */
453     get offlineStatusText() {
454       if (!this.isOffline) {
455         return '';
456       }
457       var offlineDurationMs = Date.now() - this.lastAccessTime_;
458       var offlineMessageId;
459       if (offlineDurationMs > 31622400000.0) {  // One year.
460         offlineMessageId = 'offlineForYear';
461       } else if (offlineDurationMs > 2678400000.0) {  // One month.
462         offlineMessageId = 'offlineForMonth';
463       } else if (offlineDurationMs > 604800000.0) {  // One week.
464         offlineMessageId = 'offlineForWeek';
465       } else {
466         offlineMessageId = 'offline';
467       }
468       return loadTimeData.getString(offlineMessageId);
469     },
471     /**
472      * @return {number} Number of milliseconds since the epoch when the printer
473      *     was last accessed.
474      */
475     get lastAccessTime() {
476       return this.lastAccessTime_;
477     },
479     /** @return {string} Relative URL of the destination's icon. */
480     get iconUrl() {
481       if (this.id_ == Destination.GooglePromotedId.DOCS) {
482         return Destination.IconUrl_.DOCS;
483       } else if (this.id_ == Destination.GooglePromotedId.FEDEX) {
484         return Destination.IconUrl_.FEDEX;
485       } else if (this.id_ == Destination.GooglePromotedId.SAVE_AS_PDF) {
486         return Destination.IconUrl_.PDF;
487       } else if (this.isLocal) {
488         return Destination.IconUrl_.LOCAL;
489       } else if (this.type_ == Destination.Type.MOBILE && this.isOwned_) {
490         return Destination.IconUrl_.MOBILE;
491       } else if (this.type_ == Destination.Type.MOBILE) {
492         return Destination.IconUrl_.MOBILE_SHARED;
493       } else if (this.isOwned_) {
494         return Destination.IconUrl_.CLOUD;
495       } else {
496         return Destination.IconUrl_.CLOUD_SHARED;
497       }
498     },
500     /**
501      * @return {?boolean} Whether the user has accepted the terms-of-service of
502      *     the print destination or {@code null} if a terms-of-service does not
503      *     apply.
504      */
505     get isTosAccepted() {
506       return this.isTosAccepted_;
507     },
509     /**
510      * @param {?boolean} isTosAccepted Whether the user has accepted the
511      *     terms-of-service of the print destination or {@code null} if
512      *     a terms-of-service does not apply.
513      */
514     set isTosAccepted(isTosAccepted) {
515       this.isTosAccepted_ = isTosAccepted;
516     },
518     /**
519      * @return {!Array<string>} Properties (besides display name) to match
520      *     search queries against.
521      */
522     get extraPropertiesToMatch() {
523       return [this.location, this.description];
524     },
526     /**
527      * Matches a query against the destination.
528      * @param {!RegExp} query Query to match against the destination.
529      * @return {boolean} {@code true} if the query matches this destination,
530      *     {@code false} otherwise.
531      */
532     matches: function(query) {
533       return !!this.displayName_.match(query) ||
534           !!this.extensionName_.match(query) ||
535           this.extraPropertiesToMatch.some(function(property) {
536             return property.match(query);
537           });
538     },
540     /**
541      * Gets the destination's provisional type.
542      * @return {Destination.ProvisionalType}
543      */
544     get provisionalType() {
545       return this.provisionalType_;
546     },
548     /**
549      * Whether the destinaion is provisional.
550      * @return {boolean}
551      */
552     get isProvisional() {
553       return this.provisionalType_ != Destination.ProvisionalType.NONE;
554     }
555   };
557   // Export
558   return {
559     Destination: Destination,
560   };