Chromium Code Reviews| 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 | |
|
hirono
2014/01/23 05:35:57
How about using Promise here? There are many fallb
mtomasz
2014/01/23 06:27:04
I think using Promise here would make the code muc
hirono
2014/01/23 06:43:18
SGTM!
| |
| 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 console.log(nextCurrentDirEntry, selectionEntry); |
|
kinaba
2014/01/23 04:58:02
Don't forget to remove these debug logs.
mtomasz
2014/01/23 06:27:04
Done.
| |
| 1419 defaultDisplayRoot = displayRoot; | 1412 // TODO(mtomasz): Migrate to URLs, and stop calling resolveAbsolutePath. |
| 1413 if (!this.initSelectionPath_) { | |
| 1414 callback(); | |
| 1415 return; | |
| 1416 } | |
| 1417 this.volumeManager_.resolveAbsolutePath( | |
| 1418 this.initSelectionPath_, | |
| 1419 function(inEntry) { | |
| 1420 var locationInfo = this.volumeManager_.getLocationInfo(inEntry); | |
| 1421 // If the selection is root, then use it as a current directory | |
| 1422 // instead. This is because, selecting a root entry is done as | |
| 1423 // opening it. | |
| 1424 console.log(locationInfo); | |
| 1425 if (locationInfo && locationInfo.isRootEntry) | |
| 1426 nextCurrentDirEntry = inEntry; | |
| 1427 else | |
| 1428 selectionEntry = inEntry; | |
| 1429 callback(); | |
| 1430 }.bind(this), callback); | |
| 1431 }.bind(this)); | |
| 1432 // Resolve the currentDirectoryPath to currentDirectoryEntry (if not done | |
| 1433 // by the previous step). | |
| 1434 queue.run(function(callback) { | |
| 1435 console.log(nextCurrentDirEntry, selectionEntry); | |
| 1436 if (nextCurrentDirEntry || !this.initCurrentDirectoryPath_) { | |
| 1437 callback(); | |
| 1438 return; | |
| 1439 } | |
| 1440 // TODO(mtomasz): Migrate to URLs, and stop calling resolveAbsolutePath. | |
| 1441 this.volumeManager_.resolveAbsolutePath( | |
| 1442 this.initCurrentDirectoryPath_, | |
| 1443 function(inEntry) { | |
| 1444 nextCurrentDirEntry = inEntry; | |
| 1445 callback(); | |
| 1446 }, callback); | |
| 1447 // TODO(mtomasz): Implement reopening on special search, when fake | |
| 1448 // entries are converted to directory providers. | |
| 1449 }.bind(this)); | |
| 1450 | |
| 1451 // If the directory to be changed to is not available, then first fallback | |
| 1452 // to the parent of the selection entry. | |
| 1453 queue.run(function(callback) { | |
| 1454 console.log(nextCurrentDirEntry, selectionEntry); | |
| 1455 if (nextCurrentDirEntry || !selectionEntry) { | |
| 1456 callback(); | |
| 1457 return; | |
| 1458 } | |
| 1459 selectionEntry.getParent(function(inEntry) { | |
| 1460 nextCurrentDirEntry = inEntry; | |
| 1420 callback(); | 1461 callback(); |
| 1421 }.bind(this)); | 1462 }.bind(this)); |
| 1422 }.bind(this)); | 1463 }.bind(this)); |
| 1423 | 1464 |
| 1424 // Resolve the default path. | 1465 // If the directory to be changed to is still not resolved, then fallback |
| 1425 var defaultFullPath; | 1466 // to the default display root. |
| 1426 var candidateFullPath; | |
| 1427 var candidateEntry; | |
| 1428 queue.run(function(callback) { | 1467 queue.run(function(callback) { |
| 1429 // Cancel this sequence if the current directory has already changed. | 1468 console.log(nextCurrentDirEntry, selectionEntry); |
| 1430 if (tracker.hasChanged) { | 1469 if (nextCurrentDirEntry) { |
| 1431 callback(); | 1470 callback(); |
| 1432 return; | 1471 return; |
| 1433 } | 1472 } |
| 1434 | 1473 this.volumeManager_.getDefaultDisplayRoot(function(displayRoot) { |
| 1435 // Resolve the absolute path in case only the file name or an empty string | 1474 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(); | 1475 callback(); |
| 1485 }, function() { | 1476 }.bind(this)); |
| 1486 callback(); | |
| 1487 }); | |
| 1488 }.bind(this)); | 1477 }.bind(this)); |
| 1489 | 1478 |
| 1490 // Check the obtained entry. | 1479 // If selection failed to be resolved (eg. didn't exist, in case of saving |
| 1491 var nextCurrentDirEntry; | 1480 // a file, or in case of a fallback of the current directory, then try to |
| 1492 var selectionEntry = null; | 1481 // resolve again using the target name. |
| 1493 var suggestedName = null; | |
| 1494 var error = null; | |
| 1495 queue.run(function(callback) { | 1482 queue.run(function(callback) { |
| 1496 // Cancel this sequence if the current directory has already changed. | 1483 console.log(nextCurrentDirEntry, selectionEntry); |
| 1497 if (tracker.hasChanged) { | 1484 if (selectionEntry || !nextCurrentDirEntry || !this.initTargetName_) { |
| 1498 callback(); | 1485 callback(); |
| 1499 return; | 1486 return; |
| 1500 } | 1487 } |
| 1501 | 1488 // Try to resolve as a file first. If it fails, then as a directory. |
| 1502 if (candidateEntry) { | 1489 nextCurrentDirEntry.getFile( |
| 1503 // The entry is directory. Use it. | 1490 this.initTargetName_, |
| 1504 if (candidateEntry.isDirectory) { | 1491 {}, |
| 1505 nextCurrentDirEntry = candidateEntry; | 1492 function(targetEntry) { |
| 1506 callback(); | 1493 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(); | 1494 callback(); |
| 1535 }, | 1495 }, function() { |
| 1536 callback); // In case of an error, continue. | 1496 // Failed to resolve as a file |
| 1497 nextCurrentDirEntry.getDirectory( | |
| 1498 this.initTargetName_, | |
| 1499 {}, | |
| 1500 function(targetEntry) { | |
| 1501 selectionEntry = targetEntry; | |
| 1502 callback(); | |
| 1503 }, function() { | |
| 1504 // Failed to resolve as either file or directory. | |
| 1505 callback(); | |
| 1506 }); | |
| 1507 }.bind(this)); | |
| 1537 }.bind(this)); | 1508 }.bind(this)); |
| 1538 | 1509 |
| 1539 // If the directory is not set at this stage, fallback to the default | 1510 |
| 1540 // mount point. | 1511 // Finalize. |
| 1541 queue.run(function(callback) { | 1512 queue.run(function(callback) { |
| 1542 // Check error. | 1513 console.log(nextCurrentDirEntry, selectionEntry); |
| 1543 if (error) { | |
| 1544 callback(); | |
| 1545 throw error; | |
| 1546 } | |
| 1547 // Check directory change. | 1514 // Check directory change. |
| 1548 tracker.stop(); | 1515 tracker.stop(); |
| 1549 if (tracker.hasChanged) { | 1516 if (tracker.hasChanged) { |
| 1550 callback(); | 1517 callback(); |
| 1551 return; | 1518 return; |
| 1552 } | 1519 } |
| 1553 // Finish setup current directory. | 1520 // Finish setup current directory. |
| 1554 this.finishSetupCurrentDirectory_( | 1521 this.finishSetupCurrentDirectory_( |
| 1555 nextCurrentDirEntry || defaultDisplayRoot, | 1522 nextCurrentDirEntry, |
| 1556 selectionEntry, | 1523 selectionEntry, |
| 1557 suggestedName); | 1524 this.initTargetName_); |
| 1558 callback(); | 1525 callback(); |
| 1559 }.bind(this)); | 1526 }.bind(this)); |
| 1560 }; | 1527 }; |
| 1561 | 1528 |
| 1562 /** | 1529 /** |
| 1563 * @param {DirectoryEntry} directoryEntry Directory to be opened. | 1530 * @param {DirectoryEntry} directoryEntry Directory to be opened. |
| 1564 * @param {Entry=} opt_selectionEntry Entry to be selected. | 1531 * @param {Entry=} opt_selectionEntry Entry to be selected. |
| 1565 * @param {string=} opt_suggestedName Suggested name for a non-existing\ | 1532 * @param {string=} opt_suggestedName Suggested name for a non-existing\ |
| 1566 * selection. | 1533 * selection. |
| 1567 * @private | 1534 * @private |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 1579 } | 1546 } |
| 1580 | 1547 |
| 1581 if (this.dialogType === DialogType.FULL_PAGE) { | 1548 if (this.dialogType === DialogType.FULL_PAGE) { |
| 1582 // In the FULL_PAGE mode if the restored path points to a file we might | 1549 // In the FULL_PAGE mode if the restored path points to a file we might |
| 1583 // have to invoke a task after selecting it. | 1550 // have to invoke a task after selecting it. |
| 1584 if (this.params_.action === 'select') | 1551 if (this.params_.action === 'select') |
| 1585 return; | 1552 return; |
| 1586 | 1553 |
| 1587 var task = null; | 1554 var task = null; |
| 1588 // Handle restoring after crash, or the gallery action. | 1555 // Handle restoring after crash, or the gallery action. |
| 1556 // TODO(mtomasz): Use the gallery action instead of just the gallery | |
| 1557 // field. | |
| 1589 if (this.params_.gallery || this.params_.action === 'gallery') { | 1558 if (this.params_.gallery || this.params_.action === 'gallery') { |
| 1590 if (!opt_selectionEntry) { | 1559 if (!opt_selectionEntry) { |
| 1591 // Non-existent file or a directory. | 1560 // Non-existent file or a directory. |
| 1592 // Reloading while the Gallery is open with empty or multiple | 1561 // Reloading while the Gallery is open with empty or multiple |
| 1593 // selection. Open the Gallery when the directory is scanned. | 1562 // selection. Open the Gallery when the directory is scanned. |
| 1594 task = function() { | 1563 task = function() { |
| 1595 new FileTasks(this, this.params_).openGallery([]); | 1564 new FileTasks(this, this.params_).openGallery([]); |
| 1596 }.bind(this); | 1565 }.bind(this); |
| 1597 } else { | 1566 } else { |
| 1598 // The file or the directory exists. | 1567 // The file or the directory exists. |
| 1599 task = function() { | 1568 task = function() { |
| 1600 // TODO(mtomasz): Replace the url with an entry. | |
| 1601 new FileTasks(this, this.params_).openGallery([opt_selectionEntry]); | 1569 new FileTasks(this, this.params_).openGallery([opt_selectionEntry]); |
| 1602 }.bind(this); | 1570 }.bind(this); |
| 1603 } | 1571 } |
| 1604 } else { | 1572 } else { |
| 1605 // TODO(mtomasz): Implement remounting archives after crash. | 1573 // TODO(mtomasz): Implement remounting archives after crash. |
| 1606 // See: crbug.com/333139 | 1574 // See: crbug.com/333139 |
| 1607 } | 1575 } |
| 1608 | 1576 |
| 1609 // If there is a task to be run, run it after the scan is completed. | 1577 // If there is a task to be run, run it after the scan is completed. |
| 1610 if (task) { | 1578 if (task) { |
| 1611 var listener = function() { | 1579 var listener = function() { |
| 1580 if (!util.isSameEntry(this.directoryModel_.getCurrentDirEntry(), | |
| 1581 directoryEntry)) { | |
| 1582 // Opened on a different path. Probably fallbacked. Therefore, | |
| 1583 // do not invoke a task. | |
| 1584 return; | |
| 1585 } | |
| 1612 this.directoryModel_.removeEventListener( | 1586 this.directoryModel_.removeEventListener( |
| 1613 'scan-completed', listener); | 1587 'scan-completed', listener); |
| 1614 task(); | 1588 task(); |
| 1615 }.bind(this); | 1589 }.bind(this); |
| 1616 this.directoryModel_.addEventListener('scan-completed', listener); | 1590 this.directoryModel_.addEventListener('scan-completed', listener); |
| 1617 } | 1591 } |
| 1618 } else if (this.dialogType === DialogType.SELECT_SAVEAS_FILE) { | 1592 } else if (this.dialogType === DialogType.SELECT_SAVEAS_FILE) { |
| 1619 this.filenameInput_.value = opt_suggestedName || ''; | 1593 this.filenameInput_.value = opt_suggestedName || ''; |
| 1620 this.selectDefaultPathInFilenameInput_(); | 1594 this.selectTargetNameInFilenameInput_(); |
| 1621 } | 1595 } |
| 1622 }; | 1596 }; |
| 1623 | 1597 |
| 1624 /** | 1598 /** |
| 1625 * @private | 1599 * @private |
| 1626 */ | 1600 */ |
| 1627 FileManager.prototype.refreshCurrentDirectoryMetadata_ = function() { | 1601 FileManager.prototype.refreshCurrentDirectoryMetadata_ = function() { |
| 1628 var entries = this.directoryModel_.getFileList().slice(); | 1602 var entries = this.directoryModel_.getFileList().slice(); |
| 1629 var directoryEntry = this.directoryModel_.getCurrentDirEntry(); | 1603 var directoryEntry = this.directoryModel_.getCurrentDirEntry(); |
| 1630 if (!directoryEntry) | 1604 if (!directoryEntry) |
| (...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2037 FileManager.prototype.blinkListItem_ = function(listItem) { | 2011 FileManager.prototype.blinkListItem_ = function(listItem) { |
| 2038 listItem.classList.add('blink'); | 2012 listItem.classList.add('blink'); |
| 2039 setTimeout(function() { | 2013 setTimeout(function() { |
| 2040 listItem.classList.remove('blink'); | 2014 listItem.classList.remove('blink'); |
| 2041 }, 100); | 2015 }, 100); |
| 2042 }; | 2016 }; |
| 2043 | 2017 |
| 2044 /** | 2018 /** |
| 2045 * @private | 2019 * @private |
| 2046 */ | 2020 */ |
| 2047 FileManager.prototype.selectDefaultPathInFilenameInput_ = function() { | 2021 FileManager.prototype.selectTargetNameInFilenameInput_ = function() { |
| 2048 var input = this.filenameInput_; | 2022 var input = this.filenameInput_; |
| 2049 input.focus(); | 2023 input.focus(); |
| 2050 var selectionEnd = input.value.lastIndexOf('.'); | 2024 var selectionEnd = input.value.lastIndexOf('.'); |
| 2051 if (selectionEnd == -1) { | 2025 if (selectionEnd == -1) { |
| 2052 input.select(); | 2026 input.select(); |
| 2053 } else { | 2027 } else { |
| 2054 input.selectionStart = 0; | 2028 input.selectionStart = 0; |
| 2055 input.selectionEnd = selectionEnd; | 2029 input.selectionEnd = selectionEnd; |
| 2056 } | 2030 } |
| 2057 // Clear, so we never do this again. | |
| 2058 this.defaultPath = ''; | |
| 2059 }; | 2031 }; |
| 2060 | 2032 |
| 2061 /** | 2033 /** |
| 2062 * Handles mouse click or tap. | 2034 * Handles mouse click or tap. |
| 2063 * | 2035 * |
| 2064 * @param {Event} event The click event. | 2036 * @param {Event} event The click event. |
| 2065 * @private | 2037 * @private |
| 2066 */ | 2038 */ |
| 2067 FileManager.prototype.onDetailClick_ = function(event) { | 2039 FileManager.prototype.onDetailClick_ = function(event) { |
| 2068 if (this.isRenamingInProgress()) { | 2040 if (this.isRenamingInProgress()) { |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2254 /** | 2226 /** |
| 2255 * Update the UI when the current directory changes. | 2227 * Update the UI when the current directory changes. |
| 2256 * | 2228 * |
| 2257 * @param {Event} event The directory-changed event. | 2229 * @param {Event} event The directory-changed event. |
| 2258 * @private | 2230 * @private |
| 2259 */ | 2231 */ |
| 2260 FileManager.prototype.onDirectoryChanged_ = function(event) { | 2232 FileManager.prototype.onDirectoryChanged_ = function(event) { |
| 2261 this.selectionHandler_.onFileSelectionChanged(); | 2233 this.selectionHandler_.onFileSelectionChanged(); |
| 2262 this.ui_.searchBox.clear(); | 2234 this.ui_.searchBox.clear(); |
| 2263 // TODO(mtomasz): Use Entry.toURL() instead of fullPath. | 2235 // TODO(mtomasz): Use Entry.toURL() instead of fullPath. |
| 2236 // TODO(mtomasz): Consider remembering the selection. | |
| 2264 util.updateAppState( | 2237 util.updateAppState( |
| 2265 this.getCurrentDirectoryEntry() && | 2238 this.getCurrentDirectoryEntry() ? |
| 2266 this.getCurrentDirectoryEntry().fullPath, '' /* opt_param */); | 2239 this.getCurrentDirectoryEntry().fullPath : '', |
| 2240 '' /* selectionPath */, | |
| 2241 '' /* opt_param */); | |
| 2267 | 2242 |
| 2268 // If the current directory is moved from the device's volume, do not | 2243 // If the current directory is moved from the device's volume, do not |
| 2269 // automatically close the window on device removal. | 2244 // automatically close the window on device removal. |
| 2270 if (event.previousDirEntry && | 2245 if (event.previousDirEntry && |
| 2271 PathUtil.getRootPath(event.previousDirEntry.fullPath) != | 2246 PathUtil.getRootPath(event.previousDirEntry.fullPath) != |
| 2272 PathUtil.getRootPath(event.newDirEntry.fullPath)) | 2247 PathUtil.getRootPath(event.newDirEntry.fullPath)) |
| 2273 this.closeOnUnmount_ = false; | 2248 this.closeOnUnmount_ = false; |
| 2274 | 2249 |
| 2275 if (this.commandHandler) | 2250 if (this.commandHandler) |
| 2276 this.commandHandler.updateAvailability(); | 2251 this.commandHandler.updateAvailability(); |
| (...skipping 1373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3650 callback(this.preferences_); | 3625 callback(this.preferences_); |
| 3651 return; | 3626 return; |
| 3652 } | 3627 } |
| 3653 | 3628 |
| 3654 chrome.fileBrowserPrivate.getPreferences(function(prefs) { | 3629 chrome.fileBrowserPrivate.getPreferences(function(prefs) { |
| 3655 this.preferences_ = prefs; | 3630 this.preferences_ = prefs; |
| 3656 callback(prefs); | 3631 callback(prefs); |
| 3657 }.bind(this)); | 3632 }.bind(this)); |
| 3658 }; | 3633 }; |
| 3659 })(); | 3634 })(); |
| OLD | NEW |