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');
8 * The CDD (Cloud Device Description) describes the capabilities of a print
14 * vendor_capability: !Array<{Object}>,
15 * collate: ({default: (boolean|undefined)}|undefined),
18 * type: (string|undefined),
19 * vendor_id: (string|undefined),
20 * custom_display_name: (string|undefined),
21 * is_default: (boolean|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)}>
37 cr.define('print_preview', function() {
41 * Print destination data object that holds data for both local and cloud
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
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),
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.
65 function Destination(id, type, origin, displayName, isRecent,
66 connectionStatus, opt_params) {
68 * ID of the destination.
74 * Type of the destination.
75 * @private {!print_preview.Destination.Type}
80 * Origin of the destination.
81 * @private {!print_preview.Destination.Origin}
83 this.origin_ = origin;
86 * Display name of the destination.
89 this.displayName_ = displayName || '';
92 * Whether the destination has been used recently.
95 this.isRecent_ = isRecent;
98 * Tags associated with the destination.
99 * @private {!Array<string>}
101 this.tags_ = (opt_params && opt_params.tags) || [];
104 * Print capabilities of the destination.
105 * @private {?print_preview.Cdd}
107 this.capabilities_ = null;
110 * Whether the destination is owned by the user.
113 this.isOwned_ = (opt_params && opt_params.isOwned) || false;
116 * Account this destination is registered for, if known.
119 this.account_ = (opt_params && opt_params.account) || '';
122 * Cache of destination location fetched from tags.
125 this.location_ = null;
128 * Printer description.
131 this.description_ = (opt_params && opt_params.description) || '';
134 * Connection status of the destination.
135 * @private {!print_preview.Destination.ConnectionStatus}
137 this.connectionStatus_ = connectionStatus;
140 * Number of milliseconds since the epoch when the printer was last
144 this.lastAccessTime_ = (opt_params && opt_params.lastAccessTime) ||
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}
153 this.isTosAccepted_ = !!(opt_params && opt_params.isTosAccepted);
156 * Cloud ID for Privet printers.
159 this.cloudID_ = (opt_params && opt_params.cloudID) || '';
162 * Extension ID for extension managed printers.
165 this.extensionId_ = (opt_params && opt_params.extensionId) || '';
168 * Extension name for extension managed printers.
171 this.extensionName_ = (opt_params && opt_params.extensionName) || '';
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}
182 this.provisionalType_ = (opt_params && opt_params.provisionalType) ||
183 Destination.ProvisionalType.NONE;
185 assert(this.provisionalType_ !=
186 Destination.ProvisionalType.NEEDS_USB_PERMISSON ||
188 'Provisional USB destination only supprted with extension origin.');
192 * Prefix of the location destination tag.
193 * @type {!Array<string>}
196 Destination.LOCATION_TAG_PREFIXES = [
198 '__cp__printer-location='
202 * Enumeration of Google-promoted destination IDs.
205 Destination.GooglePromotedId = {
206 DOCS: '__google__docs',
207 FEDEX: '__google__fedex',
208 SAVE_AS_PDF: 'Save as PDF'
212 * Enumeration of the types of destinations.
217 GOOGLE_PROMOTED: 'google_promoted',
223 * Enumeration of the origin types for cloud destinations.
226 Destination.Origin = {
232 EXTENSION: 'extension'
236 * Enumeration of the connection statuses of printer destinations.
239 Destination.ConnectionStatus = {
244 UNREGISTERED: 'UNREGISTERED'
248 * Enumeration specifying whether a destination is provisional and the reason
249 * the destination is provisional.
252 Destination.ProvisionalType = {
253 /** Destination is not provisional. */
256 * User has to grant USB access for the destination to its provider.
257 * Used for destinations with extension origin.
259 NEEDS_USB_PERMISSION: 'NEEDS_USB_PERMISSION'
263 * Enumeration of relative icon URLs for various types of destinations.
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'
279 Destination.prototype = {
280 /** @return {string} ID of the destination. */
285 /** @return {!print_preview.Destination.Type} Type of the destination. */
291 * @return {!print_preview.Destination.Origin} Origin of the destination.
297 /** @return {string} Display name of the destination. */
299 return this.displayName_;
302 /** @return {boolean} Whether the destination has been used recently. */
304 return this.isRecent_;
308 * @param {boolean} isRecent Whether the destination has been used recently.
310 set isRecent(isRecent) {
311 this.isRecent_ = isRecent;
315 * @return {boolean} Whether the user owns the destination. Only applies to
316 * cloud-based destinations.
319 return this.isOwned_;
323 * @return {string} Account this destination is registered for, if known.
326 return this.account_;
329 /** @return {boolean} Whether the destination is local or cloud-based. */
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);
338 /** @return {boolean} Whether the destination is a Privet local printer */
340 return this.origin_ == Destination.Origin.PRIVET;
344 * @return {boolean} Whether the destination is an extension managed
348 return this.origin_ == Destination.Origin.EXTENSION;
352 * @return {string} The location of the destination, or an empty string if
353 * the location is unknown.
356 if (this.location_ == null) {
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) || '';
367 return this.location_;
371 * @return {string} The description of the destination, or an empty string,
372 * if it was not provided.
375 return this.description_;
379 * @return {string} Most relevant string to help user to identify this
383 if (this.id_ == Destination.GooglePromotedId.DOCS ||
384 this.id_ == Destination.GooglePromotedId.FEDEX) {
385 return this.account_;
387 return this.location || this.extensionName || this.description;
390 /** @return {!Array<string>} Tags associated with the destination. */
392 return this.tags_.slice(0);
395 /** @return {string} Cloud ID associated with the destination */
397 return this.cloudID_;
401 * @return {string} Extension ID associated with the destination. Non-empty
402 * only for extension managed printers.
405 return this.extensionId_;
409 * @return {string} Extension name associated with the destination.
410 * Non-empty only for extension managed printers.
412 get extensionName() {
413 return this.extensionName_;
416 /** @return {?print_preview.Cdd} Print capabilities of the destination. */
418 return this.capabilities_;
422 * @param {!print_preview.Cdd} capabilities Print capabilities of the
425 set capabilities(capabilities) {
426 this.capabilities_ = capabilities;
430 * @return {!print_preview.Destination.ConnectionStatus} Connection status
431 * of the print destination.
433 get connectionStatus() {
434 return this.connectionStatus_;
438 * @param {!print_preview.Destination.ConnectionStatus} status Connection
439 * status of the print destination.
441 set connectionStatus(status) {
442 this.connectionStatus_ = status;
445 /** @return {boolean} Whether the destination is considered offline. */
447 return arrayContains([print_preview.Destination.ConnectionStatus.OFFLINE,
448 print_preview.Destination.ConnectionStatus.DORMANT],
449 this.connectionStatus_);
452 /** @return {string} Human readable status for offline destination. */
453 get offlineStatusText() {
454 if (!this.isOffline) {
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';
466 offlineMessageId = 'offline';
468 return loadTimeData.getString(offlineMessageId);
472 * @return {number} Number of milliseconds since the epoch when the printer
475 get lastAccessTime() {
476 return this.lastAccessTime_;
479 /** @return {string} Relative URL of the destination's icon. */
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;
496 return Destination.IconUrl_.CLOUD_SHARED;
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
505 get isTosAccepted() {
506 return this.isTosAccepted_;
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.
514 set isTosAccepted(isTosAccepted) {
515 this.isTosAccepted_ = isTosAccepted;
519 * @return {!Array<string>} Properties (besides display name) to match
520 * search queries against.
522 get extraPropertiesToMatch() {
523 return [this.location, this.description];
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.
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);
541 * Gets the destination's provisional type.
542 * @return {Destination.ProvisionalType}
544 get provisionalType() {
545 return this.provisionalType_;
549 * Whether the destinaion is provisional.
552 get isProvisional() {
553 return this.provisionalType_ != Destination.ProvisionalType.NONE;
559 Destination: Destination,