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