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