| 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 // 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 })(); |
| OLD | NEW |