OLD | NEW |
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 /** | 5 /** |
6 * This object encapsulates everything related to tasks execution. | 6 * This object encapsulates everything related to tasks execution. |
| 7 * |
7 * @param {FileManager} fileManager FileManager instance. | 8 * @param {FileManager} fileManager FileManager instance. |
8 * @param {object} opt_params File manager load parameters. | 9 * @param {object} opt_params File manager load parameters. |
| 10 * @constructor |
9 */ | 11 */ |
10 function FileTasks(fileManager, opt_params) { | 12 function FileTasks(fileManager, opt_params) { |
11 this.fileManager_ = fileManager; | 13 this.fileManager_ = fileManager; |
12 this.params_ = opt_params; | 14 this.params_ = opt_params; |
13 this.tasks_ = null; | 15 this.tasks_ = null; |
14 this.defaultTask_ = null; | 16 this.defaultTask_ = null; |
15 | 17 |
16 /** | 18 /** |
17 * List of invocations to be called once tasks are available. | 19 * List of invocations to be called once tasks are available. |
| 20 * |
| 21 * @private |
| 22 * @type {Array,<Object>} |
18 */ | 23 */ |
19 this.pendingInvocations_ = []; | 24 this.pendingInvocations_ = []; |
20 } | 25 } |
21 | 26 |
22 /** | 27 /** |
23 * Location of the Chrome Web Store. | 28 * Location of the Chrome Web Store. |
| 29 * |
| 30 * @const |
| 31 * @type {string} |
24 */ | 32 */ |
25 FileTasks.CHROME_WEB_STORE_URL = 'https://chrome.google.com/webstore'; | 33 FileTasks.CHROME_WEB_STORE_URL = 'https://chrome.google.com/webstore'; |
26 | 34 |
27 /** | 35 /** |
28 * Location of the FAQ about the file actions. | 36 * Location of the FAQ about the file actions. |
| 37 * |
| 38 * @const |
| 39 * @type {string} |
29 */ | 40 */ |
30 FileTasks.NO_ACTION_FOR_FILE_URL = 'http://support.google.com/chromeos/bin/' + | 41 FileTasks.NO_ACTION_FOR_FILE_URL = 'http://support.google.com/chromeos/bin/' + |
31 'answer.py?answer=1700055&topic=29026&ctx=topic'; | 42 'answer.py?answer=1700055&topic=29026&ctx=topic'; |
32 | 43 |
33 /** | 44 /** |
34 * Complete the initialization. | 45 * Complete the initialization. |
35 * | 46 * |
36 * @param {Array.<string>} urls List of file urls. | 47 * @param {Array.<string>} urls List of file urls. |
37 * @param {Array.<string>=} opt_mimeTypes List of MIME types for each | 48 * @param {Array.<string>=} opt_mimeTypes List of MIME types for each |
38 * of the files. | 49 * of the files. |
39 */ | 50 */ |
40 FileTasks.prototype.init = function(urls, opt_mimeTypes) { | 51 FileTasks.prototype.init = function(urls, opt_mimeTypes) { |
41 this.urls_ = urls; | 52 this.urls_ = urls; |
42 if (urls.length > 0) | 53 if (urls.length > 0) |
43 chrome.fileBrowserPrivate.getFileTasks(urls, opt_mimeTypes || [], | 54 chrome.fileBrowserPrivate.getFileTasks(urls, opt_mimeTypes || [], |
44 this.onTasks_.bind(this)); | 55 this.onTasks_.bind(this)); |
45 }; | 56 }; |
46 | 57 |
47 /** | 58 /** |
48 * Returns amount of tasks. | 59 * Returns amount of tasks. |
49 * @return {number=} amount of tasks. | 60 * |
| 61 * @return {number} amount of tasks. |
50 */ | 62 */ |
51 FileTasks.prototype.size = function() { | 63 FileTasks.prototype.size = function() { |
52 return (this.tasks_ && this.tasks_.length) || 0; | 64 return (this.tasks_ && this.tasks_.length) || 0; |
53 }; | 65 }; |
54 | 66 |
55 /** | 67 /** |
56 * Callback when tasks found. | 68 * Callback when tasks found. |
| 69 * |
57 * @param {Array.<Object>} tasks The tasks. | 70 * @param {Array.<Object>} tasks The tasks. |
58 * @private | 71 * @private |
59 */ | 72 */ |
60 FileTasks.prototype.onTasks_ = function(tasks) { | 73 FileTasks.prototype.onTasks_ = function(tasks) { |
61 this.processTasks_(tasks); | 74 this.processTasks_(tasks); |
62 for (var index = 0; index < this.pendingInvocations_.length; index++) { | 75 for (var index = 0; index < this.pendingInvocations_.length; index++) { |
63 var name = this.pendingInvocations_[index][0]; | 76 var name = this.pendingInvocations_[index][0]; |
64 var args = this.pendingInvocations_[index][1]; | 77 var args = this.pendingInvocations_[index][1]; |
65 this[name].apply(this, args); | 78 this[name].apply(this, args); |
66 } | 79 } |
67 this.pendingInvocations_ = []; | 80 this.pendingInvocations_ = []; |
68 }; | 81 }; |
69 | 82 |
70 /** | 83 /** |
71 * Processes internal tasks. | 84 * Processes internal tasks. |
| 85 * |
72 * @param {Array.<Object>} tasks The tasks. | 86 * @param {Array.<Object>} tasks The tasks. |
73 * @private | 87 * @private |
74 */ | 88 */ |
75 FileTasks.prototype.processTasks_ = function(tasks) { | 89 FileTasks.prototype.processTasks_ = function(tasks) { |
76 this.tasks_ = []; | 90 this.tasks_ = []; |
77 var id = util.platform.getAppId(); | 91 var id = util.platform.getAppId(); |
78 var is_on_drive = false; | 92 var is_on_drive = false; |
79 for (var index = 0; index < this.urls_.length; ++index) { | 93 for (var index = 0; index < this.urls_.length; ++index) { |
80 if (FileType.isOnDrive(this.urls_[index])) { | 94 if (FileType.isOnDrive(this.urls_[index])) { |
81 is_on_drive = true; | 95 is_on_drive = true; |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
149 if (!this.defaultTask_ && this.tasks_.length > 0) { | 163 if (!this.defaultTask_ && this.tasks_.length > 0) { |
150 // If we haven't picked a default task yet, then just pick the first one. | 164 // If we haven't picked a default task yet, then just pick the first one. |
151 // This is not the preferred way we want to pick this, but better this than | 165 // This is not the preferred way we want to pick this, but better this than |
152 // no default at all if the C++ code didn't set one. | 166 // no default at all if the C++ code didn't set one. |
153 this.defaultTask_ = this.tasks_[0]; | 167 this.defaultTask_ = this.tasks_[0]; |
154 } | 168 } |
155 }; | 169 }; |
156 | 170 |
157 /** | 171 /** |
158 * Executes default task. | 172 * Executes default task. |
| 173 * |
159 * @private | 174 * @private |
160 */ | 175 */ |
161 FileTasks.prototype.executeDefault_ = function() { | 176 FileTasks.prototype.executeDefault_ = function() { |
162 if (this.defaultTask_ != null) { | 177 if (this.defaultTask_ != null) { |
163 this.execute_(this.defaultTask_.taskId); | 178 this.execute_(this.defaultTask_.taskId); |
164 return; | 179 return; |
165 } | 180 } |
166 | 181 |
167 // We don't have tasks, so try to show a file in a browser tab. | 182 // We don't have tasks, so try to show a file in a browser tab. |
168 // We only do that for single selection to avoid confusion. | 183 // We only do that for single selection to avoid confusion. |
(...skipping 14 matching lines...) Expand all Loading... |
183 this.checkAvailability_(function() { | 198 this.checkAvailability_(function() { |
184 chrome.fileBrowserPrivate.viewFiles(this.urls_, 'default', callback); | 199 chrome.fileBrowserPrivate.viewFiles(this.urls_, 'default', callback); |
185 }.bind(this)); | 200 }.bind(this)); |
186 } | 201 } |
187 | 202 |
188 // Do nothing for multiple urls. | 203 // Do nothing for multiple urls. |
189 }; | 204 }; |
190 | 205 |
191 /** | 206 /** |
192 * Executes a single task. | 207 * Executes a single task. |
| 208 * |
193 * @param {string} taskId Task identifier. | 209 * @param {string} taskId Task identifier. |
194 * @param {Array.<string>=} opt_urls Urls to execute on instead of |this.urls_|. | 210 * @param {Array.<string>=} opt_urls Urls to execute on instead of |this.urls_|. |
195 * @private | 211 * @private |
196 */ | 212 */ |
197 FileTasks.prototype.execute_ = function(taskId, opt_urls) { | 213 FileTasks.prototype.execute_ = function(taskId, opt_urls) { |
198 var urls = opt_urls || this.urls_; | 214 var urls = opt_urls || this.urls_; |
199 this.checkAvailability_(function() { | 215 this.checkAvailability_(function() { |
200 var task_parts = taskId.split('|'); | 216 var task_parts = taskId.split('|'); |
201 if (task_parts[0] == util.platform.getAppId() && task_parts[1] == 'file') { | 217 if (task_parts[0] == util.platform.getAppId() && task_parts[1] == 'file') { |
202 // For internal tasks we do not listen to the event to avoid | 218 // For internal tasks we do not listen to the event to avoid |
203 // handling the same task instance from multiple tabs. | 219 // handling the same task instance from multiple tabs. |
204 // So, we manually execute the task. | 220 // So, we manually execute the task. |
205 this.executeInternalTask_(task_parts[2], urls); | 221 this.executeInternalTask_(task_parts[2], urls); |
206 } else { | 222 } else { |
207 chrome.fileBrowserPrivate.executeTask(taskId, urls); | 223 chrome.fileBrowserPrivate.executeTask(taskId, urls); |
208 } | 224 } |
209 }.bind(this)); | 225 }.bind(this)); |
210 }; | 226 }; |
211 | 227 |
212 /** | 228 /** |
213 * Checks whether the remote files are available right now. | 229 * Checks whether the remote files are available right now. |
| 230 * |
214 * @param {function} callback The callback. | 231 * @param {function} callback The callback. |
215 * @private | 232 * @private |
216 */ | 233 */ |
217 FileTasks.prototype.checkAvailability_ = function(callback) { | 234 FileTasks.prototype.checkAvailability_ = function(callback) { |
218 var areAll = function(props, name) { | 235 var areAll = function(props, name) { |
219 var isOne = function(e) { | 236 var isOne = function(e) { |
220 // If got no properties, we safely assume that item is unavailable. | 237 // If got no properties, we safely assume that item is unavailable. |
221 return e && e[name]; | 238 return e && e[name]; |
222 }; | 239 }; |
223 return props.filter(isOne).length == props.length; | 240 return props.filter(isOne).length == props.length; |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
272 }); | 289 }); |
273 }); | 290 }); |
274 return; | 291 return; |
275 } | 292 } |
276 | 293 |
277 callback(); | 294 callback(); |
278 }; | 295 }; |
279 | 296 |
280 /** | 297 /** |
281 * Executes an internal task. | 298 * Executes an internal task. |
| 299 * |
282 * @param {string} id The short task id. | 300 * @param {string} id The short task id. |
283 * @param {Array.<string>} urls The urls to execute on. | 301 * @param {Array.<string>} urls The urls to execute on. |
284 * @private | 302 * @private |
285 */ | 303 */ |
286 FileTasks.prototype.executeInternalTask_ = function(id, urls) { | 304 FileTasks.prototype.executeInternalTask_ = function(id, urls) { |
287 var fm = this.fileManager_; | 305 var fm = this.fileManager_; |
288 | 306 |
289 if (id == 'play') { | 307 if (id == 'play') { |
290 var position = 0; | 308 var position = 0; |
291 if (urls.length == 1) { | 309 if (urls.length == 1) { |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
337 chrome.fileBrowserPrivate.viewFiles(urls, id, function(success) { | 355 chrome.fileBrowserPrivate.viewFiles(urls, id, function(success) { |
338 if (!success) | 356 if (!success) |
339 console.error('chrome.fileBrowserPrivate.viewFiles failed', urls); | 357 console.error('chrome.fileBrowserPrivate.viewFiles failed', urls); |
340 }); | 358 }); |
341 return; | 359 return; |
342 } | 360 } |
343 }; | 361 }; |
344 | 362 |
345 /** | 363 /** |
346 * Mounts archives. | 364 * Mounts archives. |
| 365 * |
347 * @param {Array.<string>} urls Mount file urls list. | 366 * @param {Array.<string>} urls Mount file urls list. |
348 * @private | 367 * @private |
349 */ | 368 */ |
350 FileTasks.prototype.mountArchives_ = function(urls) { | 369 FileTasks.prototype.mountArchives_ = function(urls) { |
351 var fm = this.fileManager_; | 370 var fm = this.fileManager_; |
352 | 371 |
353 var tracker = fm.directoryModel_.createDirectoryChangeTracker(); | 372 var tracker = fm.directoryModel_.createDirectoryChangeTracker(); |
354 tracker.start(); | 373 tracker.start(); |
355 | 374 |
356 fm.resolveSelectResults_(urls, function(urls) { | 375 fm.resolveSelectResults_(urls, function(urls) { |
357 for (var index = 0; index < urls.length; ++index) { | 376 for (var index = 0; index < urls.length; ++index) { |
358 fm.volumeManager_.mountArchive(urls[index], function(mountPath) { | 377 fm.volumeManager_.mountArchive(urls[index], function(mountPath) { |
359 console.log('Mounted at: ', mountPath); | 378 console.log('Mounted at: ', mountPath); |
360 tracker.stop(); | 379 tracker.stop(); |
361 if (!tracker.hasChanged) | 380 if (!tracker.hasChanged) |
362 fm.directoryModel_.changeDirectory(mountPath); | 381 fm.directoryModel_.changeDirectory(mountPath); |
363 }, function(url, error) { | 382 }, function(url, error) { |
364 var path = util.extractFilePath(url); | 383 var path = util.extractFilePath(url); |
365 tracker.stop(); | 384 tracker.stop(); |
366 var namePos = path.lastIndexOf('/'); | 385 var namePos = path.lastIndexOf('/'); |
367 fm.alert.show(strf('ARCHIVE_MOUNT_FAILED', | 386 fm.alert.show(strf('ARCHIVE_MOUNT_FAILED', |
368 path.substr(namePos + 1), error)); | 387 path.substr(namePos + 1), error)); |
369 }.bind(null, urls[index])); | 388 }.bind(null, urls[index])); |
370 } | 389 } |
371 }); | 390 }); |
372 }; | 391 }; |
373 | 392 |
374 /** | 393 /** |
375 * Open the Gallery. | 394 * Open the Gallery. |
| 395 * |
376 * @param {Array.<string>} urls List of selected urls. | 396 * @param {Array.<string>} urls List of selected urls. |
377 */ | 397 */ |
378 FileTasks.prototype.openGallery = function(urls) { | 398 FileTasks.prototype.openGallery = function(urls) { |
379 var fm = this.fileManager_; | 399 var fm = this.fileManager_; |
380 | 400 |
381 var allUrls = | 401 var allUrls = |
382 fm.getAllUrlsInCurrentDirectory().filter(FileType.isImageOrVideo); | 402 fm.getAllUrlsInCurrentDirectory().filter(FileType.isImageOrVideo); |
383 | 403 |
384 var galleryFrame = fm.document_.createElement('iframe'); | 404 var galleryFrame = fm.document_.createElement('iframe'); |
385 galleryFrame.className = 'overlay-pane'; | 405 galleryFrame.className = 'overlay-pane'; |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
443 }; | 463 }; |
444 galleryFrame.contentWindow.Gallery.open(context, allUrls, urls); | 464 galleryFrame.contentWindow.Gallery.open(context, allUrls, urls); |
445 }.bind(this); | 465 }.bind(this); |
446 | 466 |
447 galleryFrame.src = 'gallery.html'; | 467 galleryFrame.src = 'gallery.html'; |
448 fm.openFilePopup_(galleryFrame, fm.updateTitle_.bind(fm)); | 468 fm.openFilePopup_(galleryFrame, fm.updateTitle_.bind(fm)); |
449 }; | 469 }; |
450 | 470 |
451 /** | 471 /** |
452 * Displays the list of tasks in a task picker combobutton. | 472 * Displays the list of tasks in a task picker combobutton. |
| 473 * |
453 * @param {cr.ui.ComboButton} combobutton The task picker element. | 474 * @param {cr.ui.ComboButton} combobutton The task picker element. |
454 * @private | 475 * @private |
455 */ | 476 */ |
456 FileTasks.prototype.display_ = function(combobutton) { | 477 FileTasks.prototype.display_ = function(combobutton) { |
457 if (this.tasks_.length == 0) { | 478 if (this.tasks_.length == 0) { |
458 combobutton.hidden = true; | 479 combobutton.hidden = true; |
459 return; | 480 return; |
460 } | 481 } |
461 | 482 |
462 combobutton.clear(); | 483 combobutton.clear(); |
(...skipping 13 matching lines...) Expand all Loading... |
476 | 497 |
477 combobutton.addSeparator(); | 498 combobutton.addSeparator(); |
478 combobutton.addDropDownItem({ | 499 combobutton.addDropDownItem({ |
479 label: loadTimeData.getString('CHANGE_DEFAULT_MENU_ITEM') | 500 label: loadTimeData.getString('CHANGE_DEFAULT_MENU_ITEM') |
480 }); | 501 }); |
481 } | 502 } |
482 }; | 503 }; |
483 | 504 |
484 /** | 505 /** |
485 * Creates sorted array of available task descriptions such as title and icon. | 506 * Creates sorted array of available task descriptions such as title and icon. |
| 507 * |
486 * @return {Array} created array can be used to feed combobox, menus and so on. | 508 * @return {Array} created array can be used to feed combobox, menus and so on. |
487 * @private | 509 * @private |
488 */ | 510 */ |
489 FileTasks.prototype.createItems_ = function() { | 511 FileTasks.prototype.createItems_ = function() { |
490 var items = []; | 512 var items = []; |
491 var title = this.defaultTask_.title + ' ' + | 513 var title = this.defaultTask_.title + ' ' + |
492 loadTimeData.getString('DEFAULT_ACTION_LABEL'); | 514 loadTimeData.getString('DEFAULT_ACTION_LABEL'); |
493 items.push(this.createCombobuttonItem_(this.defaultTask_, title, true)); | 515 items.push(this.createCombobuttonItem_(this.defaultTask_, title, true)); |
494 | 516 |
495 for (var index = 0; index < this.tasks_.length; index++) { | 517 for (var index = 0; index < this.tasks_.length; index++) { |
496 var task = this.tasks_[index]; | 518 var task = this.tasks_[index]; |
497 if (task != this.defaultTask_) | 519 if (task != this.defaultTask_) |
498 items.push(this.createCombobuttonItem_(task)); | 520 items.push(this.createCombobuttonItem_(task)); |
499 } | 521 } |
500 | 522 |
501 items.sort(function(a, b) { | 523 items.sort(function(a, b) { |
502 return a.label.localeCompare(b.label); | 524 return a.label.localeCompare(b.label); |
503 }); | 525 }); |
504 | 526 |
505 return items; | 527 return items; |
506 }; | 528 }; |
507 | 529 |
508 /** | 530 /** |
509 * Updates context menu with default item. | 531 * Updates context menu with default item. |
510 * @private | 532 * @private |
511 */ | 533 */ |
| 534 |
512 FileTasks.prototype.updateMenuItem_ = function() { | 535 FileTasks.prototype.updateMenuItem_ = function() { |
513 this.fileManager_.updateContextMenuActionItems(this.defaultTask_, | 536 this.fileManager_.updateContextMenuActionItems(this.defaultTask_, |
514 this.tasks_.length > 1); | 537 this.tasks_.length > 1); |
515 }; | 538 }; |
516 | 539 |
517 /** | 540 /** |
518 * Creates combobutton item based on task. | 541 * Creates combobutton item based on task. |
| 542 * |
519 * @param {Object} task Task to convert. | 543 * @param {Object} task Task to convert. |
520 * @param {string=} opt_title Title. | 544 * @param {string=} opt_title Title. |
521 * @param {boolean} opt_bold Make a menu item bold. | 545 * @param {boolean} opt_bold Make a menu item bold. |
522 * @return {Object} Item appendable to combobutton drop-down list. | 546 * @return {Object} Item appendable to combobutton drop-down list. |
523 * @private | 547 * @private |
524 */ | 548 */ |
525 FileTasks.prototype.createCombobuttonItem_ = function(task, opt_title, | 549 FileTasks.prototype.createCombobuttonItem_ = function(task, opt_title, |
526 opt_bold) { | 550 opt_bold) { |
527 return { | 551 return { |
528 label: opt_title || task.title, | 552 label: opt_title || task.title, |
529 iconUrl: task.iconUrl, | 553 iconUrl: task.iconUrl, |
530 iconType: task.iconType, | 554 iconType: task.iconType, |
531 task: task, | 555 task: task, |
532 bold: opt_bold || false | 556 bold: opt_bold || false |
533 }; | 557 }; |
534 }; | 558 }; |
535 | 559 |
536 | 560 |
537 /** | 561 /** |
538 * Decorates a FileTasks method, so it will be actually executed after the tasks | 562 * Decorates a FileTasks method, so it will be actually executed after the tasks |
539 * are available. | 563 * are available. |
540 * This decorator expects an implementation called |method + '_'|. | 564 * This decorator expects an implementation called |method + '_'|. |
| 565 * |
541 * @param {string} method The method name. | 566 * @param {string} method The method name. |
542 */ | 567 */ |
543 FileTasks.decorate = function(method) { | 568 FileTasks.decorate = function(method) { |
544 var privateMethod = method + '_'; | 569 var privateMethod = method + '_'; |
545 FileTasks.prototype[method] = function() { | 570 FileTasks.prototype[method] = function() { |
546 if (this.tasks_) { | 571 if (this.tasks_) { |
547 this[privateMethod].apply(this, arguments); | 572 this[privateMethod].apply(this, arguments); |
548 } else { | 573 } else { |
549 this.pendingInvocations_.push([privateMethod, arguments]); | 574 this.pendingInvocations_.push([privateMethod, arguments]); |
550 } | 575 } |
(...skipping 23 matching lines...) Expand all Loading... |
574 title, | 599 title, |
575 message, | 600 message, |
576 items, defaultIdx, | 601 items, defaultIdx, |
577 onSuccess); | 602 onSuccess); |
578 }; | 603 }; |
579 | 604 |
580 FileTasks.decorate('display'); | 605 FileTasks.decorate('display'); |
581 FileTasks.decorate('updateMenuItem'); | 606 FileTasks.decorate('updateMenuItem'); |
582 FileTasks.decorate('execute'); | 607 FileTasks.decorate('execute'); |
583 FileTasks.decorate('executeDefault'); | 608 FileTasks.decorate('executeDefault'); |
OLD | NEW |