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

Side by Side Diff: chrome/browser/resources/file_manager/foreground/js/file_manager_commands.js

Issue 247123002: Move Files.app files to ui/file_manager (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix the test failure on non-chromeos Created 6 years, 8 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 | Annotate | Revision Log
OLDNEW
(Empty)
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 'use strict';
6
7 /**
8 * TODO(dzvorygin): Here we use this hack, since 'hidden' is standard
9 * attribute and we can't use it's setter as usual.
10 * @param {boolean} value New value of hidden property.
11 */
12 cr.ui.Command.prototype.setHidden = function(value) {
13 this.__lookupSetter__('hidden').call(this, value);
14 };
15
16 /**
17 * A command.
18 * @interface
19 */
20 var Command = function() {};
21
22 /**
23 * Handles the execute event.
24 * @param {Event} event Command event.
25 * @param {FileManager} fileManager FileManager.
26 */
27 Command.prototype.execute = function(event, fileManager) {};
28
29 /**
30 * Handles the can execute event.
31 * @param {Event} event Can execute event.
32 * @param {FileManager} fileManager FileManager.
33 */
34 Command.prototype.canExecute = function(event, fileManager) {};
35
36 /**
37 * Utility for commands.
38 */
39 var CommandUtil = {};
40
41 /**
42 * Extracts entry on which command event was dispatched.
43 *
44 * @param {DirectoryTree|DirectoryItem|NavigationList|HTMLLIElement|cr.ui.List}
45 * element Directory to extract a path from.
46 * @return {Entry} Entry of the found node.
47 */
48 CommandUtil.getCommandEntry = function(element) {
49 if (element instanceof NavigationList) {
50 // element is a NavigationList.
51 /** @type {NavigationModelItem} */
52 var item = element.selectedItem;
53 return element.selectedItem &&
54 CommandUtil.getEntryFromNavigationModelItem_(item);
55 } else if (element instanceof NavigationListItem) {
56 // element is a subitem of NavigationList.
57 /** @type {NavigationList} */
58 var navigationList = element.parentElement;
59 var index = navigationList.getIndexOfListItem(element);
60 /** @type {NavigationModelItem} */
61 var item = (index != -1) ? navigationList.dataModel.item(index) : null;
62 return item && CommandUtil.getEntryFromNavigationModelItem_(item);
63 } else if (element instanceof DirectoryTree) {
64 // element is a DirectoryTree.
65 return element.selectedItem.entry;
66 } else if (element instanceof DirectoryItem) {
67 // element is a sub item in DirectoryTree.
68 return element.entry;
69 } else if (element instanceof cr.ui.List) {
70 // element is a normal List (eg. the file list on the right panel).
71 var entry = element.selectedItem;
72 // Check if it is Entry or not by checking for toURL().
73 return entry && 'toURL' in entry ? entry : null;
74 } else {
75 console.warn('Unsupported element');
76 return null;
77 }
78 };
79
80 /**
81 * Obtains an entry from the give navigation model item.
82 * @param {NavigationModelItem} item Navigation modle item.
83 * @return {Entry} Related entry.
84 * @private
85 */
86 CommandUtil.getEntryFromNavigationModelItem_ = function(item) {
87 if (item.isVolume)
88 return item.volumeInfo.displayRoot;
89 if (item.isShortcut)
90 return item.entry;
91 return null;
92 };
93
94 /**
95 * Checks if command can be executed on drive.
96 * @param {Event} event Command event to mark.
97 * @param {FileManager} fileManager FileManager to use.
98 */
99 CommandUtil.canExecuteEnabledOnDriveOnly = function(event, fileManager) {
100 event.canExecute = fileManager.isOnDrive();
101 };
102
103 /**
104 * Sets the command as visible only when the current volume is drive and it's
105 * running as a normal app, not as a modal dialog.
106 * @param {Event} event Command event to mark.
107 * @param {FileManager} fileManager FileManager to use.
108 */
109 CommandUtil.canExecuteVisibleOnDriveInNormalAppModeOnly =
110 function(event, fileManager) {
111 var enabled = fileManager.isOnDrive() &&
112 !DialogType.isModal(fileManager.dialogType);
113 event.canExecute = enabled;
114 event.command.setHidden(!enabled);
115 };
116
117 /**
118 * Sets as the command as always enabled.
119 * @param {Event} event Command event to mark.
120 */
121 CommandUtil.canExecuteAlways = function(event) {
122 event.canExecute = true;
123 };
124
125 /**
126 * Returns a single selected/passed entry or null.
127 * @param {Event} event Command event.
128 * @param {FileManager} fileManager FileManager to use.
129 * @return {FileEntry} The entry or null.
130 */
131 CommandUtil.getSingleEntry = function(event, fileManager) {
132 if (event.target.entry) {
133 return event.target.entry;
134 }
135 var selection = fileManager.getSelection();
136 if (selection.totalCount == 1) {
137 return selection.entries[0];
138 }
139 return null;
140 };
141
142 /**
143 * Obtains target entries that can be pinned from the selection.
144 * If directories are included in the selection, it just returns an empty
145 * array to avoid confusing because pinning directory is not supported
146 * currently.
147 *
148 * @return {Array.<Entry>} Target entries.
149 */
150 CommandUtil.getPinTargetEntries = function() {
151 var hasDirectory = false;
152 var results = fileManager.getSelection().entries.filter(function(entry) {
153 hasDirectory = hasDirectory || entry.isDirectory;
154 if (!entry || hasDirectory)
155 return false;
156 var metadata = fileManager.metadataCache_.getCached(entry, 'drive');
157 if (!metadata || metadata.hosted)
158 return false;
159 entry.pinned = metadata.pinned;
160 return true;
161 });
162 return hasDirectory ? [] : results;
163 };
164
165 /**
166 * Sets the default handler for the commandId and prevents handling
167 * the keydown events for this command. Not doing that breaks relationship
168 * of original keyboard event and the command. WebKit would handle it
169 * differently in some cases.
170 * @param {Node} node to register command handler on.
171 * @param {string} commandId Command id to respond to.
172 */
173 CommandUtil.forceDefaultHandler = function(node, commandId) {
174 var doc = node.ownerDocument;
175 var command = doc.querySelector('command[id="' + commandId + '"]');
176 node.addEventListener('keydown', function(e) {
177 if (command.matchesEvent(e)) {
178 // Prevent cr.ui.CommandManager of handling it and leave it
179 // for the default handler.
180 e.stopPropagation();
181 }
182 });
183 node.addEventListener('command', function(event) {
184 if (event.command.id !== commandId)
185 return;
186 document.execCommand(event.command.id);
187 event.cancelBubble = true;
188 });
189 node.addEventListener('canExecute', function(event) {
190 if (event.command.id === commandId)
191 event.canExecute = document.queryCommandEnabled(event.command.id);
192 });
193 };
194
195 /**
196 * Default command.
197 * @type {Command}
198 */
199 CommandUtil.defaultCommand = {
200 execute: function(event, fileManager) {
201 fileManager.document.execCommand(event.command.id);
202 },
203 canExecute: function(event, fileManager) {
204 event.canExecute = fileManager.document.queryCommandEnabled(
205 event.command.id);
206 }
207 };
208
209 /**
210 * Creates the volume switch command with index.
211 * @param {number} index Volume index from 1 to 9.
212 * @return {Command} Volume switch command.
213 */
214 CommandUtil.createVolumeSwitchCommand = function(index) {
215 return {
216 execute: function(event, fileManager) {
217 fileManager.navigationList.selectByIndex(index - 1);
218 },
219 canExecute: function(event, fileManager) {
220 event.canExecute = index > 0 &&
221 index <= fileManager.navigationList.dataModel.length;
222 }
223 };
224 };
225
226 /**
227 * Handle of the command events.
228 * @param {FileManager} fileManager FileManager.
229 * @constructor
230 */
231 var CommandHandler = function(fileManager) {
232 /**
233 * FileManager.
234 * @type {FileManager}
235 * @private
236 */
237 this.fileManager_ = fileManager;
238
239 /**
240 * Command elements.
241 * @type {Object.<string, cr.ui.Command>}
242 * @private
243 */
244 this.commands_ = {};
245
246 Object.seal(this);
247
248 // Decorate command tags in the document.
249 var commands = fileManager.document.querySelectorAll('command');
250 for (var i = 0; i < commands.length; i++) {
251 cr.ui.Command.decorate(commands[i]);
252 this.commands_[commands[i].id] = commands[i];
253 }
254
255 // Register events.
256 fileManager.document.addEventListener('command', this.onCommand_.bind(this));
257 fileManager.document.addEventListener('canExecute',
258 this.onCanExecute_.bind(this));
259 };
260
261 /**
262 * Updates the availability of all commands.
263 */
264 CommandHandler.prototype.updateAvailability = function() {
265 for (var id in this.commands_) {
266 this.commands_[id].canExecuteChange();
267 }
268 };
269
270 /**
271 * Checks if the handler should ignore the current event, eg. since there is
272 * a popup dialog currently opened.
273 *
274 * @return {boolean} True if the event should be ignored, false otherwise.
275 * @private
276 */
277 CommandHandler.prototype.shouldIgnoreEvents_ = function() {
278 // Do not handle commands, when a dialog is shown.
279 if (this.fileManager_.document.querySelector('.cr-dialog-container.shown'))
280 return true;
281
282 return false; // Do not ignore.
283 };
284
285 /**
286 * Handles command events.
287 * @param {Event} event Command event.
288 * @private
289 */
290 CommandHandler.prototype.onCommand_ = function(event) {
291 if (this.shouldIgnoreEvents_())
292 return;
293 var handler = CommandHandler.COMMANDS_[event.command.id];
294 handler.execute.call(this, event, this.fileManager_);
295 };
296
297 /**
298 * Handles canExecute events.
299 * @param {Event} event Can execute event.
300 * @private
301 */
302 CommandHandler.prototype.onCanExecute_ = function(event) {
303 if (this.shouldIgnoreEvents_())
304 return;
305 var handler = CommandHandler.COMMANDS_[event.command.id];
306 handler.canExecute.call(this, event, this.fileManager_);
307 };
308
309 /**
310 * Commands.
311 * @type {Object.<string, Command>}
312 * @const
313 * @private
314 */
315 CommandHandler.COMMANDS_ = {};
316
317 /**
318 * Unmounts external drive.
319 * @type {Command}
320 */
321 CommandHandler.COMMANDS_['unmount'] = {
322 /**
323 * @param {Event} event Command event.
324 * @param {FileManager} fileManager The file manager instance.
325 */
326 execute: function(event, fileManager) {
327 var root = CommandUtil.getCommandEntry(event.target);
328 if (!root)
329 return;
330 var errorCallback = function() {
331 fileManager.alert.showHtml('', str('UNMOUNT_FAILED'));
332 };
333 var volumeInfo = fileManager.volumeManager.getVolumeInfo(root);
334 if (!volumeInfo) {
335 errorCallback();
336 return;
337 }
338 fileManager.volumeManager_.unmount(
339 volumeInfo,
340 function() {},
341 errorCallback);
342 },
343 /**
344 * @param {Event} event Command event.
345 */
346 canExecute: function(event, fileManager) {
347 var root = CommandUtil.getCommandEntry(event.target);
348 if (!root)
349 return;
350 var locationInfo = this.fileManager_.volumeManager.getLocationInfo(root);
351 var rootType =
352 locationInfo && locationInfo.isRootEntry && locationInfo.rootType;
353
354 event.canExecute = (rootType == RootType.ARCHIVE ||
355 rootType == RootType.REMOVABLE);
356 event.command.setHidden(!event.canExecute);
357 event.command.label = rootType == RootType.ARCHIVE ?
358 str('CLOSE_ARCHIVE_BUTTON_LABEL') :
359 str('UNMOUNT_DEVICE_BUTTON_LABEL');
360 }
361 };
362
363 /**
364 * Formats external drive.
365 * @type {Command}
366 */
367 CommandHandler.COMMANDS_['format'] = {
368 /**
369 * @param {Event} event Command event.
370 * @param {FileManager} fileManager The file manager instance.
371 */
372 execute: function(event, fileManager) {
373 var directoryModel = fileManager.directoryModel;
374 var root = CommandUtil.getCommandEntry(event.target);
375 // If an entry is not found from the event target, use the current
376 // directory. This can happen for the format button for unsupported and
377 // unrecognized volumes.
378 if (!root)
379 root = directoryModel.getCurrentDirEntry();
380
381 var volumeInfo = fileManager.volumeManager.getVolumeInfo(root);
382 if (volumeInfo) {
383 fileManager.confirm.show(
384 loadTimeData.getString('FORMATTING_WARNING'),
385 chrome.fileBrowserPrivate.formatVolume.bind(null,
386 volumeInfo.volumeId));
387 }
388 },
389 /**
390 * @param {Event} event Command event.
391 * @param {FileManager} fileManager The file manager instance.
392 */
393 canExecute: function(event, fileManager) {
394 var directoryModel = fileManager.directoryModel;
395 var root = CommandUtil.getCommandEntry(event.target);
396 // See the comment in execute() for why doing this.
397 if (!root)
398 root = directoryModel.getCurrentDirEntry();
399 var location = root && fileManager.volumeManager.getLocationInfo(root);
400 var removable = location && location.rootType === RootType.REMOVABLE;
401 // Don't check if the volume is read-only. Unformatted volume is considered
402 // read-only per VolumeInfo.isReadOnly, but can be formatted. An error will
403 // be raised if formatting failed anyway.
404 event.canExecute = removable;
405 event.command.setHidden(!removable);
406 }
407 };
408
409 /**
410 * Initiates new folder creation.
411 * @type {Command}
412 */
413 CommandHandler.COMMANDS_['new-folder'] = {
414 execute: function(event, fileManager) {
415 fileManager.createNewFolder();
416 },
417 canExecute: function(event, fileManager) {
418 var directoryModel = fileManager.directoryModel;
419 event.canExecute = !fileManager.isOnReadonlyDirectory() &&
420 !fileManager.isRenamingInProgress() &&
421 !directoryModel.isSearching() &&
422 !directoryModel.isScanning();
423 }
424 };
425
426 /**
427 * Initiates new window creation.
428 * @type {Command}
429 */
430 CommandHandler.COMMANDS_['new-window'] = {
431 execute: function(event, fileManager) {
432 chrome.fileBrowserPrivate.getProfiles(function(profiles,
433 currentId,
434 displayedId) {
435 fileManager.backgroundPage.launchFileManager({
436 currentDirectoryURL: fileManager.getCurrentDirectoryEntry() &&
437 fileManager.getCurrentDirectoryEntry().toURL(),
438 displayedId: currentId !== displayedId ? displayedId : undefined
439 });
440 });
441 },
442 canExecute: function(event, fileManager) {
443 event.canExecute =
444 fileManager.getCurrentDirectoryEntry() &&
445 (fileManager.dialogType === DialogType.FULL_PAGE);
446 }
447 };
448
449 /**
450 * Deletes selected files.
451 * @type {Command}
452 */
453 CommandHandler.COMMANDS_['delete'] = {
454 execute: function(event, fileManager) {
455 fileManager.deleteSelection();
456 },
457 canExecute: function(event, fileManager) {
458 var selection = fileManager.getSelection();
459 event.canExecute = !fileManager.isOnReadonlyDirectory() &&
460 selection &&
461 selection.totalCount > 0;
462 }
463 };
464
465 /**
466 * Pastes files from clipboard.
467 * @type {Command}
468 */
469 CommandHandler.COMMANDS_['paste'] = {
470 execute: function() {
471 document.execCommand(event.command.id);
472 },
473 canExecute: function(event, fileManager) {
474 var document = fileManager.document;
475 var fileTransferController = fileManager.fileTransferController;
476 event.canExecute = (fileTransferController &&
477 fileTransferController.queryPasteCommandEnabled());
478 }
479 };
480
481 CommandHandler.COMMANDS_['cut'] = CommandUtil.defaultCommand;
482 CommandHandler.COMMANDS_['copy'] = CommandUtil.defaultCommand;
483
484 /**
485 * Initiates file renaming.
486 * @type {Command}
487 */
488 CommandHandler.COMMANDS_['rename'] = {
489 execute: function(event, fileManager) {
490 fileManager.initiateRename();
491 },
492 canExecute: function(event, fileManager) {
493 var selection = fileManager.getSelection();
494 event.canExecute = !fileManager.isRenamingInProgress() &&
495 !fileManager.isOnReadonlyDirectory() &&
496 selection &&
497 selection.totalCount == 1;
498 }
499 };
500
501 /**
502 * Opens drive help.
503 * @type {Command}
504 */
505 CommandHandler.COMMANDS_['volume-help'] = {
506 execute: function(event, fileManager) {
507 if (fileManager.isOnDrive())
508 util.visitURL(str('GOOGLE_DRIVE_HELP_URL'));
509 else
510 util.visitURL(str('FILES_APP_HELP_URL'));
511 },
512 canExecute: function(event, fileManager) {
513 // Hides the help menu in modal dialog mode. It does not make much sense
514 // because after all, users cannot view the help without closing, and
515 // besides that the help page is about Files.app as an app, not about the
516 // dialog mode itself. It can also lead to hard-to-fix bug crbug.com/339089.
517 var hideHelp = DialogType.isModal(fileManager.dialogType);
518 event.canExecute = !hideHelp;
519 event.command.setHidden(hideHelp);
520 fileManager.document_.getElementById('help-separator').hidden = hideHelp;
521 },
522 };
523
524 /**
525 * Opens drive buy-more-space url.
526 * @type {Command}
527 */
528 CommandHandler.COMMANDS_['drive-buy-more-space'] = {
529 execute: function(event, fileManager) {
530 util.visitURL(str('GOOGLE_DRIVE_BUY_STORAGE_URL'));
531 },
532 canExecute: CommandUtil.canExecuteVisibleOnDriveInNormalAppModeOnly
533 };
534
535 /**
536 * Opens drive.google.com.
537 * @type {Command}
538 */
539 CommandHandler.COMMANDS_['drive-go-to-drive'] = {
540 execute: function(event, fileManager) {
541 util.visitURL(str('GOOGLE_DRIVE_ROOT_URL'));
542 },
543 canExecute: CommandUtil.canExecuteVisibleOnDriveInNormalAppModeOnly
544 };
545
546 /**
547 * Displays open with dialog for current selection.
548 * @type {Command}
549 */
550 CommandHandler.COMMANDS_['open-with'] = {
551 execute: function(event, fileManager) {
552 var tasks = fileManager.getSelection().tasks;
553 if (tasks) {
554 tasks.showTaskPicker(fileManager.defaultTaskPicker,
555 str('OPEN_WITH_BUTTON_LABEL'),
556 '',
557 function(task) {
558 tasks.execute(task.taskId);
559 });
560 }
561 },
562 canExecute: function(event, fileManager) {
563 var tasks = fileManager.getSelection().tasks;
564 event.canExecute = tasks && tasks.size() > 1;
565 }
566 };
567
568 /**
569 * Focuses search input box.
570 * @type {Command}
571 */
572 CommandHandler.COMMANDS_['search'] = {
573 execute: function(event, fileManager) {
574 var element = fileManager.document.querySelector('#search-box input');
575 element.focus();
576 element.select();
577 },
578 canExecute: function(event, fileManager) {
579 event.canExecute = !fileManager.isRenamingInProgress();
580 }
581 };
582
583 /**
584 * Activates the n-th volume.
585 * @type {Command}
586 */
587 CommandHandler.COMMANDS_['volume-switch-1'] =
588 CommandUtil.createVolumeSwitchCommand(1);
589 CommandHandler.COMMANDS_['volume-switch-2'] =
590 CommandUtil.createVolumeSwitchCommand(2);
591 CommandHandler.COMMANDS_['volume-switch-3'] =
592 CommandUtil.createVolumeSwitchCommand(3);
593 CommandHandler.COMMANDS_['volume-switch-4'] =
594 CommandUtil.createVolumeSwitchCommand(4);
595 CommandHandler.COMMANDS_['volume-switch-5'] =
596 CommandUtil.createVolumeSwitchCommand(5);
597 CommandHandler.COMMANDS_['volume-switch-6'] =
598 CommandUtil.createVolumeSwitchCommand(6);
599 CommandHandler.COMMANDS_['volume-switch-7'] =
600 CommandUtil.createVolumeSwitchCommand(7);
601 CommandHandler.COMMANDS_['volume-switch-8'] =
602 CommandUtil.createVolumeSwitchCommand(8);
603 CommandHandler.COMMANDS_['volume-switch-9'] =
604 CommandUtil.createVolumeSwitchCommand(9);
605
606 /**
607 * Flips 'available offline' flag on the file.
608 * @type {Command}
609 */
610 CommandHandler.COMMANDS_['toggle-pinned'] = {
611 execute: function(event, fileManager) {
612 var pin = !event.command.checked;
613 event.command.checked = pin;
614 var entries = CommandUtil.getPinTargetEntries();
615 var currentEntry;
616 var error = false;
617 var steps = {
618 // Pick an entry and pin it.
619 start: function() {
620 // Check if all the entries are pinned or not.
621 if (entries.length == 0)
622 return;
623 currentEntry = entries.shift();
624 chrome.fileBrowserPrivate.pinDriveFile(
625 currentEntry.toURL(),
626 pin,
627 steps.entryPinned);
628 },
629
630 // Check the result of pinning
631 entryPinned: function() {
632 // Convert to boolean.
633 error = !!chrome.runtime.lastError;
634 if (error && pin) {
635 fileManager.metadataCache_.get(
636 currentEntry, 'filesystem', steps.showError);
637 }
638 fileManager.metadataCache_.clear(currentEntry, 'drive');
639 fileManager.metadataCache_.get(
640 currentEntry, 'drive', steps.updateUI.bind(this));
641 },
642
643 // Update the user interface accoding to the cache state.
644 updateUI: function(drive) {
645 fileManager.updateMetadataInUI_(
646 'drive', [currentEntry.toURL()], [drive]);
647 if (!error)
648 steps.start();
649 },
650
651 // Show the error
652 showError: function(filesystem) {
653 fileManager.alert.showHtml(str('DRIVE_OUT_OF_SPACE_HEADER'),
654 strf('DRIVE_OUT_OF_SPACE_MESSAGE',
655 unescape(currentEntry.name),
656 util.bytesToString(filesystem.size)));
657 }
658 };
659 steps.start();
660 },
661
662 canExecute: function(event, fileManager) {
663 var entries = CommandUtil.getPinTargetEntries();
664 var checked = true;
665 for (var i = 0; i < entries.length; i++) {
666 checked = checked && entries[i].pinned;
667 }
668 if (entries.length > 0) {
669 event.canExecute = true;
670 event.command.setHidden(false);
671 event.command.checked = checked;
672 } else {
673 event.canExecute = false;
674 event.command.setHidden(true);
675 }
676 }
677 };
678
679 /**
680 * Creates zip file for current selection.
681 * @type {Command}
682 */
683 CommandHandler.COMMANDS_['zip-selection'] = {
684 execute: function(event, fileManager) {
685 var dirEntry = fileManager.getCurrentDirectoryEntry();
686 var selectionEntries = fileManager.getSelection().entries;
687 fileManager.fileOperationManager_.zipSelection(dirEntry, selectionEntries);
688 },
689 canExecute: function(event, fileManager) {
690 var dirEntry = fileManager.getCurrentDirectoryEntry();
691 var selection = fileManager.getSelection();
692 event.canExecute =
693 dirEntry &&
694 !fileManager.isOnReadonlyDirectory() &&
695 !fileManager.isOnDrive() &&
696 selection && selection.totalCount > 0;
697 }
698 };
699
700 /**
701 * Shows the share dialog for the current selection (single only).
702 * @type {Command}
703 */
704 CommandHandler.COMMANDS_['share'] = {
705 execute: function(event, fileManager) {
706 fileManager.shareSelection();
707 },
708 canExecute: function(event, fileManager) {
709 var selection = fileManager.getSelection();
710 var isDriveOffline =
711 fileManager.volumeManager.getDriveConnectionState().type ===
712 util.DriveConnectionType.OFFLINE;
713 event.canExecute = fileManager.isOnDrive() &&
714 !isDriveOffline &&
715 selection && selection.totalCount == 1;
716 event.command.setHidden(!fileManager.isOnDrive());
717 }
718 };
719
720 /**
721 * Creates a shortcut of the selected folder (single only).
722 * @type {Command}
723 */
724 CommandHandler.COMMANDS_['create-folder-shortcut'] = {
725 /**
726 * @param {Event} event Command event.
727 * @param {FileManager} fileManager The file manager instance.
728 */
729 execute: function(event, fileManager) {
730 var entry = CommandUtil.getCommandEntry(event.target);
731 if (entry)
732 fileManager.createFolderShortcut(entry);
733 },
734
735 /**
736 * @param {Event} event Command event.
737 * @param {FileManager} fileManager The file manager instance.
738 */
739 canExecute: function(event, fileManager) {
740 var entry = CommandUtil.getCommandEntry(event.target);
741 var folderShortcutExists = entry &&
742 fileManager.folderShortcutExists(entry);
743
744 var onlyOneFolderSelected = true;
745 // Only on list, user can select multiple files. The command is enabled only
746 // when a single file is selected.
747 if (event.target instanceof cr.ui.List &&
748 !(event.target instanceof NavigationList)) {
749 var items = event.target.selectedItems;
750 onlyOneFolderSelected = (items.length == 1 && items[0].isDirectory);
751 }
752
753 var location = entry && fileManager.volumeManager.getLocationInfo(entry);
754 var eligible = location && location.isEligibleForFolderShortcut;
755 event.canExecute =
756 eligible && onlyOneFolderSelected && !folderShortcutExists;
757 event.command.setHidden(!eligible || !onlyOneFolderSelected);
758 }
759 };
760
761 /**
762 * Removes the folder shortcut.
763 * @type {Command}
764 */
765 CommandHandler.COMMANDS_['remove-folder-shortcut'] = {
766 /**
767 * @param {Event} event Command event.
768 * @param {FileManager} fileManager The file manager instance.
769 */
770 execute: function(event, fileManager) {
771 var entry = CommandUtil.getCommandEntry(event.target);
772 if (entry)
773 fileManager.removeFolderShortcut(entry);
774 },
775
776 /**
777 * @param {Event} event Command event.
778 * @param {FileManager} fileManager The file manager instance.
779 */
780 canExecute: function(event, fileManager) {
781 var entry = CommandUtil.getCommandEntry(event.target);
782 var location = entry && fileManager.volumeManager.getLocationInfo(entry);
783
784 var eligible = location && location.isEligibleForFolderShortcut;
785 var isShortcut = entry && fileManager.folderShortcutExists(entry);
786 event.canExecute = isShortcut && eligible;
787 event.command.setHidden(!event.canExecute);
788 }
789 };
790
791 /**
792 * Zoom in to the Files.app.
793 * @type {Command}
794 */
795 CommandHandler.COMMANDS_['zoom-in'] = {
796 execute: function(event, fileManager) {
797 chrome.fileBrowserPrivate.zoom('in');
798 },
799 canExecute: CommandUtil.canExecuteAlways
800 };
801
802 /**
803 * Zoom out from the Files.app.
804 * @type {Command}
805 */
806 CommandHandler.COMMANDS_['zoom-out'] = {
807 execute: function(event, fileManager) {
808 chrome.fileBrowserPrivate.zoom('out');
809 },
810 canExecute: CommandUtil.canExecuteAlways
811 };
812
813 /**
814 * Reset the zoom factor.
815 * @type {Command}
816 */
817 CommandHandler.COMMANDS_['zoom-reset'] = {
818 execute: function(event, fileManager) {
819 chrome.fileBrowserPrivate.zoom('reset');
820 },
821 canExecute: CommandUtil.canExecuteAlways
822 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698