| 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 'use strict'; | 5 'use strict'; |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * FileManager constructor. | 8 * FileManager constructor. |
| 9 * | 9 * |
| 10 * FileManager objects encapsulate the functionality of the file selector | 10 * FileManager objects encapsulate the functionality of the file selector |
| (...skipping 28 matching lines...) Expand all Loading... |
| 39 this.selectionHandler_ = null; | 39 this.selectionHandler_ = null; |
| 40 | 40 |
| 41 /** | 41 /** |
| 42 * VolumeInfo of the current volume. | 42 * VolumeInfo of the current volume. |
| 43 * @type {VolumeInfo} | 43 * @type {VolumeInfo} |
| 44 * @private | 44 * @private |
| 45 */ | 45 */ |
| 46 this.currentVolumeInfo_ = null; | 46 this.currentVolumeInfo_ = null; |
| 47 } | 47 } |
| 48 | 48 |
| 49 /** | |
| 50 * Maximum delay in milliseconds for updating thumbnails in the bottom panel | |
| 51 * to mitigate flickering. If images load faster then the delay they replace | |
| 52 * old images smoothly. On the other hand we don't want to keep old images | |
| 53 * too long. | |
| 54 * | |
| 55 * @type {number} | |
| 56 * @const | |
| 57 */ | |
| 58 FileManager.THUMBNAIL_SHOW_DELAY = 100; | |
| 59 | |
| 60 FileManager.prototype = { | 49 FileManager.prototype = { |
| 61 __proto__: cr.EventTarget.prototype, | 50 __proto__: cr.EventTarget.prototype, |
| 62 get directoryModel() { | 51 get directoryModel() { |
| 63 return this.directoryModel_; | 52 return this.directoryModel_; |
| 64 }, | 53 }, |
| 65 get navigationList() { | 54 get navigationList() { |
| 66 return this.navigationList_; | 55 return this.navigationList_; |
| 67 }, | 56 }, |
| 68 get document() { | 57 get document() { |
| 69 return this.document_; | 58 return this.document_; |
| (...skipping 506 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 576 | 565 |
| 577 /** | 566 /** |
| 578 * Initializes general purpose basic things, which are used by other | 567 * Initializes general purpose basic things, which are used by other |
| 579 * initializing methods. | 568 * initializing methods. |
| 580 * | 569 * |
| 581 * @param {function()} callback Completion callback. | 570 * @param {function()} callback Completion callback. |
| 582 * @private | 571 * @private |
| 583 */ | 572 */ |
| 584 FileManager.prototype.initGeneral_ = function(callback) { | 573 FileManager.prototype.initGeneral_ = function(callback) { |
| 585 // Initialize the application state. | 574 // Initialize the application state. |
| 575 // TODO(mtomasz): Unify window.appState with location.search format. |
| 586 if (window.appState) { | 576 if (window.appState) { |
| 587 this.params_ = window.appState.params || {}; | 577 this.params_ = window.appState.params || {}; |
| 588 this.defaultPath = window.appState.defaultPath; | 578 this.initCurrentDirectoryPath_ = window.appState.currentDirectoryPath; |
| 579 this.initSelectionPath_ = window.appState.selectionPath; |
| 580 this.initTargetName_ = window.appState.targetName; |
| 589 } else { | 581 } else { |
| 582 // Used by the select dialog only. |
| 590 this.params_ = location.search ? | 583 this.params_ = location.search ? |
| 591 JSON.parse(decodeURIComponent(location.search.substr(1))) : | 584 JSON.parse(decodeURIComponent(location.search.substr(1))) : |
| 592 {}; | 585 {}; |
| 593 this.defaultPath = this.params_.defaultPath; | 586 this.initCurrentDirectoryPath_ = this.params_.currentDirectoryPath; |
| 587 this.initSelectionPath_ = this.params_.selectionPath; |
| 588 this.initTargetName_ = this.params_.targetName; |
| 594 } | 589 } |
| 595 | 590 |
| 596 // Initialize the member variables that depend this.params_. | 591 // Initialize the member variables that depend this.params_. |
| 597 this.dialogType = this.params_.type || DialogType.FULL_PAGE; | 592 this.dialogType = this.params_.type || DialogType.FULL_PAGE; |
| 598 this.startupPrefName_ = 'file-manager-' + this.dialogType; | 593 this.startupPrefName_ = 'file-manager-' + this.dialogType; |
| 599 this.fileTypes_ = this.params_.typeList || []; | 594 this.fileTypes_ = this.params_.typeList || []; |
| 600 | 595 |
| 601 callback(); | 596 callback(); |
| 602 }; | 597 }; |
| 603 | 598 |
| (...skipping 782 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1386 * @private | 1381 * @private |
| 1387 */ | 1382 */ |
| 1388 FileManager.prototype.onDragEnd_ = function() { | 1383 FileManager.prototype.onDragEnd_ = function() { |
| 1389 // On open file dialog, the preview panel is always shown. | 1384 // On open file dialog, the preview panel is always shown. |
| 1390 if (DialogType.isOpenDialog(this.dialogType)) | 1385 if (DialogType.isOpenDialog(this.dialogType)) |
| 1391 return; | 1386 return; |
| 1392 this.previewPanel_.visibilityType = PreviewPanel.VisibilityType.AUTO; | 1387 this.previewPanel_.visibilityType = PreviewPanel.VisibilityType.AUTO; |
| 1393 }; | 1388 }; |
| 1394 | 1389 |
| 1395 /** | 1390 /** |
| 1396 * Restores current directory and may be a selected item after page load (or | 1391 * Sets up the current directory during initialization. |
| 1397 * reload) or popping a state (after click on back/forward). defaultPath | |
| 1398 * primarily is used with save/open dialogs. | |
| 1399 * Default path may also contain a file name. Freshly opened file manager | |
| 1400 * window has neither. | |
| 1401 * | |
| 1402 * @private | 1392 * @private |
| 1403 */ | 1393 */ |
| 1404 FileManager.prototype.setupCurrentDirectory_ = function() { | 1394 FileManager.prototype.setupCurrentDirectory_ = function() { |
| 1405 var tracker = this.directoryModel_.createDirectoryChangeTracker(); | 1395 var tracker = this.directoryModel_.createDirectoryChangeTracker(); |
| 1406 var queue = new AsyncUtil.Queue(); | 1396 var queue = new AsyncUtil.Queue(); |
| 1407 | 1397 |
| 1408 // Wait until the volume manager is initialized. | 1398 // Wait until the volume manager is initialized. |
| 1409 queue.run(function(callback) { | 1399 queue.run(function(callback) { |
| 1410 tracker.start(); | 1400 tracker.start(); |
| 1411 this.volumeManager_.ensureInitialized(callback); | 1401 this.volumeManager_.ensureInitialized(callback); |
| 1412 }.bind(this)); | 1402 }.bind(this)); |
| 1413 | 1403 |
| 1414 // Obtains the fallback path. | 1404 var nextCurrentDirEntry; |
| 1415 var defaultDisplayRoot; | 1405 var selectionEntry; |
| 1406 |
| 1407 // Resolve the selectionPath to selectionEntry or to currentDirectoryEntry |
| 1408 // in case of being a display root. |
| 1416 queue.run(function(callback) { | 1409 queue.run(function(callback) { |
| 1417 this.volumeManager_.getDefaultDisplayRoot(function(displayRoot) { | 1410 // TODO(mtomasz): Migrate to URLs, and stop calling resolveAbsolutePath. |
| 1418 defaultDisplayRoot = displayRoot; | 1411 if (!this.initSelectionPath_) { |
| 1412 callback(); |
| 1413 return; |
| 1414 } |
| 1415 this.volumeManager_.resolveAbsolutePath( |
| 1416 this.initSelectionPath_, |
| 1417 function(inEntry) { |
| 1418 var locationInfo = this.volumeManager_.getLocationInfo(inEntry); |
| 1419 // If the selection is root, then use it as a current directory |
| 1420 // instead. This is because, selecting a root entry is done as |
| 1421 // opening it. |
| 1422 if (locationInfo && locationInfo.isRootEntry) |
| 1423 nextCurrentDirEntry = inEntry; |
| 1424 else |
| 1425 selectionEntry = inEntry; |
| 1426 callback(); |
| 1427 }.bind(this), callback); |
| 1428 }.bind(this)); |
| 1429 // Resolve the currentDirectoryPath to currentDirectoryEntry (if not done |
| 1430 // by the previous step). |
| 1431 queue.run(function(callback) { |
| 1432 if (nextCurrentDirEntry || !this.initCurrentDirectoryPath_) { |
| 1433 callback(); |
| 1434 return; |
| 1435 } |
| 1436 // TODO(mtomasz): Migrate to URLs, and stop calling resolveAbsolutePath. |
| 1437 this.volumeManager_.resolveAbsolutePath( |
| 1438 this.initCurrentDirectoryPath_, |
| 1439 function(inEntry) { |
| 1440 nextCurrentDirEntry = inEntry; |
| 1441 callback(); |
| 1442 }, callback); |
| 1443 // TODO(mtomasz): Implement reopening on special search, when fake |
| 1444 // entries are converted to directory providers. |
| 1445 }.bind(this)); |
| 1446 |
| 1447 // If the directory to be changed to is not available, then first fallback |
| 1448 // to the parent of the selection entry. |
| 1449 queue.run(function(callback) { |
| 1450 if (nextCurrentDirEntry || !selectionEntry) { |
| 1451 callback(); |
| 1452 return; |
| 1453 } |
| 1454 selectionEntry.getParent(function(inEntry) { |
| 1455 nextCurrentDirEntry = inEntry; |
| 1419 callback(); | 1456 callback(); |
| 1420 }.bind(this)); | 1457 }.bind(this)); |
| 1421 }.bind(this)); | 1458 }.bind(this)); |
| 1422 | 1459 |
| 1423 // Resolve the default path. | 1460 // If the directory to be changed to is still not resolved, then fallback |
| 1424 var defaultFullPath; | 1461 // to the default display root. |
| 1425 var candidateFullPath; | |
| 1426 var candidateEntry; | |
| 1427 queue.run(function(callback) { | 1462 queue.run(function(callback) { |
| 1428 // Cancel this sequence if the current directory has already changed. | 1463 if (nextCurrentDirEntry) { |
| 1429 if (tracker.hasChanged) { | |
| 1430 callback(); | 1464 callback(); |
| 1431 return; | 1465 return; |
| 1432 } | 1466 } |
| 1433 | 1467 this.volumeManager_.getDefaultDisplayRoot(function(displayRoot) { |
| 1434 // Resolve the absolute path in case only the file name or an empty string | 1468 nextCurrentDirEntry = displayRoot; |
| 1435 // is passed. | |
| 1436 if (!this.defaultPath) { | |
| 1437 // TODO(mtomasz): that in this case we can directly jump to #1540 | |
| 1438 // and avoid fullPath conversion -> Entry. | |
| 1439 defaultFullPath = defaultDisplayRoot.fullPath; | |
| 1440 } else if (this.defaultPath.indexOf('/') === -1) { | |
| 1441 // Path is a file name. | |
| 1442 defaultFullPath = defaultDisplayRoot.fullPath + '/' + this.defaultPath; | |
| 1443 } else { | |
| 1444 defaultFullPath = this.defaultPath; | |
| 1445 } | |
| 1446 | |
| 1447 // If Drive is disabled but the path points to Drive's entry, fallback to | |
| 1448 // defaultDisplayRootPath. | |
| 1449 if (PathUtil.isDriveBasedPath(defaultFullPath) && | |
| 1450 !this.volumeManager_.getVolumeInfo(RootDirectory.DRIVE)) { | |
| 1451 candidateFullPath = defaultDisplayRoot.fullPath + '/' + | |
| 1452 PathUtil.basename(defaultFullPath); | |
| 1453 } else { | |
| 1454 candidateFullPath = defaultFullPath; | |
| 1455 } | |
| 1456 | |
| 1457 // If the path points a fake entry, use the entry directly. | |
| 1458 // TODO(hirono): Obtains proper volume. | |
| 1459 var volumeInfo = this.volumeManager_.getCurrentProfileVolumeInfo( | |
| 1460 util.VolumeType.DRIVE); | |
| 1461 if (volumeInfo) { | |
| 1462 for (var name in volumeInfo.fakeEntries) { | |
| 1463 var fakeEntry = volumeInfo.fakeEntries[name]; | |
| 1464 // Skip the drive root fake entry, because we can need actual drive | |
| 1465 // root to list its files. | |
| 1466 if (fakeEntry.rootType === RootType.DRIVE) | |
| 1467 continue; | |
| 1468 if (candidateFullPath === fakeEntry.fullPath) { | |
| 1469 candidateEntry = fakeEntry; | |
| 1470 callback(); | |
| 1471 return; | |
| 1472 } | |
| 1473 } | |
| 1474 } | |
| 1475 | |
| 1476 // Convert the path to the directory entry and an optional selection | |
| 1477 // entry. | |
| 1478 // TODO(hirono): There may be a race here. The path on Drive, may not | |
| 1479 // be available yet. | |
| 1480 this.volumeManager_.resolveAbsolutePath(candidateFullPath, | |
| 1481 function(inEntry) { | |
| 1482 candidateEntry = inEntry; | |
| 1483 callback(); | 1469 callback(); |
| 1484 }, function() { | 1470 }.bind(this)); |
| 1485 callback(); | |
| 1486 }); | |
| 1487 }.bind(this)); | 1471 }.bind(this)); |
| 1488 | 1472 |
| 1489 // Check the obtained entry. | 1473 // If selection failed to be resolved (eg. didn't exist, in case of saving |
| 1490 var nextCurrentDirEntry; | 1474 // a file, or in case of a fallback of the current directory, then try to |
| 1491 var selectionEntry = null; | 1475 // resolve again using the target name. |
| 1492 var suggestedName = null; | |
| 1493 var error = null; | |
| 1494 queue.run(function(callback) { | 1476 queue.run(function(callback) { |
| 1495 // Cancel this sequence if the current directory has already changed. | 1477 if (selectionEntry || !nextCurrentDirEntry || !this.initTargetName_) { |
| 1496 if (tracker.hasChanged) { | |
| 1497 callback(); | 1478 callback(); |
| 1498 return; | 1479 return; |
| 1499 } | 1480 } |
| 1500 | 1481 // Try to resolve as a file first. If it fails, then as a directory. |
| 1501 if (candidateEntry) { | 1482 nextCurrentDirEntry.getFile( |
| 1502 // The entry is directory. Use it. | 1483 this.initTargetName_, |
| 1503 if (candidateEntry.isDirectory) { | 1484 {}, |
| 1504 nextCurrentDirEntry = candidateEntry; | 1485 function(targetEntry) { |
| 1505 callback(); | 1486 selectionEntry = targetEntry; |
| 1506 return; | |
| 1507 } | |
| 1508 // The entry exists, but it is not a directory. Therefore use a | |
| 1509 // parent. | |
| 1510 candidateEntry.getParent(function(parentEntry) { | |
| 1511 nextCurrentDirEntry = parentEntry; | |
| 1512 selectionEntry = candidateEntry; | |
| 1513 callback(); | |
| 1514 }, function() { | |
| 1515 error = new Error('Unable to resolve parent for: ' + | |
| 1516 candidateEntry.fullPath); | |
| 1517 callback(); | |
| 1518 }); | |
| 1519 return; | |
| 1520 } | |
| 1521 | |
| 1522 // If the entry doesn't exist, most probably because the path contains a | |
| 1523 // suggested name. Therefore try to open its parent. However, the parent | |
| 1524 // may also not exist. In such situation, fallback. | |
| 1525 var pathNodes = candidateFullPath.split('/'); | |
| 1526 var baseName = pathNodes.pop(); | |
| 1527 var parentPath = pathNodes.join('/'); | |
| 1528 this.volumeManager_.resolveAbsolutePath( | |
| 1529 parentPath, | |
| 1530 function(parentEntry) { | |
| 1531 nextCurrentDirEntry = parentEntry; | |
| 1532 suggestedName = baseName; | |
| 1533 callback(); | 1487 callback(); |
| 1534 }, | 1488 }, function() { |
| 1535 callback); // In case of an error, continue. | 1489 // Failed to resolve as a file |
| 1490 nextCurrentDirEntry.getDirectory( |
| 1491 this.initTargetName_, |
| 1492 {}, |
| 1493 function(targetEntry) { |
| 1494 selectionEntry = targetEntry; |
| 1495 callback(); |
| 1496 }, function() { |
| 1497 // Failed to resolve as either file or directory. |
| 1498 callback(); |
| 1499 }); |
| 1500 }.bind(this)); |
| 1536 }.bind(this)); | 1501 }.bind(this)); |
| 1537 | 1502 |
| 1538 // If the directory is not set at this stage, fallback to the default | 1503 |
| 1539 // mount point. | 1504 // Finalize. |
| 1540 queue.run(function(callback) { | 1505 queue.run(function(callback) { |
| 1541 // Check error. | |
| 1542 if (error) { | |
| 1543 callback(); | |
| 1544 throw error; | |
| 1545 } | |
| 1546 // Check directory change. | 1506 // Check directory change. |
| 1547 tracker.stop(); | 1507 tracker.stop(); |
| 1548 if (tracker.hasChanged) { | 1508 if (tracker.hasChanged) { |
| 1549 callback(); | 1509 callback(); |
| 1550 return; | 1510 return; |
| 1551 } | 1511 } |
| 1552 // Finish setup current directory. | 1512 // Finish setup current directory. |
| 1553 this.finishSetupCurrentDirectory_( | 1513 this.finishSetupCurrentDirectory_( |
| 1554 nextCurrentDirEntry || defaultDisplayRoot, | 1514 nextCurrentDirEntry, |
| 1555 selectionEntry, | 1515 selectionEntry, |
| 1556 suggestedName); | 1516 this.initTargetName_); |
| 1557 callback(); | 1517 callback(); |
| 1558 }.bind(this)); | 1518 }.bind(this)); |
| 1559 }; | 1519 }; |
| 1560 | 1520 |
| 1561 /** | 1521 /** |
| 1562 * @param {DirectoryEntry} directoryEntry Directory to be opened. | 1522 * @param {DirectoryEntry} directoryEntry Directory to be opened. |
| 1563 * @param {Entry=} opt_selectionEntry Entry to be selected. | 1523 * @param {Entry=} opt_selectionEntry Entry to be selected. |
| 1564 * @param {string=} opt_suggestedName Suggested name for a non-existing\ | 1524 * @param {string=} opt_suggestedName Suggested name for a non-existing\ |
| 1565 * selection. | 1525 * selection. |
| 1566 * @private | 1526 * @private |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1578 } | 1538 } |
| 1579 | 1539 |
| 1580 if (this.dialogType === DialogType.FULL_PAGE) { | 1540 if (this.dialogType === DialogType.FULL_PAGE) { |
| 1581 // In the FULL_PAGE mode if the restored path points to a file we might | 1541 // In the FULL_PAGE mode if the restored path points to a file we might |
| 1582 // have to invoke a task after selecting it. | 1542 // have to invoke a task after selecting it. |
| 1583 if (this.params_.action === 'select') | 1543 if (this.params_.action === 'select') |
| 1584 return; | 1544 return; |
| 1585 | 1545 |
| 1586 var task = null; | 1546 var task = null; |
| 1587 // Handle restoring after crash, or the gallery action. | 1547 // Handle restoring after crash, or the gallery action. |
| 1548 // TODO(mtomasz): Use the gallery action instead of just the gallery |
| 1549 // field. |
| 1588 if (this.params_.gallery || this.params_.action === 'gallery') { | 1550 if (this.params_.gallery || this.params_.action === 'gallery') { |
| 1589 if (!opt_selectionEntry) { | 1551 if (!opt_selectionEntry) { |
| 1590 // Non-existent file or a directory. | 1552 // Non-existent file or a directory. |
| 1591 // Reloading while the Gallery is open with empty or multiple | 1553 // Reloading while the Gallery is open with empty or multiple |
| 1592 // selection. Open the Gallery when the directory is scanned. | 1554 // selection. Open the Gallery when the directory is scanned. |
| 1593 task = function() { | 1555 task = function() { |
| 1594 new FileTasks(this, this.params_).openGallery([]); | 1556 new FileTasks(this, this.params_).openGallery([]); |
| 1595 }.bind(this); | 1557 }.bind(this); |
| 1596 } else { | 1558 } else { |
| 1597 // The file or the directory exists. | 1559 // The file or the directory exists. |
| 1598 task = function() { | 1560 task = function() { |
| 1599 // TODO(mtomasz): Replace the url with an entry. | |
| 1600 new FileTasks(this, this.params_).openGallery([opt_selectionEntry]); | 1561 new FileTasks(this, this.params_).openGallery([opt_selectionEntry]); |
| 1601 }.bind(this); | 1562 }.bind(this); |
| 1602 } | 1563 } |
| 1603 } else { | 1564 } else { |
| 1604 // TODO(mtomasz): Implement remounting archives after crash. | 1565 // TODO(mtomasz): Implement remounting archives after crash. |
| 1605 // See: crbug.com/333139 | 1566 // See: crbug.com/333139 |
| 1606 } | 1567 } |
| 1607 | 1568 |
| 1608 // If there is a task to be run, run it after the scan is completed. | 1569 // If there is a task to be run, run it after the scan is completed. |
| 1609 if (task) { | 1570 if (task) { |
| 1610 var listener = function() { | 1571 var listener = function() { |
| 1572 if (!util.isSameEntry(this.directoryModel_.getCurrentDirEntry(), |
| 1573 directoryEntry)) { |
| 1574 // Opened on a different path. Probably fallbacked. Therefore, |
| 1575 // do not invoke a task. |
| 1576 return; |
| 1577 } |
| 1611 this.directoryModel_.removeEventListener( | 1578 this.directoryModel_.removeEventListener( |
| 1612 'scan-completed', listener); | 1579 'scan-completed', listener); |
| 1613 task(); | 1580 task(); |
| 1614 }.bind(this); | 1581 }.bind(this); |
| 1615 this.directoryModel_.addEventListener('scan-completed', listener); | 1582 this.directoryModel_.addEventListener('scan-completed', listener); |
| 1616 } | 1583 } |
| 1617 } else if (this.dialogType === DialogType.SELECT_SAVEAS_FILE) { | 1584 } else if (this.dialogType === DialogType.SELECT_SAVEAS_FILE) { |
| 1618 this.filenameInput_.value = opt_suggestedName || ''; | 1585 this.filenameInput_.value = opt_suggestedName || ''; |
| 1619 this.selectDefaultPathInFilenameInput_(); | 1586 this.selectTargetNameInFilenameInput_(); |
| 1620 } | 1587 } |
| 1621 }; | 1588 }; |
| 1622 | 1589 |
| 1623 /** | 1590 /** |
| 1624 * @private | 1591 * @private |
| 1625 */ | 1592 */ |
| 1626 FileManager.prototype.refreshCurrentDirectoryMetadata_ = function() { | 1593 FileManager.prototype.refreshCurrentDirectoryMetadata_ = function() { |
| 1627 var entries = this.directoryModel_.getFileList().slice(); | 1594 var entries = this.directoryModel_.getFileList().slice(); |
| 1628 var directoryEntry = this.directoryModel_.getCurrentDirEntry(); | 1595 var directoryEntry = this.directoryModel_.getCurrentDirEntry(); |
| 1629 if (!directoryEntry) | 1596 if (!directoryEntry) |
| (...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2036 FileManager.prototype.blinkListItem_ = function(listItem) { | 2003 FileManager.prototype.blinkListItem_ = function(listItem) { |
| 2037 listItem.classList.add('blink'); | 2004 listItem.classList.add('blink'); |
| 2038 setTimeout(function() { | 2005 setTimeout(function() { |
| 2039 listItem.classList.remove('blink'); | 2006 listItem.classList.remove('blink'); |
| 2040 }, 100); | 2007 }, 100); |
| 2041 }; | 2008 }; |
| 2042 | 2009 |
| 2043 /** | 2010 /** |
| 2044 * @private | 2011 * @private |
| 2045 */ | 2012 */ |
| 2046 FileManager.prototype.selectDefaultPathInFilenameInput_ = function() { | 2013 FileManager.prototype.selectTargetNameInFilenameInput_ = function() { |
| 2047 var input = this.filenameInput_; | 2014 var input = this.filenameInput_; |
| 2048 input.focus(); | 2015 input.focus(); |
| 2049 var selectionEnd = input.value.lastIndexOf('.'); | 2016 var selectionEnd = input.value.lastIndexOf('.'); |
| 2050 if (selectionEnd == -1) { | 2017 if (selectionEnd == -1) { |
| 2051 input.select(); | 2018 input.select(); |
| 2052 } else { | 2019 } else { |
| 2053 input.selectionStart = 0; | 2020 input.selectionStart = 0; |
| 2054 input.selectionEnd = selectionEnd; | 2021 input.selectionEnd = selectionEnd; |
| 2055 } | 2022 } |
| 2056 // Clear, so we never do this again. | |
| 2057 this.defaultPath = ''; | |
| 2058 }; | 2023 }; |
| 2059 | 2024 |
| 2060 /** | 2025 /** |
| 2061 * Handles mouse click or tap. | 2026 * Handles mouse click or tap. |
| 2062 * | 2027 * |
| 2063 * @param {Event} event The click event. | 2028 * @param {Event} event The click event. |
| 2064 * @private | 2029 * @private |
| 2065 */ | 2030 */ |
| 2066 FileManager.prototype.onDetailClick_ = function(event) { | 2031 FileManager.prototype.onDetailClick_ = function(event) { |
| 2067 if (this.isRenamingInProgress()) { | 2032 if (this.isRenamingInProgress()) { |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2253 /** | 2218 /** |
| 2254 * Update the UI when the current directory changes. | 2219 * Update the UI when the current directory changes. |
| 2255 * | 2220 * |
| 2256 * @param {Event} event The directory-changed event. | 2221 * @param {Event} event The directory-changed event. |
| 2257 * @private | 2222 * @private |
| 2258 */ | 2223 */ |
| 2259 FileManager.prototype.onDirectoryChanged_ = function(event) { | 2224 FileManager.prototype.onDirectoryChanged_ = function(event) { |
| 2260 this.selectionHandler_.onFileSelectionChanged(); | 2225 this.selectionHandler_.onFileSelectionChanged(); |
| 2261 this.ui_.searchBox.clear(); | 2226 this.ui_.searchBox.clear(); |
| 2262 // TODO(mtomasz): Use Entry.toURL() instead of fullPath. | 2227 // TODO(mtomasz): Use Entry.toURL() instead of fullPath. |
| 2228 // TODO(mtomasz): Consider remembering the selection. |
| 2263 util.updateAppState( | 2229 util.updateAppState( |
| 2264 this.getCurrentDirectoryEntry() && | 2230 this.getCurrentDirectoryEntry() ? |
| 2265 this.getCurrentDirectoryEntry().fullPath, '' /* opt_param */); | 2231 this.getCurrentDirectoryEntry().fullPath : '', |
| 2232 '' /* selectionPath */, |
| 2233 '' /* opt_param */); |
| 2266 | 2234 |
| 2267 if (this.commandHandler) | 2235 if (this.commandHandler) |
| 2268 this.commandHandler.updateAvailability(); | 2236 this.commandHandler.updateAvailability(); |
| 2269 | 2237 |
| 2270 this.updateUnformattedVolumeStatus_(); | 2238 this.updateUnformattedVolumeStatus_(); |
| 2271 this.updateTitle_(); | 2239 this.updateTitle_(); |
| 2272 var newCurrentVolumeInfo = this.volumeManager_.getVolumeInfo( | 2240 var newCurrentVolumeInfo = this.volumeManager_.getVolumeInfo( |
| 2273 event.newDirEntry); | 2241 event.newDirEntry); |
| 2274 | 2242 |
| 2275 // If volume has changed, then update the gear menu. | 2243 // If volume has changed, then update the gear menu. |
| (...skipping 1377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3653 callback(this.preferences_); | 3621 callback(this.preferences_); |
| 3654 return; | 3622 return; |
| 3655 } | 3623 } |
| 3656 | 3624 |
| 3657 chrome.fileBrowserPrivate.getPreferences(function(prefs) { | 3625 chrome.fileBrowserPrivate.getPreferences(function(prefs) { |
| 3658 this.preferences_ = prefs; | 3626 this.preferences_ = prefs; |
| 3659 callback(prefs); | 3627 callback(prefs); |
| 3660 }.bind(this)); | 3628 }.bind(this)); |
| 3661 }; | 3629 }; |
| 3662 })(); | 3630 })(); |
| OLD | NEW |