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

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

Issue 12857002: Files.app: Add subfolders in the left nav (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 7 years, 9 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
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 // This variable is checked in SelectFileDialogExtensionBrowserTest. 5 // This variable is checked in SelectFileDialogExtensionBrowserTest.
6 var JSErrorCount = 0; 6 var JSErrorCount = 0;
7 7
8 /** 8 /**
9 * Count uncaught exceptions. 9 * Count uncaught exceptions.
10 */ 10 */
(...skipping 504 matching lines...) Expand 10 before | Expand all | Expand 10 after
515 this.onCopyManagerOperationComplete_.bind(this)); 515 this.onCopyManagerOperationComplete_.bind(this));
516 516
517 var controller = this.fileTransferController_ = 517 var controller = this.fileTransferController_ =
518 new FileTransferController(this.document_, 518 new FileTransferController(this.document_,
519 this.copyManager_, 519 this.copyManager_,
520 this.directoryModel_); 520 this.directoryModel_);
521 controller.attachDragSource(this.table_.list); 521 controller.attachDragSource(this.table_.list);
522 controller.attachDropTarget(this.table_.list); 522 controller.attachDropTarget(this.table_.list);
523 controller.attachDragSource(this.grid_); 523 controller.attachDragSource(this.grid_);
524 controller.attachDropTarget(this.grid_); 524 controller.attachDropTarget(this.grid_);
525 controller.attachDropTarget(this.rootsList_, true); 525 controller.attachDropTarget(this.directoryTree_,
526 true /* onlyIntoDirectories */);
526 controller.attachBreadcrumbsDropTarget(this.breadcrumbs_); 527 controller.attachBreadcrumbsDropTarget(this.breadcrumbs_);
527 controller.attachCopyPasteHandlers(); 528 controller.attachCopyPasteHandlers();
528 controller.addEventListener('selection-copied', 529 controller.addEventListener('selection-copied',
529 this.blinkSelection.bind(this)); 530 this.blinkSelection.bind(this));
530 controller.addEventListener('selection-cut', 531 controller.addEventListener('selection-cut',
531 this.blinkSelection.bind(this)); 532 this.blinkSelection.bind(this));
532 }; 533 };
533 534
534 /** 535 /**
535 * One-time initialization of context menus. 536 * One-time initialization of context menus.
536 */ 537 */
537 FileManager.prototype.initContextMenus_ = function() { 538 FileManager.prototype.initContextMenus_ = function() {
538 this.fileContextMenu_ = this.dialogDom_.querySelector('#file-context-menu'); 539 this.fileContextMenu_ = this.dialogDom_.querySelector('#file-context-menu');
539 cr.ui.Menu.decorate(this.fileContextMenu_); 540 cr.ui.Menu.decorate(this.fileContextMenu_);
540 541
541 cr.ui.contextMenuHandler.setContextMenu(this.grid_, this.fileContextMenu_); 542 cr.ui.contextMenuHandler.setContextMenu(this.grid_, this.fileContextMenu_);
542 cr.ui.contextMenuHandler.setContextMenu(this.table_.querySelector('.list'), 543 cr.ui.contextMenuHandler.setContextMenu(this.table_.querySelector('.list'),
543 this.fileContextMenu_); 544 this.fileContextMenu_);
544 cr.ui.contextMenuHandler.setContextMenu( 545 cr.ui.contextMenuHandler.setContextMenu(
545 this.document_.querySelector('.drive-welcome.page'), 546 this.document_.querySelector('.drive-welcome.page'),
546 this.fileContextMenu_); 547 this.fileContextMenu_);
547 548
548 this.rootsContextMenu_ = 549 this.rootsContextMenu_ =
549 this.dialogDom_.querySelector('#roots-context-menu'); 550 this.dialogDom_.querySelector('#roots-context-menu');
550 cr.ui.Menu.decorate(this.rootsContextMenu_); 551 cr.ui.Menu.decorate(this.rootsContextMenu_);
551 552
553 this.directoryTree_.setContextMenu(this.rootsContextMenu_);
554
552 this.textContextMenu_ = 555 this.textContextMenu_ =
553 this.dialogDom_.querySelector('#text-context-menu'); 556 this.dialogDom_.querySelector('#text-context-menu');
554 cr.ui.Menu.decorate(this.textContextMenu_); 557 cr.ui.Menu.decorate(this.textContextMenu_);
555 558
556 this.gearButton_ = this.dialogDom_.querySelector('#gear-button'); 559 this.gearButton_ = this.dialogDom_.querySelector('#gear-button');
557 this.gearButton_.addEventListener('menushow', 560 this.gearButton_.addEventListener('menushow',
558 this.refreshRemainingSpace_.bind(this, 561 this.refreshRemainingSpace_.bind(this,
559 false /* Without loading caption. */)); 562 false /* Without loading caption. */));
560 cr.ui.decorate(this.gearButton_, cr.ui.MenuButton); 563 cr.ui.decorate(this.gearButton_, cr.ui.MenuButton);
561 564
(...skipping 20 matching lines...) Expand all
582 cr.ui.Command.decorate(commands[i]); 585 cr.ui.Command.decorate(commands[i]);
583 586
584 var doc = this.document_; 587 var doc = this.document_;
585 588
586 CommandUtil.registerCommand(doc, 'newfolder', 589 CommandUtil.registerCommand(doc, 'newfolder',
587 Commands.newFolderCommand, this, this.directoryModel_); 590 Commands.newFolderCommand, this, this.directoryModel_);
588 591
589 CommandUtil.registerCommand(doc, 'newwindow', 592 CommandUtil.registerCommand(doc, 'newwindow',
590 Commands.newWindowCommand, this); 593 Commands.newWindowCommand, this);
591 594
592 CommandUtil.registerCommand(this.rootsList_, 'unmount', 595 CommandUtil.registerCommand(this.directoryTree_, 'unmount',
593 Commands.unmountCommand, this.rootsList_, this); 596 Commands.unmountCommand, this.directoryTree_, this);
594 597
595 CommandUtil.registerCommand(doc, 'format', 598 CommandUtil.registerCommand(doc, 'format',
596 Commands.formatCommand, this.rootsList_, this, this.directoryModel_); 599 Commands.formatCommand, this.directoryTree_, this,
600 this.directoryModel_);
597 601
598 CommandUtil.registerCommand(this.rootsList_, 'import-photos', 602 CommandUtil.registerCommand(this.directoryTree_, 'import-photos',
599 Commands.importCommand, this.rootsList_); 603 Commands.importCommand, this.directoryTree_);
600 604
601 CommandUtil.registerCommand(doc, 'delete', 605 CommandUtil.registerCommand(doc, 'delete',
602 Commands.deleteFileCommand, this); 606 Commands.deleteFileCommand, this);
603 607
604 CommandUtil.registerCommand(doc, 'rename', 608 CommandUtil.registerCommand(doc, 'rename',
605 Commands.renameFileCommand, this); 609 Commands.renameFileCommand, this);
606 610
607 CommandUtil.registerCommand(doc, 'volume-help', 611 CommandUtil.registerCommand(doc, 'volume-help',
608 Commands.volumeHelpCommand, this); 612 Commands.volumeHelpCommand, this);
609 613
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after
907 911
908 var fileListFocusBound = this.onFileListFocus_.bind(this); 912 var fileListFocusBound = this.onFileListFocus_.bind(this);
909 var fileListBlurBound = this.onFileListBlur_.bind(this); 913 var fileListBlurBound = this.onFileListBlur_.bind(this);
910 914
911 this.table_.list.addEventListener('focus', fileListFocusBound); 915 this.table_.list.addEventListener('focus', fileListFocusBound);
912 this.grid_.addEventListener('focus', fileListFocusBound); 916 this.grid_.addEventListener('focus', fileListFocusBound);
913 917
914 this.table_.list.addEventListener('blur', fileListBlurBound); 918 this.table_.list.addEventListener('blur', fileListBlurBound);
915 this.grid_.addEventListener('blur', fileListBlurBound); 919 this.grid_.addEventListener('blur', fileListBlurBound);
916 920
917 this.initRootsList_(); 921 this.initSidebar_();
918 922
919 this.table_.addEventListener('column-resize-end', 923 this.table_.addEventListener('column-resize-end',
920 this.updateStartupPrefs_.bind(this)); 924 this.updateStartupPrefs_.bind(this));
921 925
922 this.setListType(prefs.listType || FileManager.ListType.DETAIL); 926 this.setListType(prefs.listType || FileManager.ListType.DETAIL);
923 927
924 if (prefs.columns) { 928 if (prefs.columns) {
925 var cm = this.table_.columnModel; 929 var cm = this.table_.columnModel;
926 for (var i = 0; i < cm.totalSize; i++) { 930 for (var i = 0; i < cm.totalSize; i++) {
927 if (prefs.columns[i] > 0) 931 if (prefs.columns[i] > 0)
(...skipping 12 matching lines...) Expand all
940 // Update metadata to change 'Today' and 'Yesterday' dates. 944 // Update metadata to change 'Today' and 'Yesterday' dates.
941 var today = new Date(); 945 var today = new Date();
942 today.setHours(0); 946 today.setHours(0);
943 today.setMinutes(0); 947 today.setMinutes(0);
944 today.setSeconds(0); 948 today.setSeconds(0);
945 today.setMilliseconds(0); 949 today.setMilliseconds(0);
946 setTimeout(this.dailyUpdateModificationTime_.bind(this), 950 setTimeout(this.dailyUpdateModificationTime_.bind(this),
947 today.getTime() + MILLISECONDS_IN_DAY - Date.now() + 1000); 951 today.getTime() + MILLISECONDS_IN_DAY - Date.now() + 1000);
948 }; 952 };
949 953
950 FileManager.prototype.initRootsList_ = function() { 954 FileManager.prototype.initSidebar_ = function() {
951 this.rootsList_ = this.dialogDom_.querySelector('#roots-list'); 955 this.directoryTree_ = this.dialogDom_.querySelector('#directory-tree');
952 cr.ui.List.decorate(this.rootsList_); 956 DirectoryTree.decorate(this.directoryTree_, this.directoryModel_);
953 957
954 // Overriding default role 'list' set by cr.ui.List.decorate() to 'listbox' 958 this.directoryTree_.addEventListener('change', function() {
955 // role for better accessibility on ChromeOS. 959 var currentPath = this.directoryTree_.getCurrentPath() ||
956 this.rootsList_.setAttribute('role', 'listbox'); 960 this.directoryModel_.getDefaultDirectory();
957 961 this.directoryModel_.changeDirectory(currentPath);
958 var self = this; 962 }.bind(this));
959 this.rootsList_.itemConstructor = function(entry) {
960 return self.renderRoot_(entry.fullPath);
961 };
962
963 this.rootsList_.selectionModel =
964 this.directoryModel_.getRootsListSelectionModel();
965
966 // TODO(dgozman): add "Add a drive" item.
967 this.rootsList_.dataModel = this.directoryModel_.getRootsList();
968 }; 963 };
969 964
970 FileManager.prototype.updateStartupPrefs_ = function() { 965 FileManager.prototype.updateStartupPrefs_ = function() {
971 var sortStatus = this.directoryModel_.getFileList().sortStatus; 966 var sortStatus = this.directoryModel_.getFileList().sortStatus;
972 var prefs = { 967 var prefs = {
973 sortField: sortStatus.field, 968 sortField: sortStatus.field,
974 sortDirection: sortStatus.direction, 969 sortDirection: sortStatus.direction,
975 columns: [] 970 columns: []
976 }; 971 };
977 var cm = this.table_.columnModel; 972 var cm = this.table_.columnModel;
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1026 */ 1021 */
1027 FileManager.prototype.getSelectedFilterIndex_ = function() { 1022 FileManager.prototype.getSelectedFilterIndex_ = function() {
1028 var index = Number(this.fileTypeSelector_.selectedIndex); 1023 var index = Number(this.fileTypeSelector_.selectedIndex);
1029 if (index < 0) // Nothing selected. 1024 if (index < 0) // Nothing selected.
1030 return 0; 1025 return 0;
1031 if (this.params_.includeAllFiles) // Already 1-based. 1026 if (this.params_.includeAllFiles) // Already 1-based.
1032 return index; 1027 return index;
1033 return index + 1; // Convert to 1-based; 1028 return index + 1; // Convert to 1-based;
1034 }; 1029 };
1035 1030
1036 FileManager.prototype.getRootEntry_ = function(index) {
1037 if (index == -1)
1038 return null;
1039
1040 return this.rootsList_.dataModel.item(index);
1041 };
1042
1043 FileManager.prototype.setListType = function(type) { 1031 FileManager.prototype.setListType = function(type) {
1044 if (type && type == this.listType_) 1032 if (type && type == this.listType_)
1045 return; 1033 return;
1046 1034
1047 this.table_.list.startBatchUpdates(); 1035 this.table_.list.startBatchUpdates();
1048 this.grid_.startBatchUpdates(); 1036 this.grid_.startBatchUpdates();
1049 1037
1050 // TODO(dzvorygin): style.display and dataModel setting order shouldn't 1038 // TODO(dzvorygin): style.display and dataModel setting order shouldn't
1051 // cause any UI bugs. Currently, the only right way is first to set display 1039 // cause any UI bugs. Currently, the only right way is first to set display
1052 // style and only then set dataModel. 1040 // style and only then set dataModel.
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
1240 g.startBatchUpdates(); 1228 g.startBatchUpdates();
1241 setTimeout(function() { 1229 setTimeout(function() {
1242 g.columns = 0; 1230 g.columns = 0;
1243 g.redraw(); 1231 g.redraw();
1244 g.endBatchUpdates(); 1232 g.endBatchUpdates();
1245 }, 0); 1233 }, 0);
1246 } else { 1234 } else {
1247 this.table_.redraw(); 1235 this.table_.redraw();
1248 } 1236 }
1249 1237
1250 this.rootsList_.redraw();
1251 this.breadcrumbs_.truncate(); 1238 this.breadcrumbs_.truncate();
1252 this.searchBreadcrumbs_.truncate(); 1239 this.searchBreadcrumbs_.truncate();
1253 1240
1254 this.updateWindowState_(); 1241 this.updateWindowState_();
1255 }; 1242 };
1256 1243
1257 FileManager.prototype.updateWindowState_ = function() { 1244 FileManager.prototype.updateWindowState_ = function() {
1258 util.platform.getWindowStatus(function(wnd) { 1245 util.platform.getWindowStatus(function(wnd) {
1259 if (wnd.state == 'maximized') { 1246 if (wnd.state == 'maximized') {
1260 this.dialogDom_.setAttribute('maximized', 'maximized'); 1247 this.dialogDom_.setAttribute('maximized', 'maximized');
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
1457 } 1444 }
1458 1445
1459 this.okButton_.textContent = okLabel; 1446 this.okButton_.textContent = okLabel;
1460 1447
1461 var dialogTitle = this.params_.title || defaultTitle; 1448 var dialogTitle = this.params_.title || defaultTitle;
1462 this.dialogDom_.querySelector('.dialog-title').textContent = dialogTitle; 1449 this.dialogDom_.querySelector('.dialog-title').textContent = dialogTitle;
1463 1450
1464 this.dialogDom_.setAttribute('type', this.dialogType); 1451 this.dialogDom_.setAttribute('type', this.dialogType);
1465 }; 1452 };
1466 1453
1467 FileManager.prototype.renderRoot_ = function(path) {
1468 var li = this.document_.createElement('li');
1469 li.className = 'root-item';
1470 li.setAttribute('role', 'option');
1471 var dm = this.directoryModel_;
1472 var handleClick = function() {
1473 if (li.selected && path !== dm.getCurrentDirPath()) {
1474 dm.changeDirectory(path);
1475 }
1476 };
1477 li.addEventListener('mousedown', handleClick);
1478 li.addEventListener(cr.ui.TouchHandler.EventType.TOUCH_START, handleClick);
1479
1480 var rootType = PathUtil.getRootType(path);
1481
1482 var iconDiv = this.document_.createElement('div');
1483 iconDiv.className = 'volume-icon';
1484 iconDiv.setAttribute('volume-type-icon', rootType);
1485 if (rootType === RootType.REMOVABLE) {
1486 iconDiv.setAttribute('volume-subtype',
1487 this.volumeManager_.getDeviceType(path));
1488 }
1489 li.appendChild(iconDiv);
1490
1491 var div = this.document_.createElement('div');
1492 div.className = 'root-label';
1493
1494 div.textContent = PathUtil.getRootLabel(path);
1495 li.appendChild(div);
1496
1497 if (rootType === RootType.ARCHIVE || rootType === RootType.REMOVABLE) {
1498 var eject = this.document_.createElement('div');
1499 eject.className = 'root-eject';
1500 eject.addEventListener('click', function(event) {
1501 event.stopPropagation();
1502 var unmountCommand = this.dialogDom_.querySelector('command#unmount');
1503 // Let's make sure 'canExecute' state of the command is properly set for
1504 // the root before executing it.
1505 unmountCommand.canExecuteChange(li);
1506 unmountCommand.execute(li);
1507 }.bind(this));
1508 // Block other mouse handlers.
1509 eject.addEventListener('mouseup', function(e) { e.stopPropagation() });
1510 eject.addEventListener('mousedown', function(e) { e.stopPropagation() });
1511 li.appendChild(eject);
1512 }
1513
1514 if (rootType != RootType.DRIVE && rootType != RootType.DOWNLOADS)
1515 cr.ui.contextMenuHandler.setContextMenu(li, this.rootsContextMenu_);
1516
1517 cr.defineProperty(li, 'lead', cr.PropertyKind.BOOL_ATTR);
1518 cr.defineProperty(li, 'selected', cr.PropertyKind.BOOL_ATTR);
1519
1520 return li;
1521 };
1522
1523 /** 1454 /**
1524 * Unmounts device. 1455 * Unmounts device.
1525 * @param {string} path Path to a volume to unmount. 1456 * @param {string} path Path to a volume to unmount.
1526 */ 1457 */
1527 FileManager.prototype.unmountVolume = function(path) { 1458 FileManager.prototype.unmountVolume = function(path) {
1528 var listItem = this.rootsList_.getListItemByIndex(
1529 this.directoryModel_.findRootsListIndex(path));
1530 if (listItem)
1531 listItem.setAttribute('disabled', '');
1532 var onError = function(error) { 1459 var onError = function(error) {
1533 if (listItem)
1534 listItem.removeAttribute('disabled');
1535 this.alert.showHtml('', str('UNMOUNT_FAILED')); 1460 this.alert.showHtml('', str('UNMOUNT_FAILED'));
1536 }; 1461 };
1537 this.volumeManager_.unmount(path, function() {}, onError.bind(this)); 1462 this.volumeManager_.unmount(path, function() {}, onError.bind(this));
1538 }; 1463 };
1539 1464
1540 FileManager.prototype.refreshCurrentDirectoryMetadata_ = function() { 1465 FileManager.prototype.refreshCurrentDirectoryMetadata_ = function() {
1541 var entries = this.directoryModel_.getFileList().slice(); 1466 var entries = this.directoryModel_.getFileList().slice();
1542 var directoryEntry = this.directoryModel_.getCurrentDirEntry(); 1467 var directoryEntry = this.directoryModel_.getCurrentDirEntry();
1543 // We don't pass callback here. When new metadata arrives, we have an 1468 // We don't pass callback here. When new metadata arrives, we have an
1544 // observer registered to update the UI. 1469 // observer registered to update the UI.
(...skipping 1618 matching lines...) Expand 10 before | Expand all | Expand 10 after
3163 callback(this.preferences_); 3088 callback(this.preferences_);
3164 return; 3089 return;
3165 } 3090 }
3166 3091
3167 chrome.fileBrowserPrivate.getPreferences(function(prefs) { 3092 chrome.fileBrowserPrivate.getPreferences(function(prefs) {
3168 this.preferences_ = prefs; 3093 this.preferences_ = prefs;
3169 callback(prefs); 3094 callback(prefs);
3170 }.bind(this)); 3095 }.bind(this));
3171 }; 3096 };
3172 })(); 3097 })();
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698