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

Side by Side Diff: ui/file_manager/file_manager/foreground/js/import_controller.js

Issue 880303002: Eliminate last vestigages of the command system design. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Merge w/ master. Created 5 years, 10 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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 // Namespace 5 // Namespace
6 var importer = importer || {}; 6 var importer = importer || {};
7 7
8 /** @enum {string} */ 8 /** @enum {string} */
9 importer.ResponseId = { 9 importer.ResponseId = {
10 HIDDEN: 'hidden', 10 HIDDEN: 'hidden',
(...skipping 18 matching lines...) Expand all
29 * behalf of Cloud Import. 29 * behalf of Cloud Import.
30 * 30 *
31 * @constructor 31 * @constructor
32 * @struct 32 * @struct
33 * 33 *
34 * @param {!importer.ControllerEnvironment} environment The class providing 34 * @param {!importer.ControllerEnvironment} environment The class providing
35 * access to runtime environmental information, like the current directory, 35 * access to runtime environmental information, like the current directory,
36 * volume lookup and so-on. 36 * volume lookup and so-on.
37 * @param {!importer.MediaScanner} scanner 37 * @param {!importer.MediaScanner} scanner
38 * @param {!importer.ImportRunner} importRunner 38 * @param {!importer.ImportRunner} importRunner
39 * @param {function()} commandUpdateHandler 39 * @param {!importer.CommandWidget} commandWidget
40 */ 40 */
41 importer.ImportController = 41 importer.ImportController =
42 function(environment, scanner, importRunner, commandUpdateHandler) { 42 function(environment, scanner, importRunner, commandWidget) {
43 43
44 /** @private {!importer.ControllerEnvironment} */ 44 /** @private {!importer.ControllerEnvironment} */
45 this.environment_ = environment; 45 this.environment_ = environment;
46 46
47 /** @private {!importer.ImportRunner} */ 47 /** @private {!importer.ImportRunner} */
48 this.importRunner_ = importRunner; 48 this.importRunner_ = importRunner;
49 49
50 /** @private {!importer.MediaScanner} */ 50 /** @private {!importer.MediaScanner} */
51 this.scanner_ = scanner; 51 this.scanner_ = scanner;
52 52
53 /** @private {function()} */ 53 /** @private {!importer.CommandWidget} */
54 this.updateCommands_ = commandUpdateHandler; 54 this.commandWidget_ = commandWidget;
55 55
56 /** 56 /**
57 * A cache of scans by volumeId, directory URL. 57 * A cache of scans by volumeId, directory URL.
58 * Currently only scans of directories are cached. 58 * Currently only scans of directories are cached.
59 * @private {!Object.<string, !Object.<string, !importer.ScanResult>>} 59 * @private {!Object.<string, !Object.<string, !importer.ScanResult>>}
60 */ 60 */
61 this.cachedScans_ = {}; 61 this.cachedScans_ = {};
62 62
63 var listener = this.onScanEvent_.bind(this); 63 var listener = this.onScanEvent_.bind(this);
64 this.scanner_.addObserver(listener); 64 this.scanner_.addObserver(listener);
65 // Remove the observer when the foreground window is closed. 65 // Remove the observer when the foreground window is closed.
66 window.addEventListener('pagehide', function() { 66 window.addEventListener(
67 this.scanner_.removeObserver(listener); 67 'pagehide',
68 }.bind(this)); 68 function() {
69 this.scanner_.removeObserver(listener);
70 }.bind(this));
71
69 this.environment_.addVolumeUnmountListener( 72 this.environment_.addVolumeUnmountListener(
70 this.onVolumeUnmounted_.bind(this)); 73 this.onVolumeUnmounted_.bind(this));
74
71 this.environment_.addDirectoryChangedListener( 75 this.environment_.addDirectoryChangedListener(
72 this.onDirectoryChanged_.bind(this)); 76 this.onDirectoryChanged_.bind(this));
77
78 this.commandWidget_.addExecuteListener(
79 this.execute.bind(this));
73 }; 80 };
74 81
75 /** 82 /**
76 * @param {!importer.ScanEvent} event Command event. 83 * @param {!importer.ScanEvent} event Command event.
77 * @param {importer.ScanResult} result 84 * @param {importer.ScanResult} result
78 * 85 *
79 * @private 86 * @private
80 */ 87 */
81 importer.ImportController.prototype.onScanEvent_ = function(event, result) { 88 importer.ImportController.prototype.onScanEvent_ = function(event, result) {
82 if (event === importer.ScanEvent.INVALIDATED) { 89 if (event === importer.ScanEvent.INVALIDATED) {
83 for (var key in this.cachedScans_) { 90 for (var key in this.cachedScans_) {
84 for (var url in this.cachedScans_[key]) { 91 for (var url in this.cachedScans_[key]) {
85 if (this.cachedScans_[key][url].isInvalidated()) { 92 if (this.cachedScans_[key][url].isInvalidated()) {
86 delete this.cachedScans_[key][url]; 93 delete this.cachedScans_[key][url];
87 } 94 }
88 } 95 }
89 } 96 }
90 } 97 }
91 if (event === importer.ScanEvent.FINALIZED || 98 if (event === importer.ScanEvent.FINALIZED ||
92 event === importer.ScanEvent.INVALIDATED) { 99 event === importer.ScanEvent.INVALIDATED) {
93 this.updateCommands_(); 100 this.pushUpdate_();
94 } 101 }
95 }; 102 };
96 103
97 /** 104 /**
98 * Executes import against the current directory. Should only 105 * Executes import against the current directory. Should only
99 * be called when the current directory has been validated 106 * be called when the current directory has been validated
100 * by calling "update" on this class. 107 * by calling "update" on this class.
101 */ 108 */
102 importer.ImportController.prototype.execute = function() { 109 importer.ImportController.prototype.execute = function() {
103 metrics.recordEnum('CloudImport.UserAction', 'IMPORT_INITIATED'); 110 metrics.recordEnum('CloudImport.UserAction', 'IMPORT_INITIATED');
104 var result = this.getScanForImport_(); 111 var result = this.getScanForImport_();
105 var importTask = this.importRunner_.importFromScanResult(result); 112 var importTask = this.importRunner_.importFromScanResult(result);
106 }; 113 };
107 114
108 /** 115 /**
109 * Called by the 'cloud-import' command when it wants an update 116 * Push an update to the command widget.
110 * on the command state. 117 * @private
118 */
119 importer.ImportController.prototype.pushUpdate_ = function() {
120 this.commandWidget_.update(this.getCommandUpdate());
121 };
122
123 /**
124 * Returns an update describing the state of the CommandWidget.
111 * 125 *
112 * @return {!importer.CommandUpdate} response 126 * @return {!importer.CommandUpdate} response
113 */ 127 */
114 importer.ImportController.prototype.getCommandUpdate = function() { 128 importer.ImportController.prototype.getCommandUpdate = function() {
115 // If there is no Google Drive mount, Drive may be disabled 129 // If there is no Google Drive mount, Drive may be disabled
116 // or the machine may be running in guest mode. 130 // or the machine may be running in guest mode.
117 if (this.environment_.isGoogleDriveMounted()) { 131 if (this.environment_.isGoogleDriveMounted()) {
118 var entries = this.environment_.getSelection(); 132 var entries = this.environment_.getSelection();
119 133
120 // Enabled if user has a selection and it consists entirely of files 134 // Enabled if user has a selection and it consists entirely of files
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
257 271
258 /** 272 /**
259 * @param {string} volumeId 273 * @param {string} volumeId
260 * @private 274 * @private
261 */ 275 */
262 importer.ImportController.prototype.onVolumeUnmounted_ = function(volumeId) { 276 importer.ImportController.prototype.onVolumeUnmounted_ = function(volumeId) {
263 // Forget all scans related to the unmounted volume volume. 277 // Forget all scans related to the unmounted volume volume.
264 if (this.cachedScans_.hasOwnProperty(volumeId)) { 278 if (this.cachedScans_.hasOwnProperty(volumeId)) {
265 delete this.cachedScans_[volumeId]; 279 delete this.cachedScans_[volumeId];
266 } 280 }
281 this.pushUpdate_();
282 };
283
284 /** @private */
285 importer.ImportController.prototype.onDirectoryChanged_ = function() {
286 this.pushUpdate_();
267 }; 287 };
268 288
269 /** 289 /**
270 * @param {string} volumeId
271 * @private
272 */
273 importer.ImportController.prototype.onDirectoryChanged_ = function() {
274 this.updateCommands_();
275 };
276
277 /**
278 * Interface abstracting away the concrete file manager available 290 * Interface abstracting away the concrete file manager available
279 * to commands. By hiding file manager we make it easy to test 291 * to commands. By hiding file manager we make it easy to test
280 * ImportController. 292 * ImportController.
281 * 293 *
282 * @interface 294 * @interface
283 * @extends {VolumeManagerCommon.VolumeInfoProvider} 295 * @extends {VolumeManagerCommon.VolumeInfoProvider}
284 */ 296 */
285 importer.ControllerEnvironment = function() {}; 297 importer.ControllerEnvironment = function() {};
286 298
287 /** 299 /**
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
391 // TODO(smckay): remove listeners when the page is torn down. 403 // TODO(smckay): remove listeners when the page is torn down.
392 this.fileManager_.directoryModel.addEventListener( 404 this.fileManager_.directoryModel.addEventListener(
393 'directory-changed', 405 'directory-changed',
394 listener); 406 listener);
395 }; 407 };
396 408
397 /** 409 /**
398 * Class that adapts from the new non-command button to the old 410 * Class that adapts from the new non-command button to the old
399 * command style interface. 411 * command style interface.
400 * 412 *
401 * <p>NOTE: This adapter is a stop gap bridge between the old-style 413 * @interface
402 * Command button and our new do-it-yourself toolbar button. We used 414 */
403 * an adapter to minimize changes to RuntimeImportController while other 415 importer.CommandWidget = function() {};
404 * people are working on that file. Once the dust settles we can make 416
405 * more transformative changes. 417 /**
418 * Install a listener that get's called when the user wants to initiate
419 * import.
420 *
421 * @param {function()} listener
422 */
423 importer.CommandWidget.prototype.addExecuteListener;
424
425 /**
426 * @param {!importer.CommandUpdate} update
427 */
428 importer.CommandWidget.prototype.update;
429
430 /**
431 * Runtime implementation of CommandWidget.
406 * 432 *
407 * @constructor 433 * @constructor
434 * @implements {importer.CommandWidget}
408 * @struct 435 * @struct
409 *
410 * @param {!FileManager} fileManager
411 */ 436 */
412 importer.ButtonCommandAdapter = function(fileManager) { 437 importer.RuntimeCommandWidget = function() {
413 438 /** @private {Element} */
414 /** @param {!FileManager} */
415 this.fileManager_ = fileManager;
416
417 /** @param {Element} */
418 this.buttonElement_ = document.querySelector('#cloud-import-button'); 439 this.buttonElement_ = document.querySelector('#cloud-import-button');
419 440
420 this.buttonElement_.onclick = this.execute_.bind(this); 441 this.buttonElement_.onclick = this.notifyExecuteListener_.bind(this);
421 442
422 /** @param {Element} */ 443 /** @private {Element} */
423 this.iconElement_ = document.querySelector('#cloud-import-button core-icon'); 444 this.iconElement_ = document.querySelector('#cloud-import-button core-icon');
445
446 /** @private {function()} */
447 this.listener_;
448 };
449
450 /** @override */
451 importer.RuntimeCommandWidget.prototype.addExecuteListener =
452 function(listener) {
453 console.assert(!this.listener_);
454 this.listener_ = listener;
424 }; 455 };
425 456
426 /** @private */ 457 /** @private */
427 importer.ButtonCommandAdapter.prototype.execute_ = function() { 458 importer.RuntimeCommandWidget.prototype.notifyExecuteListener_ = function() {
428 this.fileManager_.importController.execute(); 459 console.assert(!!this.listener_);
460 this.listener_();
429 }; 461 };
430 462
431 /** 463 /** @override */
432 * @param {!Event} event Command event. 464 importer.RuntimeCommandWidget.prototype.update = function(update) {
433 * @param {!FileManager} fileManager
434 */
435 importer.ButtonCommandAdapter.prototype.update = function() {
436 if (this.fileManager_.importController) {
437 var update = fileManager.importController.getCommandUpdate();
438 this.buttonElement_.setAttribute('title', update.label); 465 this.buttonElement_.setAttribute('title', update.label);
439 this.buttonElement_.disabled = !update.executable; 466 this.buttonElement_.disabled = !update.executable;
440 this.buttonElement_.style.display = update.visible ? 'block' : 'none'; 467 this.buttonElement_.style.display = update.visible ? 'block' : 'none';
441 this.iconElement_.setAttribute('icon', update.coreIcon); 468 this.iconElement_.setAttribute('icon', update.coreIcon);
442 } else {
443 this.buttonElement_.setAttribute('display', 'none');
444 this.iconElement_.setAttribute('icon', 'cloud-off');
445 }
446 }; 469 };
470
mtomasz 2015/01/28 22:54:03 nit: remove \n
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698