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 5 cr.define('print_preview', function() { 6 'use strict'; 7 8 /** 9 * Print destination data object that holds data for both local and cloud 10 * destinations. 11 * @param {string} id ID of the destination. 12 * @param {!print_preview.Destination.Type} type Type of the destination. 13 * @param {!print_preview.Destination.Origin} origin Origin of the 14 * destination. 15 * @param {string} displayName Display name of the destination. 16 * @param {boolean} isRecent Whether the destination has been used recently. 17 * @param {!print_preview.Destination.ConnectionStatus} connectionStatus 18 * Connection status of the print destination. 19 * @param {{tags: Array.<string>, 20 * isOwned: ?boolean, 21 * account: ?string, 22 * lastAccessTime: ?number, 23 * isTosAccepted: ?boolean, 24 * cloudID: ?string, 25 * description: ?string}=} opt_params Optional parameters for the 26 * destination. 27 * @constructor 28 */ 29 function Destination(id, type, origin, displayName, isRecent, 30 connectionStatus, opt_params) { 31 /** 32 * ID of the destination. 33 * @private {string} 34 */ 35 this.id_ = id; 36 37 /** 38 * Type of the destination. 39 * @private {!print_preview.Destination.Type} 40 */ 41 this.type_ = type; 42 43 /** 44 * Origin of the destination. 45 * @private {!print_preview.Destination.Origin} 46 */ 47 this.origin_ = origin; 48 49 /** 50 * Display name of the destination. 51 * @private {string} 52 */ 53 this.displayName_ = displayName || ''; 54 55 /** 56 * Whether the destination has been used recently. 57 * @private {boolean} 58 */ 59 this.isRecent_ = isRecent; 60 61 /** 62 * Tags associated with the destination. 63 * @private {!Array.<string>} 64 */ 65 this.tags_ = (opt_params && opt_params.tags) || []; 66 67 /** 68 * Print capabilities of the destination. 69 * @private {print_preview.Cdd} 70 */ 71 this.capabilities_ = null; 72 73 /** 74 * Whether the destination is owned by the user. 75 * @private {boolean} 76 */ 77 this.isOwned_ = (opt_params && opt_params.isOwned) || false; 78 79 /** 80 * Account this destination is registered for, if known. 81 * @private {string} 82 */ 83 this.account_ = (opt_params && opt_params.account) || ''; 84 85 /** 86 * Cache of destination location fetched from tags. 87 * @private {?string} 88 */ 89 this.location_ = null; 90 91 /** 92 * Printer description. 93 * @private {string} 94 */ 95 this.description_ = (opt_params && opt_params.description) || ''; 96 97 /** 98 * Connection status of the destination. 99 * @private {!print_preview.Destination.ConnectionStatus} 100 */ 101 this.connectionStatus_ = connectionStatus; 102 103 /** 104 * Number of milliseconds since the epoch when the printer was last 105 * accessed. 106 * @private {number} 107 */ 108 this.lastAccessTime_ = (opt_params && opt_params.lastAccessTime) || 109 Date.now(); 110 111 /** 112 * Whether the user has accepted the terms-of-service for the print 113 * destination. Only applies to the FedEx Office cloud-based printer. 114 * {@code null} if terms-of-service does not apply to the print destination. 115 * @private {?boolean} 116 */ 117 this.isTosAccepted_ = opt_params && opt_params.isTosAccepted; 118 119 /** 120 * Cloud ID for Privet printers. 121 * @private {string} 122 */ 123 this.cloudID_ = (opt_params && opt_params.cloudID) || ''; 124 }; 125 126 /** 127 * Prefix of the location destination tag. 128 * @type {!Array.<string>} 129 * @const 130 */ 131 Destination.LOCATION_TAG_PREFIXES = [ 132 '__cp__location=', 133 '__cp__printer-location=' 134 ]; 135 136 /** 137 * Enumeration of Google-promoted destination IDs. 138 * @enum {string} 139 */ 140 Destination.GooglePromotedId = { 141 DOCS: '__google__docs', 142 FEDEX: '__google__fedex', 143 SAVE_AS_PDF: 'Save as PDF' 144 }; 145 146 /** 147 * Enumeration of the types of destinations. 148 * @enum {string} 149 */ 150 Destination.Type = { 151 GOOGLE: 'google', 152 LOCAL: 'local', 153 MOBILE: 'mobile' 154 }; 155 156 /** 157 * Enumeration of the origin types for cloud destinations. 158 * @enum {string} 159 */ 160 Destination.Origin = { 161 LOCAL: 'local', 162 COOKIES: 'cookies', 163 PROFILE: 'profile', 164 DEVICE: 'device', 165 PRIVET: 'privet' 166 }; 167 168 /** 169 * Enumeration of the connection statuses of printer destinations. 170 * @enum {string} 171 */ 172 Destination.ConnectionStatus = { 173 DORMANT: 'DORMANT', 174 OFFLINE: 'OFFLINE', 175 ONLINE: 'ONLINE', 176 UNKNOWN: 'UNKNOWN', 177 UNREGISTERED: 'UNREGISTERED' 178 }; 179 180 /** 181 * Enumeration of relative icon URLs for various types of destinations. 182 * @enum {string} 183 * @private 184 */ 185 Destination.IconUrl_ = { 186 CLOUD: 'images/printer.png', 187 CLOUD_SHARED: 'images/printer_shared.png', 188 LOCAL: 'images/printer.png', 189 MOBILE: 'images/mobile.png', 190 MOBILE_SHARED: 'images/mobile_shared.png', 191 THIRD_PARTY: 'images/third_party.png', 192 PDF: 'images/pdf.png', 193 DOCS: 'images/google_doc.png', 194 FEDEX: 'images/third_party_fedex.png' 195 }; 196 197 Destination.prototype = { 198 /** @return {string} ID of the destination. */ 199 get id() { 200 return this.id_; 201 }, 202 203 /** @return {!print_preview.Destination.Type} Type of the destination. */ 204 get type() { 205 return this.type_; 206 }, 207 208 /** 209 * @return {!print_preview.Destination.Origin} Origin of the destination. 210 */ 211 get origin() { 212 return this.origin_; 213 }, 214 215 /** @return {string} Display name of the destination. */ 216 get displayName() { 217 return this.displayName_; 218 }, 219 220 /** @return {boolean} Whether the destination has been used recently. */ 221 get isRecent() { 222 return this.isRecent_; 223 }, 224 225 /** 226 * @param {boolean} isRecent Whether the destination has been used recently. 227 */ 228 set isRecent(isRecent) { 229 this.isRecent_ = isRecent; 230 }, 231 232 /** 233 * @return {boolean} Whether the user owns the destination. Only applies to 234 * cloud-based destinations. 235 */ 236 get isOwned() { 237 return this.isOwned_; 238 }, 239 240 /** 241 * @return {string} Account this destination is registered for, if known. 242 */ 243 get account() { 244 return this.account_; 245 }, 246 247 /** @return {boolean} Whether the destination is local or cloud-based. */ 248 get isLocal() { 249 return this.origin_ == Destination.Origin.LOCAL || 250 (this.origin_ == Destination.Origin.PRIVET && 251 this.connectionStatus_ != 252 Destination.ConnectionStatus.UNREGISTERED); 253 }, 254 255 /** @return {boolean} Whether the destination is a Privet local printer */ 256 get isPrivet() { 257 return this.origin_ == Destination.Origin.PRIVET; 258 }, 259 260 /** 261 * @return {string} The location of the destination, or an empty string if 262 * the location is unknown. 263 */ 264 get location() { 265 if (this.location_ == null) { 266 this.location_ = ''; 267 this.tags_.some(function(tag) { 268 return Destination.LOCATION_TAG_PREFIXES.some(function(prefix) { 269 if (tag.indexOf(prefix) == 0) { 270 this.location_ = tag.substring(prefix.length) || ''; 271 return true; 272 } 273 }, this); 274 }, this); 275 } 276 return this.location_; 277 }, 278 279 /** 280 * @return {string} The description of the destination, or an empty string, 281 * if it was not provided. 282 */ 283 get description() { 284 return this.description_; 285 }, 286 287 /** 288 * @return {string} Most relevant string to help user to identify this 289 * destination. 290 */ 291 get hint() { 292 if (this.id_ == Destination.GooglePromotedId.DOCS || 293 this.id_ == Destination.GooglePromotedId.FEDEX) { 294 return this.account_; 295 } 296 return this.location || this.description; 297 }, 298 299 /** @return {!Array.<string>} Tags associated with the destination. */ 300 get tags() { 301 return this.tags_.slice(0); 302 }, 303 304 /** @return {string} Cloud ID associated with the destination */ 305 get cloudID() { 306 return this.cloudID_; 307 }, 308 309 /** @return {print_preview.Cdd} Print capabilities of the destination. */ 310 get capabilities() { 311 return this.capabilities_; 312 }, 313 314 /** 315 * @param {!print_preview.Cdd} capabilities Print capabilities of the 316 * destination. 317 */ 318 set capabilities(capabilities) { 319 this.capabilities_ = capabilities; 320 }, 321 322 /** 323 * @return {!print_preview.Destination.ConnectionStatus} Connection status 324 * of the print destination. 325 */ 326 get connectionStatus() { 327 return this.connectionStatus_; 328 }, 329 330 /** 331 * @param {!print_preview.Destination.ConnectionStatus} status Connection 332 * status of the print destination. 333 */ 334 set connectionStatus(status) { 335 this.connectionStatus_ = status; 336 }, 337 338 /** @return {boolean} Whether the destination is considered offline. */ 339 get isOffline() { 340 return arrayContains([print_preview.Destination.ConnectionStatus.OFFLINE, 341 print_preview.Destination.ConnectionStatus.DORMANT], 342 this.connectionStatus_); 343 }, 344 345 /** @return {string} Human readable status for offline destination. */ 346 get offlineStatusText() { 347 if (!this.isOffline) { 348 return ''; 349 } 350 var offlineDurationMs = Date.now() - this.lastAccessTime_; 351 var offlineMessageId; 352 if (offlineDurationMs > 31622400000.0) { // One year. 353 offlineMessageId = 'offlineForYear'; 354 } else if (offlineDurationMs > 2678400000.0) { // One month. 355 offlineMessageId = 'offlineForMonth'; 356 } else if (offlineDurationMs > 604800000.0) { // One week. 357 offlineMessageId = 'offlineForWeek'; 358 } else { 359 offlineMessageId = 'offline'; 360 } 361 return localStrings.getString(offlineMessageId); 362 }, 363 364 /** 365 * @return {number} Number of milliseconds since the epoch when the printer 366 * was last accessed. 367 */ 368 get lastAccessTime() { 369 return this.lastAccessTime_; 370 }, 371 372 /** @return {string} Relative URL of the destination's icon. */ 373 get iconUrl() { 374 if (this.id_ == Destination.GooglePromotedId.DOCS) { 375 return Destination.IconUrl_.DOCS; 376 } else if (this.id_ == Destination.GooglePromotedId.FEDEX) { 377 return Destination.IconUrl_.FEDEX; 378 } else if (this.id_ == Destination.GooglePromotedId.SAVE_AS_PDF) { 379 return Destination.IconUrl_.PDF; 380 } else if (this.isLocal) { 381 return Destination.IconUrl_.LOCAL; 382 } else if (this.type_ == Destination.Type.MOBILE && this.isOwned_) { 383 return Destination.IconUrl_.MOBILE; 384 } else if (this.type_ == Destination.Type.MOBILE) { 385 return Destination.IconUrl_.MOBILE_SHARED; 386 } else if (this.isOwned_) { 387 return Destination.IconUrl_.CLOUD; 388 } else { 389 return Destination.IconUrl_.CLOUD_SHARED; 390 } 391 }, 392 393 /** 394 * @return {?boolean} Whether the user has accepted the terms-of-service of 395 * the print destination or {@code null} if a terms-of-service does not 396 * apply. 397 */ 398 get isTosAccepted() { 399 return this.isTosAccepted_; 400 }, 401 402 /** 403 * @param {?boolean} Whether the user has accepted the terms-of-service of 404 * the print destination or {@code null} if a terms-of-service does not 405 * apply. 406 */ 407 set isTosAccepted(isTosAccepted) { 408 this.isTosAccepted_ = isTosAccepted; 409 }, 410 411 /** 412 * @return {!Array.<string>} Properties (besides display name) to match 413 * search queries against. 414 */ 415 get extraPropertiesToMatch() { 416 return [this.location, this.description]; 417 }, 418 419 /** 420 * Matches a query against the destination. 421 * @param {!RegExp} query Query to match against the destination. 422 * @return {boolean} {@code true} if the query matches this destination, 423 * {@code false} otherwise. 424 */ 425 matches: function(query) { 426 return this.displayName_.match(query) || 427 this.extraPropertiesToMatch.some(function(property) { 428 return property.match(query); 429 }); 430 } 431 }; 432 433 /** 434 * The CDD (Cloud Device Description) describes the capabilities of a print 435 * destination. 436 * 437 * @typedef {{ 438 * version: string, 439 * printer: { 440 * vendor_capability: !Array.<{Object}>, 441 * collate: {default: boolean=}=, 442 * color: { 443 * option: !Array.<{ 444 * type: string=, 445 * vendor_id: string=, 446 * custom_display_name: string=, 447 * is_default: boolean= 448 * }> 449 * }=, 450 * copies: {default: number=, max: number=}=, 451 * duplex: {option: !Array.<{type: string=, is_default: boolean=}>}=, 452 * page_orientation: { 453 * option: !Array.<{type: string=, is_default: boolean=}> 454 * }= 455 * } 456 * }} 457 */ 458 var Cdd = Object; 459 460 // Export 461 return { 462 Destination: Destination, 463 Cdd: Cdd 464 }; 465 }); 466