1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// WK Bug 55728 is fixed on the chrome 12 branch but not on the trunk.
6ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// TODO(rginda): Enable this everywhere once we have a trunk-worthy fix.
7ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst ENABLE_EXIF_READER = navigator.userAgent.match(/chrome\/12\.0/i);
8ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
9ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Thumbnail view is painful without the exif reader.
10ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst ENABLE_THUMBNAIL_VIEW = ENABLE_EXIF_READER;
11ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
12ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvar g_slideshow_data = null;
13ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
14ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen/**
15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * FileManager constructor.
16ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen *
17ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * FileManager objects encapsulate the functionality of the file selector
18ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * dialogs, as well as the full screen file manager application (though the
19ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * latter is not yet implemented).
20ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen *
21ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * @param {HTMLElement} dialogDom The DOM node containing the prototypical
22ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen *     dialog UI.
23ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * @param {DOMFileSystem} filesystem The HTML5 filesystem object representing
24ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen *     the root filesystem for the new FileManager.
25ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * @param {Object} params A map of parameter names to values controlling the
26ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen *     appearance of the FileManager.  Names are:
27ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen *     - type: A value from FileManager.DialogType defining what kind of
28ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen *       dialog to present.  Defaults to FULL_PAGE.
29ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen *     - title: The title for the dialog.  Defaults to a localized string based
30ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen *       on the dialog type.
31ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen *     - defaultPath: The default path for the dialog.  The default path should
32ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen *       end with a trailing slash if it represents a directory.
33ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen */
34ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenfunction FileManager(dialogDom, rootEntries, params) {
35ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  console.log('Init FileManager: ' + dialogDom);
36ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
37ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  this.dialogDom_ = dialogDom;
38ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  this.rootEntries_ = rootEntries;
39ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  this.filesystem_ = rootEntries[0].filesystem;
40ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  this.params_ = params || {};
41ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
42ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  this.listType_ = null;
43ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
44ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  this.exifCache_ = {};
45ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
46ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // True if we should filter out files that start with a dot.
47ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  this.filterFiles_ = true;
48ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
49ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  this.commands_ = {};
50ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
51ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  this.document_ = dialogDom.ownerDocument;
52ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  this.dialogType_ =
53ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.params_.type || FileManager.DialogType.FULL_PAGE;
54ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
55ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  this.defaultPath_ = this.params_.defaultPath || '/';
56ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
57ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // This is set to just the directory portion of defaultPath in initDialogType.
58ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  this.defaultFolder_ = '/';
59ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
60ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  this.showCheckboxes_ =
61ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      (this.dialogType_ == FileManager.DialogType.FULL_PAGE ||
62ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen       this.dialogType_ == FileManager.DialogType.SELECT_OPEN_MULTI_FILE);
63ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
64ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // DirectoryEntry representing the current directory of the dialog.
65ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  this.currentDirEntry_ = null;
66ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
67ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  window.addEventListener('popstate', this.onPopState_.bind(this));
68ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  this.addEventListener('directory-changed',
69ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                        this.onDirectoryChanged_.bind(this));
70ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  this.addEventListener('selection-summarized',
71ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                        this.onSelectionSummarized_.bind(this));
72ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
73ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  this.initCommands_();
74ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  this.initDom_();
75ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  this.initDialogType_();
76ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
77ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  this.summarizeSelection_();
78ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  this.updatePreview_();
79ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  this.changeDirectory(this.defaultFolder_);
80ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
81ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  chrome.fileBrowserPrivate.onDiskChanged.addListener(
82ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.onDiskChanged_.bind(this));
83ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
84ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  this.table_.list_.focus();
85ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
86ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (ENABLE_EXIF_READER) {
87ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.exifReader = new Worker('js/exif_reader.js');
88ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.exifReader.onmessage = this.onExifReaderMessage_.bind(this);
89ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.exifReader.postMessage({verb: 'init'});
90ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
91dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
92ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
93ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenFileManager.prototype = {
94ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  __proto__: cr.EventTarget.prototype
95ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen};
96ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
97ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Anonymous "namespace".
98ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen(function() {
99ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
100ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Private variables and helper functions.
101ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
102ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  /**
103ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * Unicode codepoint for 'BLACK RIGHT-POINTING SMALL TRIANGLE'.
104ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   */
105ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  const RIGHT_TRIANGLE = '\u25b8';
106ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
107ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  /**
108ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * The DirectoryEntry.fullPath value of the directory containing external
109ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * storage volumes.
110ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   */
111ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  const MEDIA_DIRECTORY = '/media';
112ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
113ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  /**
114ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * Translated strings.
115ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   */
116ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  var localStrings;
117ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
118ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  /**
119ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * Map of icon types to regular expressions.
120ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   *
121ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * The first regexp to match the file name determines the icon type
122ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * assigned to dom elements for a file.  Order of evaluation is not
123ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * defined, so don't depend on it.
124ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   */
125ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  const iconTypes = {
126ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    'audio': /\.(mp3|m4a|oga|ogg|wav)$/i,
127ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    'html': /\.(html?)$/i,
128ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    'image': /\.(bmp|gif|jpe?g|ico|png|webp)$/i,
129ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    'pdf' : /\.(pdf)$/i,
130ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    'text': /\.(pod|rst|txt|log)$/i,
131ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    'video': /\.(mov|mp4|m4v|mpe?g4?|ogm|ogv|ogx|webm)$/i
132ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
133ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
134ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  const previewArt = {
135ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    'audio': 'images/filetype_large_audio.png',
136ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    'folder': 'images/filetype_large_folder.png',
137ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    'unknown': 'images/filetype_large_generic.png',
138ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    'video': 'images/filetype_large_video.png'
139ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
140ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
141ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  /**
142ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * Return a translated string.
143ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   *
144ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * Wrapper function to make dealing with translated strings more concise.
145ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * Equivilant to localStrings.getString(id).
146ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   *
147ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * @param {string} id The id of the string to return.
148ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * @return {string} The translated string.
149ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   */
150ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  function str(id) {
151ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return localStrings.getString(id);
152ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
153ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
154ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  /**
155ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * Return a translated string with arguments replaced.
156ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   *
157ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * Wrapper function to make dealing with translated strings more concise.
158ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * Equivilant to localStrings.getStringF(id, ...).
159ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   *
160ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * @param {string} id The id of the string to return.
161ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * @param {...string} The values to replace into the string.
162ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * @return {string} The translated string with replaced values.
163ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   */
164ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  function strf(id, var_args) {
165ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return localStrings.getStringF.apply(localStrings, arguments);
166ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
167ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
168ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  /**
169ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * Checks if |parent_path| is parent file path of |child_path|.
170ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   *
171ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * @param {string} parent_path The parent path.
172ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * @param {string} child_path The child path.
173ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   */
174ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  function isParentPath(parent_path, child_path) {
175ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (!parent_path || parent_path.length == 0 ||
176ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        !child_path || child_path.length == 0)
177ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return false;
178ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
179ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (parent_path[parent_path.length -1] != '/')
180ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      parent_path += '/';
181ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
182ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (child_path[child_path.length -1] != '/')
183ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      child_path += '/';
184ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
185ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return child_path.indexOf(parent_path) == 0;
186ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
187ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
188ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  /**
189ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * Returns parent folder path of file path.
190ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   *
191ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * @param {string} path The file path.
192ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   */
193ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  function getParentPath(path) {
194ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var parent = path.replace(/[\/]?[^\/]+[\/]?$/,'');
195ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (parent.length == 0)
196ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      parent = '/';
197ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return parent;
198ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
199ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
200ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  /**
201ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * Get the icon type for a given Entry.
202ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   *
203ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * @param {Entry} entry An Entry subclass (FileEntry or DirectoryEntry).
204ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * @return {string} One of the keys from FileManager.iconTypes, or
205ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   *     'unknown'.
206ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   */
207ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  function getIconType(entry) {
208ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (entry.cachedIconType_)
209ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return entry.cachedIconType_;
210ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
211ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var rv = 'unknown';
212ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
213ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (entry.isDirectory) {
214ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      rv = 'folder';
215ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    } else {
216ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      for (var name in iconTypes) {
217ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        var value = iconTypes[name];
218ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
219ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        if (value instanceof RegExp) {
220ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          if (value.test(entry.name))  {
221ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            rv = name;
222ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            break;
223ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          }
224ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        } else if (typeof value == 'function') {
225ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          try {
226ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            if (value(entry)) {
227ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen              rv = name;
228ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen              break;
229ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            }
230ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          } catch (ex) {
231ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            console.error('Caught exception while evaluating iconType: ' +
232ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                          name, ex);
233ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          }
234ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        } else {
235ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          console.log('Unexpected value in iconTypes[' + name + ']: ' + value);
236ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        }
237ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
238ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
239ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
240ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    entry.cachedIconType_ = rv;
241ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return rv;
242ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
243ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
244ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  /**
245ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * Call an asynchronous method on dirEntry, batching multiple callers.
246ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   *
247ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * This batches multiple callers into a single invocation, calling all
248ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * interested parties back when the async call completes.
249ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   *
250ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * The Entry method to be invoked should take two callbacks as parameters
251ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * (one for success and one for failure), and it should invoke those
252ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * callbacks with a single parameter representing the result of the call.
253ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * Example methods are Entry.getMetadata() and FileEntry.file().
254ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   *
255ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * Warning: Because this method caches the first result, subsequent changes
256ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * to the entry will not be visible to callers.
257ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   *
258ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * Error results are never cached.
259ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   *
260ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * @param {DirectoryEntry} dirEntry The DirectoryEntry to apply the method
261ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   *     to.
262ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * @param {string} methodName The name of the method to dispatch.
263ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * @param {function(*)} successCallback The function to invoke if the method
264ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   *     succeeds.  The result of the method will be the one parameter to this
265ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   *     callback.
266ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * @param {function(*)} opt_errorCallback The function to invoke if the
267ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   *     method fails.  The result of the method will be the one parameter to
268ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   *     this callback.  If not provided, the default errorCallback will throw
269ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   *     an exception.
270ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   */
271ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  function batchAsyncCall(entry, methodName, successCallback,
272ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                          opt_errorCallback) {
273ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var resultCache = methodName + '_resultCache_';
274ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
275ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (entry[resultCache]) {
276ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // The result cache for this method already exists.  Just invoke the
277ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // successCallback with the result of the previuos call.
278ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // Callback via a setTimeout so the sync/async semantics don't change
279ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // based on whether or not the value is cached.
280ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      setTimeout(function() { successCallback(entry[resultCache]) }, 0);
281ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return;
282ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
283ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
284ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (!opt_errorCallback) {
285ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      opt_errorCallback = util.ferr('Error calling ' + methodName + ' for: ' +
286ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                    entry.fullPath);
287ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
288ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
289ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var observerList = methodName + '_observers_';
290ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
291ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (entry[observerList]) {
292ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // The observer list already exists, indicating we have a pending call
293ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // out to this method.  Add this caller to the list of observers and
294ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // bail out.
295ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      entry[observerList].push([successCallback, opt_errorCallback]);
296ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return;
297ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
298ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
299ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    entry[observerList] = [[successCallback, opt_errorCallback]];
300ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
301ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    function onComplete(success, result) {
302ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (success)
303ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        entry[resultCache] = result;
304ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
305ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      for (var i = 0; i < entry[observerList].length; i++) {
306ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        entry[observerList][i][success ? 0 : 1](result);
307ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
308ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
309ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      delete entry[observerList];
310ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    };
311ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
312ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    entry[methodName](function(rv) { onComplete(true, rv) },
313ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                      function(rv) { onComplete(false, rv) });
314ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
315ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
316ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  /**
317ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * Get the size of a file, caching the result.
318ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   *
319ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * When this method completes, the fileEntry object will get a
320ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * 'cachedSize_' property (if it doesn't already have one) containing the
321ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * size of the file in bytes.
322ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   *
323ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * @param {Entry} entry An HTML5 Entry object.
324ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * @param {function(Entry)} successCallback The function to invoke once the
325ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   *     file size is known.
326ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   */
327ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  function cacheEntrySize(entry, successCallback) {
328ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (entry.isDirectory) {
329ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // No size for a directory, -1 ensures it's sorted before 0 length files.
330ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      entry.cachedSize_ = -1;
331ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
332ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
333ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if ('cachedSize_' in entry) {
334ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (successCallback) {
335ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        // Callback via a setTimeout so the sync/async semantics don't change
336ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        // based on whether or not the value is cached.
337ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        setTimeout(function() { successCallback(entry) }, 0);
338ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
339ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return;
340ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
341ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
342ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    batchAsyncCall(entry, 'file', function(file) {
343ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      entry.cachedSize_ = file.size;
344ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (successCallback)
345ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        successCallback(entry);
346ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    });
347ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
348ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
349ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  /**
350ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * Get the mtime of a file, caching the result.
351ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   *
352ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * When this method completes, the fileEntry object will get a
353ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * 'cachedMtime_' property (if it doesn't already have one) containing the
354ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * last modified time of the file as a Date object.
355ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   *
356ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * @param {Entry} entry An HTML5 Entry object.
357ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * @param {function(Entry)} successCallback The function to invoke once the
358ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   *     mtime is known.
359ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   */
360ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  function cacheEntryDate(entry, successCallback) {
361ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if ('cachedMtime_' in entry) {
362ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (successCallback) {
363ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        // Callback via a setTimeout so the sync/async semantics don't change
364ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        // based on whether or not the value is cached.
365ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        setTimeout(function() { successCallback(entry) }, 0);
366ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
367ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return;
368ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
369ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
370ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (entry.isFile) {
371ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      batchAsyncCall(entry, 'file', function(file) {
372ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        entry.cachedMtime_ = file.lastModifiedDate;
373ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        if (successCallback)
374ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          successCallback(entry);
375ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      });
376ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    } else {
377ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      batchAsyncCall(entry, 'getMetadata', function(metadata) {
378ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        entry.cachedMtime_ = metadata.modificationTime;
379ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        if (successCallback)
380ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          successCallback(entry);
381ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      });
382ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
383ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
384ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
385ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  /**
386ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * Get the icon type of a file, caching the result.
387ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   *
388ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * When this method completes, the fileEntry object will get a
389ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * 'cachedIconType_' property (if it doesn't already have one) containing the
390ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * icon type of the file as a string.
391ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   *
392ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * The successCallback is always invoked synchronously, since this does not
393ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * actually require an async call.  You should not depend on this, as it may
394ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * change if we were to start reading magic numbers (for example).
395ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   *
396ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * @param {Entry} entry An HTML5 Entry object.
397ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * @param {function(Entry)} successCallback The function to invoke once the
398ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   *     icon type is known.
399ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   */
400ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  function cacheEntryIconType(entry, successCallback) {
401ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    getIconType(entry);
402ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (successCallback)
403ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      setTimeout(function() { successCallback(entry) }, 0);
404ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
405ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
406ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Public statics.
407ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
408ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  /**
409ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * List of dialog types.
410ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   *
411ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * Keep this in sync with FileManagerDialog::GetDialogTypeAsString, except
412ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * FULL_PAGE which is specific to this code.
413ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   *
414ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * @enum {string}
415ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   */
416ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.DialogType = {
417ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    SELECT_FOLDER: 'folder',
418ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    SELECT_SAVEAS_FILE: 'saveas-file',
419ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    SELECT_OPEN_FILE: 'open-file',
420ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    SELECT_OPEN_MULTI_FILE: 'open-multi-file',
421ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    FULL_PAGE: 'full-page'
422ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
423ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
424ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.ListType = {
425ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DETAIL: 'detail',
426ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    THUMBNAIL: 'thumb'
427ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
428ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
429ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  /**
430ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * Load translated strings.
431ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   */
432ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.initStrings = function(callback) {
433ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    chrome.fileBrowserPrivate.getStrings(function(strings) {
434ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      localStrings = new LocalStrings(strings);
435ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      cr.initLocale(strings);
436ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
437ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (callback)
438ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        callback();
439ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    });
440ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
441ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
442ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Instance methods.
443ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
444ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  /**
445ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * One-time initialization of commands.
446ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   */
447ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.initCommands_ = function() {
448ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var commands = this.dialogDom_.querySelectorAll('command');
449ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    for (var i = 0; i < commands.length; i++) {
450ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      var command = commands[i];
451ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      cr.ui.Command.decorate(command);
452ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.commands_[command.id] = command;
453ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
454ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
455ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.fileContextMenu_ = this.dialogDom_.querySelector('.file-context-menu');
456ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    cr.ui.Menu.decorate(this.fileContextMenu_);
457ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
458ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.document_.addEventListener(
459ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        'canExecute', this.onRenameCanExecute_.bind(this));
460ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.document_.addEventListener(
461ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        'canExecute', this.onDeleteCanExecute_.bind(this));
462ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
463ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.document_.addEventListener('command', this.onCommand_.bind(this));
464ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
465ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
466ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  /**
467ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * One-time initialization of various DOM nodes.
468ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   */
469ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.initDom_ = function() {
470ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Cache nodes we'll be manipulating.
471ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.previewImage_ = this.dialogDom_.querySelector('.preview-img');
472ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.previewFilename_ = this.dialogDom_.querySelector('.preview-filename');
473ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.previewSummary_ = this.dialogDom_.querySelector('.preview-summary');
474ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.filenameInput_ = this.dialogDom_.querySelector('.filename-input');
475ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.taskButtons_ = this.dialogDom_.querySelector('.task-buttons');
476ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.okButton_ = this.dialogDom_.querySelector('.ok');
477ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.cancelButton_ = this.dialogDom_.querySelector('.cancel');
478ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.newFolderButton_ = this.dialogDom_.querySelector('.new-folder');
479ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
480ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.renameInput_ = this.document_.createElement('input');
481ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.renameInput_.className = 'rename';
482ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
483ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.renameInput_.addEventListener(
484ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        'keydown', this.onRenameInputKeyDown_.bind(this));
485ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.renameInput_.addEventListener(
486ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        'blur', this.onRenameInputBlur_.bind(this));
487ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
488ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.filenameInput_.addEventListener(
489ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        'keyup', this.onFilenameInputKeyUp_.bind(this));
490ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.filenameInput_.addEventListener(
491ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        'focus', this.onFilenameInputFocus_.bind(this));
492ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
493ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.dialogDom_.addEventListener('keydown', this.onKeyDown_.bind(this));
494ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.okButton_.addEventListener('click', this.onOk_.bind(this));
495ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.cancelButton_.addEventListener('click', this.onCancel_.bind(this));
496ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
497ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.dialogDom_.querySelector('button.new-folder').addEventListener(
498ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        'click', this.onNewFolderButtonClick_.bind(this));
499ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
500ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (ENABLE_THUMBNAIL_VIEW) {
501ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.dialogDom_.querySelector('button.detail-view').addEventListener(
502ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          'click', this.onDetailViewButtonClick_.bind(this));
503ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.dialogDom_.querySelector('button.thumbnail-view').addEventListener(
504ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          'click', this.onThumbnailViewButtonClick_.bind(this));
505ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    } else {
506ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.dialogDom_.querySelector(
507ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          'button.detail-view').style.display = 'none';
508ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.dialogDom_.querySelector(
509ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          'button.thumbnail-view').style.display = 'none';
510ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
511ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
512ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.dialogDom_.ownerDocument.defaultView.addEventListener(
513ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        'resize', this.onResize_.bind(this));
514ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
515ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var ary = this.dialogDom_.querySelectorAll('[visibleif]');
516ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    for (var i = 0; i < ary.length; i++) {
517ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      var expr = ary[i].getAttribute('visibleif');
518ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (!eval(expr))
519ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        ary[i].style.display = 'none';
520ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
521ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
522ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Populate the static localized strings.
523ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    i18nTemplate.process(this.document_, localStrings.templateData);
524ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
525ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Always sharing the data model between the detail/thumb views confuses
526ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // them.  Instead we maintain this bogus data model, and hook it up to the
527ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // view that is not in use.
528ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.emptyDataModel_ = new cr.ui.table.TableDataModel([]);
529ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
530ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.dataModel_ = new cr.ui.table.TableDataModel([]);
531ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.dataModel_.sort('name');
532ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.dataModel_.addEventListener('sorted',
533ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                this.onDataModelSorted_.bind(this));
534ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.dataModel_.prepareSort = this.prepareSort_.bind(this);
535ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
536ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (this.dialogType_ == FileManager.DialogType.SELECT_OPEN_FILE ||
537ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        this.dialogType_ == FileManager.DialogType.SELECT_OPEN_FOLDER ||
538ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        this.dialogType_ == FileManager.DialogType.SELECT_SAVEAS_FILE) {
539ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.selectionModelClass_ = cr.ui.table.TableSingleSelectionModel;
540ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    } else {
541ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.selectionModelClass_ = cr.ui.table.TableSelectionModel;
542ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
543ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
544ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.initTable_();
545ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.initGrid_();
546ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
547ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.setListType(FileManager.ListType.DETAIL);
548ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
549ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.onResize_();
550ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.dialogDom_.style.opacity = '1';
551ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
552ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
553ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  /**
554ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * Force the canExecute events to be dispatched.
555ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   */
556ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.updateCommands_ = function() {
557ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.commands_['rename'].canExecuteChange();
558ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.commands_['delete'].canExecuteChange();
559ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
560ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
561ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  /**
562ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * Invoked to decide whether the "rename" command can be executed.
563ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   */
564ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.onRenameCanExecute_ = function(event) {
565ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    event.canExecute =
566ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        (// Full page mode.
567ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen         this.dialogType_ == FileManager.DialogType.FULL_PAGE &&
568ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen         // Rename not in progress.
569ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen         !this.renameInput_.currentEntry &&
570ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen         // Not in root directory.
571ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen         this.currentDirEntry_.fullPath != '/' &&
572ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen         // Not in media directory.
573ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen         this.currentDirEntry_.fullPath != MEDIA_DIRECTORY &&
574ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen         // Only one file selected.
575ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen         this.selection.totalCount == 1);
576ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
577ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
578ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  /**
579ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * Invoked to decide whether the "delete" command can be executed.
580ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   */
581ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.onDeleteCanExecute_ = function(event) {
582ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    event.canExecute =
583ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        (// Full page mode.
584ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen         this.dialogType_ == FileManager.DialogType.FULL_PAGE &&
585ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen         // Rename not in progress.
586ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen         !this.renameInput_.currentEntry &&
587ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen         // Not in root directory.
588ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen         this.currentDirEntry_.fullPath != '/' &&
589ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen         // Not in media directory.
590ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen         this.currentDirEntry_.fullPath != MEDIA_DIRECTORY);
591ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
592ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
593ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.setListType = function(type) {
594ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (type && type == this.listType_)
595ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return;
596ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
597ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (type == FileManager.ListType.DETAIL) {
598ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.table_.dataModel = this.dataModel_;
599ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.table_.style.display = '';
600ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.grid_.style.display = 'none';
601ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.grid_.dataModel = this.emptyDataModel_;
602ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.currentList_ = this.table_;
603ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.dialogDom_.querySelector('button.detail-view').disabled = true;
604ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.dialogDom_.querySelector('button.thumbnail-view').disabled = false;
605ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    } else if (type == FileManager.ListType.THUMBNAIL) {
606ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.grid_.dataModel = this.dataModel_;
607ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.grid_.style.display = '';
608ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.table_.style.display = 'none';
609ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.table_.dataModel = this.emptyDataModel_;
610ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.currentList_ = this.grid_;
611ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.dialogDom_.querySelector('button.thumbnail-view').disabled = true;
612ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.dialogDom_.querySelector('button.detail-view').disabled = false;
613ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    } else {
614ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      throw new Error('Unknown list type: ' + type);
615ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
616ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
617ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.listType_ = type;
618ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.onResize_();
619ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
620ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
621ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  /**
622ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * Initialize the file thumbnail grid.
623ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   */
624ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.initGrid_ = function() {
625ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.grid_ = this.dialogDom_.querySelector('.thumbnail-grid');
626ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    cr.ui.Grid.decorate(this.grid_);
627ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
628ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var self = this;
629ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.grid_.itemConstructor = function(entry) {
630ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return self.renderThumbnail_(entry);
631ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    };
632ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
633ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.grid_.selectionModel = new this.selectionModelClass_();
634ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
635ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.grid_.addEventListener(
636ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        'dblclick', this.onDetailDoubleClick_.bind(this));
637ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.grid_.selectionModel.addEventListener(
638ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        'change', this.onSelectionChanged_.bind(this));
639ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
640ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (this.dialogType_ == FileManager.DialogType.FULL_PAGE) {
641ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      cr.ui.contextMenuHandler.addContextMenuProperty(this.grid_);
642ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.grid_.contextMenu = this.fileContextMenu_;
643ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
644ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
645ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.grid_.addEventListener('mousedown',
646ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                this.onGridMouseDown_.bind(this));
647ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
648ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
649ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  /**
650ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * Initialize the file list table.
651ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   */
652ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.initTable_ = function() {
653ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var checkWidth = this.showCheckboxes_ ? 5 : 0;
654ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
655ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var columns = [
656ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        new cr.ui.table.TableColumn('cachedIconType_', '',
657ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                    5.4 + checkWidth),
658ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        new cr.ui.table.TableColumn('name', str('NAME_COLUMN_LABEL'),
659ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                    64 - checkWidth),
660ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        new cr.ui.table.TableColumn('cachedSize_',
661ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                    str('SIZE_COLUMN_LABEL'), 15.5),
662ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        new cr.ui.table.TableColumn('cachedMtime_',
663ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                    str('DATE_COLUMN_LABEL'), 21)
664ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ];
665ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
666ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    columns[0].renderFunction = this.renderIconType_.bind(this);
667ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    columns[1].renderFunction = this.renderName_.bind(this);
668ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    columns[2].renderFunction = this.renderSize_.bind(this);
669ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    columns[3].renderFunction = this.renderDate_.bind(this);
670ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
671ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.table_ = this.dialogDom_.querySelector('.detail-table');
672ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    cr.ui.Table.decorate(this.table_);
673ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
674ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.table_.selectionModel = new this.selectionModelClass_();
675ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.table_.columnModel = new cr.ui.table.TableColumnModel(columns);
676ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
677ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.table_.addEventListener(
678ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        'dblclick', this.onDetailDoubleClick_.bind(this));
679ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.table_.selectionModel.addEventListener(
680ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        'change', this.onSelectionChanged_.bind(this));
681ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
682ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (this.dialogType_ == FileManager.DialogType.FULL_PAGE) {
683ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      cr.ui.contextMenuHandler.addContextMenuProperty(this.table_);
684ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.table_.contextMenu = this.fileContextMenu_;
685ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
686ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
687ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.table_.addEventListener('mousedown',
688ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                 this.onTableMouseDown_.bind(this));
689ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
690ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
691ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  /**
692ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * Respond to a command being executed.
693ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   */
694ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.onCommand_ = function(event) {
695ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    switch (event.command.id) {
696ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      case 'rename':
697ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        var leadIndex = this.currentList_.selectionModel.leadIndex;
698ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        var li = this.currentList_.getListItemByIndex(leadIndex);
699ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        var label = li.querySelector('.filename-label');
700ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        if (!label) {
701ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          console.warn('Unable to find label for rename of index: ' +
702ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                       leadIndex);
703ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          return;
704ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        }
705ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
706ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        this.initiateRename_(label);
707ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        break;
708ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
709ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      case 'delete':
710ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        this.deleteEntries(this.selection.entries);
711ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        break;
712ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
713ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
714ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
715ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  /**
716ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * Respond to the back button.
717ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   */
718ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.onPopState_ = function(event) {
719ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.changeDirectory(event.state, false);
720ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
721ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
722ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  /**
723ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * Resize details and thumb views to fit the new window size.
724ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   */
725ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.onResize_ = function() {
726ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.table_.style.height = this.grid_.style.height =
727ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.grid_.parentNode.clientHeight + 'px';
728ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.table_.style.width = this.grid_.style.width =
729ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.grid_.parentNode.clientWidth + 'px';
730ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
731ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.table_.list_.style.width = this.table_.parentNode.clientWidth + 'px';
732ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.table_.list_.style.height = (this.table_.clientHeight - 1 -
733ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                      this.table_.header_.clientHeight) + 'px';
734ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
735ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (this.listType_ == FileManager.ListType.THUMBNAIL) {
736ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      var self = this;
737ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      setTimeout(function () {
738ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          self.grid_.columns = 0;
739ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          self.grid_.redraw();
740ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }, 0);
741ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    } else {
742ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.currentList_.redraw();
743ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
744ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
745ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
746ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  /**
747ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * Tweak the UI to become a particular kind of dialog, as determined by the
748ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * dialog type parameter passed to the constructor.
749ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   */
750ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.initDialogType_ = function() {
751ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var defaultTitle;
752ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var okLabel = str('OPEN_LABEL');
753ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
754ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Split the dirname from the basename.
755ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var ary = this.defaultPath_.match(/^(.*?)(?:\/([^\/]+))?$/);
756ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var defaultFolder;
757ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var defaultTarget;
758ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
759ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (!ary) {
760ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      console.warn('Unable to split defaultPath: ' + defaultPath);
761ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      ary = [];
762ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
763ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
764ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    switch (this.dialogType_) {
765ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      case FileManager.DialogType.SELECT_FOLDER:
766ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        defaultTitle = str('SELECT_FOLDER_TITLE');
767ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        defaultFolder = ary[1] || '/';
768ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        defaultTarget = ary[2] || '';
769ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        break;
770ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
771ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      case FileManager.DialogType.SELECT_OPEN_FILE:
772ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        defaultTitle = str('SELECT_OPEN_FILE_TITLE');
773ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        defaultFolder = ary[1] || '/';
774ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        defaultTarget = '';
775ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
776ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        if (ary[2]) {
777ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          console.warn('Open should NOT have provided a default ' +
778ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                       'filename: ' + ary[2]);
779ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        }
780ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        break;
781ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
782ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      case FileManager.DialogType.SELECT_OPEN_MULTI_FILE:
783ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        defaultTitle = str('SELECT_OPEN_MULTI_FILE_TITLE');
784ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        defaultFolder = ary[1] || '/';
785ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        defaultTarget = '';
786ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
787ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        if (ary[2]) {
788ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          console.warn('Multi-open should NOT have provided a default ' +
789ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                       'filename: ' + ary[2]);
790ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        }
791ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        break;
792ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
793ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      case FileManager.DialogType.SELECT_SAVEAS_FILE:
794ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        defaultTitle = str('SELECT_SAVEAS_FILE_TITLE');
795ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        okLabel = str('SAVE_LABEL');
796ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
797ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        defaultFolder = ary[1] || '/';
798ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        defaultTarget = ary[2] || '';
799ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        if (!defaultTarget)
800ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          console.warn('Save-as should have provided a default filename.');
801ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        break;
802ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
803ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      case FileManager.DialogType.FULL_PAGE:
804ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        defaultFolder = ary[1] || '/';
805ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        defaultTarget = ary[2] || '';
806ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        break;
807ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
808ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      default:
809ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        throw new Error('Unknown dialog type: ' + this.dialogType_);
810ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
811ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
812ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.okButton_.textContent = okLabel;
813ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
814ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    dialogTitle = this.params_.title || defaultTitle;
815ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.dialogDom_.querySelector('.dialog-title').textContent = dialogTitle;
816ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
817ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ary = defaultFolder.match(/^\/home\/[^\/]+\/user\/Downloads(\/.*)?$/);
818ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (ary) {
819ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        // Chrome will probably suggest the full path to Downloads, but
820ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        // we're working with 'virtual paths', so we have to translate.
821ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        // TODO(rginda): Maybe chrome should have suggested the correct place
822ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        // to begin with, but that would mean it would have to treat the
823ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        // file manager dialogs differently than the native ones.
824ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        defaultFolder = '/Downloads' + (ary[1] || '');
825ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
826ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
827ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.defaultFolder_ = defaultFolder;
828ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.filenameInput_.value = defaultTarget;
829ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
830ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
831ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  /**
832ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * Cache necessary data before a sort happens.
833ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   *
834ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * This is called by the table code before a sort happens, so that we can
835ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * go fetch data for the sort field that we may not have yet.
836ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   */
837ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.prepareSort_ = function(field, callback) {
838ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var cacheFunction;
839ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
840ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (field == 'cachedMtime_') {
841ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      cacheFunction = cacheEntryDate;
842ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    } else if (field == 'cachedSize_') {
843ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      cacheFunction = cacheEntrySize;
844ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    } else if (field == 'cachedIconType_') {
845ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      cacheFunction = cacheEntryIconType;
846ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    } else {
847ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      callback();
848ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return;
849ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
850ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
851ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    function checkCount() {
852ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (uncachedCount == 0) {
853ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        // Callback via a setTimeout so the sync/async semantics don't change
854ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        // based on whether or not the value is cached.
855ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        setTimeout(callback, 0);
856ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
857ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
858ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
859ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var dataModel = this.dataModel_;
860ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var uncachedCount = dataModel.length;
861ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
862ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    for (var i = uncachedCount - 1; i >= 0 ; i--) {
863ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      var entry = dataModel.item(i);
864ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (field in entry) {
865ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        uncachedCount--;
866ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      } else {
867ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        cacheFunction(entry, function() {
868ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          uncachedCount--;
869ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          checkCount();
870ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        });
871ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
872ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
873ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
874ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    checkCount();
875ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
876ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
877ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  /**
878ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * Render (and wire up) a checkbox to be used in either a detail or a
879ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * thumbnail list item.
880ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   */
881ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.renderCheckbox_ = function(entry) {
882ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var input = this.document_.createElement('input');
883ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    input.setAttribute('type', 'checkbox');
884ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    input.className = 'file-checkbox';
885ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    input.addEventListener('mousedown',
886ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                           this.onCheckboxMouseDownUp_.bind(this));
887ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    input.addEventListener('mouseup',
888ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                           this.onCheckboxMouseDownUp_.bind(this));
889ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    input.addEventListener('click',
890ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                           this.onCheckboxClick_.bind(this));
891ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
892ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (this.selection && this.selection.entries.indexOf(entry) != -1) {
893ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // Our DOM nodes get discarded as soon as we're scrolled out of view,
894ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // so we have to make sure the check state is correct when we're brought
895ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // back to life.
896ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      input.checked = true;
897ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
898ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
899ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return input;
900ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
901ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
902ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.renderThumbnail_ = function(entry) {
903ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var li = this.document_.createElement('li');
904ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    li.className = 'thumbnail-item';
905ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
906ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (this.showCheckboxes_)
907ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      li.appendChild(this.renderCheckbox_(entry));
908ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
909ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var div = this.document_.createElement('div');
910ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    div.className = 'img-container';
911ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    li.appendChild(div);
912ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
913ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var img = this.document_.createElement('img');
914ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.getThumbnailURL(entry, function(type, url) { img.src = url });
915ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    div.appendChild(img);
916ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
917ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    div = this.document_.createElement('div');
918ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    div.className = 'filename-label';
919ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var labelText = entry.name;
920ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (this.currentDirEntry_.name == '')
921ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      labelText = this.getLabelForRootPath_(labelText);
922ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
923ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    div.textContent = labelText;
924ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    div.entry = entry;
925ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
926ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    li.appendChild(div);
927ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
928ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    cr.defineProperty(li, 'lead', cr.PropertyKind.BOOL_ATTR);
929ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    cr.defineProperty(li, 'selected', cr.PropertyKind.BOOL_ATTR);
930ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return li;
931ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
932ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
933ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  /**
934ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * Render the type column of the detail table.
935ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   *
936ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * Invoked by cr.ui.Table when a file needs to be rendered.
937ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   *
938ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * @param {Entry} entry The Entry object to render.
939ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * @param {string} columnId The id of the column to be rendered.
940ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * @param {cr.ui.Table} table The table doing the rendering.
941ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   */
942ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.renderIconType_ = function(entry, columnId, table) {
943ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var div = this.document_.createElement('div');
944ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    div.className = 'detail-icon-container';
945ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
946ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (this.showCheckboxes_)
947ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      div.appendChild(this.renderCheckbox_(entry));
948ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
949ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var icon = this.document_.createElement('div');
950ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    icon.className = 'detail-icon';
951ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    entry.cachedIconType_ = getIconType(entry);
952ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    icon.setAttribute('iconType', entry.cachedIconType_);
953ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    div.appendChild(icon);
954ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
955ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return div;
956ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
957ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
958ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.getLabelForRootPath_ = function(path) {
959ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // This hack lets us localize the top level directories.
960ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (path == 'Downloads')
961ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return str('DOWNLOADS_DIRECTORY_LABEL');
962ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
963ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (path == 'media')
964ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return str('MEDIA_DIRECTORY_LABEL');
965ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
966ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return path || str('ROOT_DIRECTORY_LABEL');
967ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
968ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
969ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  /**
970ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * Render the Name column of the detail table.
971ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   *
972ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * Invoked by cr.ui.Table when a file needs to be rendered.
973ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   *
974ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * @param {Entry} entry The Entry object to render.
975ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * @param {string} columnId The id of the column to be rendered.
976ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * @param {cr.ui.Table} table The table doing the rendering.
977ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   */
978ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.renderName_ = function(entry, columnId, table) {
979ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var label = this.document_.createElement('div');
980ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    label.entry = entry;
981ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    label.className = 'filename-label';
982ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (this.currentDirEntry_.name == '') {
983ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      label.textContent = this.getLabelForRootPath_(entry.name);
984ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    } else {
985ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      label.textContent = entry.name;
986ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
987ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
988ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return label;
989ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
990ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
991ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  /**
992ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * Render the Size column of the detail table.
993ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   *
994ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * @param {Entry} entry The Entry object to render.
995ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * @param {string} columnId The id of the column to be rendered.
996ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * @param {cr.ui.Table} table The table doing the rendering.
997ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   */
998ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.renderSize_ = function(entry, columnId, table) {
999ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var div = this.document_.createElement('div');
1000ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    div.className = 'detail-size';
1001ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1002ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    div.textContent = '...';
1003ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    cacheEntrySize(entry, function(entry) {
1004ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (entry.cachedSize_ == -1) {
1005ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        div.textContent = '';
1006ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      } else {
1007ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        div.textContent = cr.locale.bytesToSi(entry.cachedSize_);
1008ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
1009ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    });
1010ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1011ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return div;
1012ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
1013ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1014ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  /**
1015ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * Render the Date column of the detail table.
1016ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   *
1017ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * @param {Entry} entry The Entry object to render.
1018ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * @param {string} columnId The id of the column to be rendered.
1019ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * @param {cr.ui.Table} table The table doing the rendering.
1020ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   */
1021ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.renderDate_ = function(entry, columnId, table) {
1022ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var div = this.document_.createElement('div');
1023ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    div.className = 'detail-date';
1024ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1025ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    div.textContent = '...';
1026ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1027ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var self = this;
1028ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    cacheEntryDate(entry, function(entry) {
1029ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (self.currentDirEntry_.fullPath == MEDIA_DIRECTORY &&
1030ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          entry.cachedMtime_.getTime() == 0) {
1031ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        // Mount points for FAT volumes have this time associated with them.
1032ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        // We'd rather display nothing than this bogus date.
1033ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        div.textContent = '---';
1034ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      } else {
1035ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        div.textContent = cr.locale.formatDate(entry.cachedMtime_,
1036ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                               str('LOCALE_FMT_DATE_SHORT'));
1037ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
1038ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    });
1039ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1040ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return div;
1041ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
1042ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1043ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  /**
1044ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * Compute summary information about the current selection.
1045ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   *
1046ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * This method dispatches the 'selection-summarized' event when it completes.
1047ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * Depending on how many of the selected files already have known sizes, the
1048ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * dispatch may happen immediately, or after a number of async calls complete.
1049ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   */
1050ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.summarizeSelection_ = function() {
1051ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var selection = this.selection = {
1052ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      entries: [],
1053ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      urls: [],
1054ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      leadEntry: null,
1055ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      totalCount: 0,
1056ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      fileCount: 0,
1057ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      directoryCount: 0,
1058ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      bytes: 0,
1059ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      iconType: null,
1060ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      indexes: this.currentList_.selectionModel.selectedIndexes
1061ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    };
1062ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1063ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.previewSummary_.textContent = str('COMPUTING_SELECTION');
1064ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.taskButtons_.innerHTML = '';
1065ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1066ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (!selection.indexes.length) {
1067ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      cr.dispatchSimpleEvent(this, 'selection-summarized');
1068ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return;
1069ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
1070ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1071ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var fileCount = 0;
1072ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var byteCount = 0;
1073ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var pendingFiles = [];
1074ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1075ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    for (var i = 0; i < selection.indexes.length; i++) {
1076ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      var entry = this.dataModel_.item(selection.indexes[i]);
1077ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1078ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      selection.entries.push(entry);
1079ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      selection.urls.push(entry.toURL());
1080ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1081ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (selection.iconType == null) {
1082ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        selection.iconType = getIconType(entry);
1083ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      } else if (selection.iconType != 'unknown') {
1084ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        var iconType = getIconType(entry);
1085ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        if (selection.iconType != iconType)
1086ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          selection.iconType = 'unknown';
1087ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
1088ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1089ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      selection.totalCount++;
1090ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1091ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (entry.isFile) {
1092ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        if (!('cachedSize_' in entry)) {
1093ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          // Any file that hasn't been rendered may be missing its cachedSize_
1094ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          // property.  For example, visit a large file list, and press ctrl-a
1095ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          // to select all.  In this case, we need to asynchronously get the
1096ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          // sizes for these files before telling the world the selection has
1097ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          // been summarized.  See the 'computeNextFile' logic below.
1098ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          pendingFiles.push(entry);
1099ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          continue;
1100ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        } else {
1101ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          selection.bytes += entry.cachedSize_;
1102ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        }
1103ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        selection.fileCount += 1;
1104ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      } else {
1105ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        selection.directoryCount += 1;
1106ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
1107ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
1108ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1109ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var leadIndex = this.currentList_.selectionModel.leadIndex;
1110ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (leadIndex > -1) {
1111ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      selection.leadEntry = this.dataModel_.item(leadIndex);
1112ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    } else {
1113ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      selection.leadEntry = selection.entries[0];
1114ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
1115ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1116ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var self = this;
1117ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1118ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    function cacheNextFile(fileEntry) {
1119ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (fileEntry) {
1120ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        // We're careful to modify the 'selection', rather than 'self.selection'
1121ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        // here, just in case the selection has changed since this summarization
1122ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        // began.
1123ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        selection.bytes += fileEntry.cachedSize_;
1124ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
1125ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1126ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (pendingFiles.length) {
1127ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        cacheEntrySize(pendingFiles.pop(), cacheNextFile);
1128ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      } else {
1129ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        self.dispatchEvent(new cr.Event('selection-summarized'));
1130ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
1131ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    };
1132ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1133ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (this.dialogType_ == FileManager.DialogType.FULL_PAGE) {
1134ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      chrome.fileBrowserPrivate.getFileTasks(selection.urls,
1135ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                             this.onTasksFound_.bind(this));
1136ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
1137ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1138ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    cacheNextFile();
1139ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
1140ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1141ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.onExifGiven_ = function(fileURL, metadata) {
1142ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var observers = this.exifCache_[fileURL];
1143ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (!observers || !(observers instanceof Array)) {
1144ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      console.error('Missing or invalid exif observers: ' + fileURL + ': ' +
1145ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                    observers);
1146ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return;
1147ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
1148ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1149ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    for (var i = 0; i < observers.length; i++) {
1150ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      observers[i](metadata);
1151ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
1152ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1153ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.exifCache_[fileURL] = metadata;
1154ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
1155ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1156ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.onExifError_ = function(fileURL, step, error) {
1157ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    console.warn('Exif error: ' + fileURL + ': ' + step + ': ' + error);
1158ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.onExifGiven_(fileURL, {});
1159ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
1160ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1161ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.onExifReaderMessage_ = function(event) {
1162ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var data = event.data;
1163ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var self = this;
1164ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1165ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    function fwd(methodName, args) { self[methodName].apply(self, args) };
1166ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1167ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    switch (data.verb) {
1168ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      case 'log':
1169ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        console.log.apply(console, ['exif:'].concat(data.arguments));
1170ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        break;
1171ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1172ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      case 'give-exif':
1173ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        fwd('onExifGiven_', data.arguments);
1174ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        break;
1175ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1176ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      case 'give-exif-error':
1177ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        fwd('onExifError_', data.arguments);
1178ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        break;
1179ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1180ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      default:
1181ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        console.log('Unknown message from exif reader: ' + data.verb, data);
1182ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        break;
1183ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
1184ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
1185ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1186ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.onTasksFound_ = function(tasksList) {
1187ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.taskButtons_.innerHTML = '';
1188ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    for (var i = 0; i < tasksList.length; i++) {
1189ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      var task = tasksList[i];
1190ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1191ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // Tweak images, titles of internal tasks.
1192ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      var task_parts = task.taskId.split('|');
1193ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (task_parts[0] == this.getExtensionId_()) {
1194ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        if (task_parts[1] == 'preview') {
1195ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          // TODO(serya): This hack needed until task.iconUrl get working
1196ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          //              (see GetFileTasksFileBrowserFunction::RunImpl).
1197ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          task.iconUrl =
1198ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen              chrome.extension.getURL('images/icon_preview_16x16.png');
1199ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          task.title = str('PREVIEW_IMAGE');
1200ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        } else if (task_parts[1] == 'play') {
1201ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          task.iconUrl =
1202ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen              chrome.extension.getURL('images/icon_play_16x16.png');
1203ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          task.title = str('PLAY_MEDIA').replace("&", "");
1204ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        } else if (task_parts[1] == 'enqueue') {
1205ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          task.iconUrl =
1206ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen              chrome.extension.getURL('images/icon_add_to_queue_16x16.png');
1207ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          task.title = str('ENQUEUE');
1208ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        }
1209ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
1210ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1211ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      var button = this.document_.createElement('button');
1212ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      button.addEventListener('click', this.onTaskButtonClicked_.bind(this));
1213ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      button.className = 'task-button';
1214ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      button.task = task;
1215ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1216ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      var img = this.document_.createElement('img');
1217ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      img.src = task.iconUrl;
1218ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1219ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      button.appendChild(img);
1220ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      button.appendChild(this.document_.createTextNode(task.title));
1221ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1222ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.taskButtons_.appendChild(button);
1223ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
1224ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
1225ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1226ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.getExtensionId_ = function() {
1227ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return chrome.extension.getURL('').split('/')[2];
1228ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
1229ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1230ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.onTaskButtonClicked_ = function(event) {
1231ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Check internal tasks first.
1232ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var task_parts = event.srcElement.task.taskId.split('|');
1233ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (task_parts[0] == this.getExtensionId_()) {
1234ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (task_parts[1] == 'preview') {
1235ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        g_slideshow_data = this.selection.urls;
1236ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        chrome.tabs.create({url: "slideshow.html"});
1237ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      } else if (task_parts[1] == 'play') {
1238ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        chrome.fileBrowserPrivate.viewFiles(this.selection.urls,
1239ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            event.srcElement.task.taskId);
1240ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      } else if (task_parts[1] == 'enqueue') {
1241ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        chrome.fileBrowserPrivate.viewFiles(this.selection.urls,
1242ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            event.srcElement.task.taskId);
1243ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
1244ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return;
1245ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
1246ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1247ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    chrome.fileBrowserPrivate.executeTask(event.srcElement.task.taskId,
1248ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                          this.selection.urls);
1249ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
1250ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1251ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  /**
1252ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * Update the breadcrumb display to reflect the current directory.
1253ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   */
1254ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.updateBreadcrumbs_ = function() {
1255ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var bc = this.dialogDom_.querySelector('.breadcrumbs');
1256ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    bc.innerHTML = '';
1257ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1258ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var fullPath = this.currentDirEntry_.fullPath.replace(/\/$/, '');
1259ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var pathNames = fullPath.split('/');
1260ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var path = '';
1261ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1262ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    for (var i = 0; i < pathNames.length; i++) {
1263ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      var pathName = pathNames[i];
1264ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      path += pathName + '/';
1265ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1266ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      var div = this.document_.createElement('div');
1267ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      div.className = 'breadcrumb-path';
1268ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (i <= 1) {
1269ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        // i == 0: root directory itself, i == 1: the files it contains.
1270ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        div.textContent = this.getLabelForRootPath_(pathName);
1271ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      } else {
1272ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        div.textContent = pathName;
1273ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
1274ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1275ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      div.path = path;
1276ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      div.addEventListener('click', this.onBreadcrumbClick_.bind(this));
1277ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1278ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      bc.appendChild(div);
1279ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1280ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (i == pathNames.length - 1) {
1281ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        div.classList.add('breadcrumb-last');
1282ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      } else {
1283ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        var spacer = this.document_.createElement('div');
1284ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        spacer.className = 'breadcrumb-spacer';
1285ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        spacer.textContent = RIGHT_TRIANGLE;
1286ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        bc.appendChild(spacer);
1287ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
1288ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
1289ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
1290ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1291ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  /**
1292ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * Update the preview panel to display a given entry.
1293ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   *
1294ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * The selection summary line is handled by the onSelectionSummarized handler
1295ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * rather than this function, because summarization may not complete quickly.
1296ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   */
1297ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.updatePreview_ = function() {
1298ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Clear the preview image first, in case the thumbnail takes long to load.
1299ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.previewImage_.src = '';
1300ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // The transparent-background class is used to display the checkerboard
1301ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // background for image thumbnails.  We don't want to display it for
1302ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // non-thumbnail preview images.
1303ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.previewImage_.classList.remove('transparent-background');
1304ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // The multiple-selected class indicates that more than one entry is
1305ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // selcted.
1306ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.previewImage_.classList.remove('multiple-selected');
1307ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1308ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (!this.selection.totalCount) {
1309ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.previewFilename_.textContent = '';
1310ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return;
1311ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
1312ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1313ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var previewName = this.selection.leadEntry.name;
1314ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (this.currentDirEntry_.name == '')
1315ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      previewName = this.getLabelForRootPath_(previewName);
1316ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1317ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.previewFilename_.textContent = previewName;
1318ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1319ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var iconType = getIconType(this.selection.leadEntry);
1320ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (iconType == 'image') {
1321ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (fileManager.selection.totalCount > 1)
1322ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        this.previewImage_.classList.add('multiple-selected');
1323ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
1324ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1325ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var self = this;
1326ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var leadEntry = this.selection.leadEntry;
1327ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1328ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.getThumbnailURL(this.selection.leadEntry, function(iconType, url) {
1329ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (self.selection.leadEntry != leadEntry) {
1330ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        // Selection has changed since we asked, nevermind.
1331ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        return;
1332ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
1333ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1334ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (url) {
1335ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        self.previewImage_.src = url;
1336ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        if (iconType == 'image')
1337ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          self.previewImage_.classList.add('transparent-background');
1338ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      } else {
1339ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        self.previewImage_.src = previewArt['unknown'];
1340ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
1341ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    });
1342ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
1343ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1344ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.cacheExifMetadata_ = function(entry, callback) {
1345ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var url = entry.toURL();
1346ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var cacheValue = this.exifCache_[url];
1347ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1348ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (!cacheValue) {
1349ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // This is the first time anyone's asked, go get it.
1350ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.exifCache_[url] = [callback];
1351ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.exifReader.postMessage({verb: 'get-exif',
1352ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                   arguments: [entry.toURL()]});
1353ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return;
1354ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
1355ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1356ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (cacheValue instanceof Array) {
1357ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // Something is already pending, add to the list of observers.
1358ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      cacheValue.push(callback);
1359ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return;
1360ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
1361ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1362ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (cacheValue instanceof Object) {
1363ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // We already know the answer, let the caller know in a fresh call stack.
1364ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      setTimeout(function() { callback(cacheValue) });
1365ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return;
1366ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
1367ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1368ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    console.error('Unexpected exif cache value:' + cacheValue);
1369ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
1370ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1371ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.getThumbnailURL = function(entry, callback) {
1372ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (!entry)
1373ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return;
1374ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1375ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var iconType = getIconType(entry);
1376ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (iconType != 'image') {
1377ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // Not an image, display a canned clip-art graphic.
1378ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (!(iconType in previewArt))
1379ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        iconType = 'unknown';
1380ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1381ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      setTimeout(function() { callback(iconType, previewArt[iconType]) });
1382ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return;
1383ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
1384ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1385ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (ENABLE_EXIF_READER) {
1386ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (entry.name.match(/\.jpe?g$/i)) {
1387ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        // File is a jpg image, fetch the exif thumbnail.
1388ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        this.cacheExifMetadata_(entry, function(metadata) {
1389ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          callback(iconType, metadata.thumbnailURL || entry.toURL());
1390ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        });
1391ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        return;
1392ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
1393ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
1394ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1395ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // File is some other kind of image, just return the url to the whole
1396ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // thing.
1397ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    setTimeout(function() { callback(iconType, entry.toURL()) });
1398ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
1399ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1400ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  /**
1401ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * Change the current directory.
1402ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   *
1403ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * Dispatches the 'directory-changed' event when the directory is successfully
1404ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * changed.
1405ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   *
1406ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * @param {string} path The absolute path to the new directory.
1407ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * @param {bool} opt_saveHistory Save this in the history stack (defaults
1408ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   *     to true).
1409ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   */
1410ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.changeDirectory = function(path, opt_saveHistory) {
1411ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var self = this;
1412ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1413ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (arguments.length == 1) {
1414ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      opt_saveHistory = true;
1415ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    } else {
1416ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      opt_saveHistory = !!opt_saveHistory;
1417ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
1418ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1419ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    function onPathFound(dirEntry) {
1420ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (self.currentDirEntry_ &&
1421ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          self.currentDirEntry_.fullPath == dirEntry.fullPath) {
1422ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        // Directory didn't actually change.
1423ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        return;
1424ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
1425ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1426ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      var e = new cr.Event('directory-changed');
1427ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      e.previousDirEntry = self.currentDirEntry_;
1428ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      e.newDirEntry = dirEntry;
1429ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      e.saveHistory = opt_saveHistory;
1430ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      self.currentDirEntry_ = dirEntry;
1431ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      self.dispatchEvent(e);
1432ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    };
1433ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1434ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (path == '/')
1435ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return onPathFound(this.filesystem_.root);
1436ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1437ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.filesystem_.root.getDirectory(
1438ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        path, {create: false}, onPathFound,
1439ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        function(err) {
1440ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          console.error('Error changing directory to: ' + path + ', ' + err);
1441ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          if (!self.currentDirEntry_) {
1442ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            // If we've never successfully changed to a directory, force them
1443ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            // to the root.
1444ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            self.changeDirectory('/');
1445ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          }
1446ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        });
1447ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
1448ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1449ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.deleteEntries = function(entries) {
1450ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (!window.confirm(str('CONFIRM_DELETE')))
1451ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return;
1452ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1453ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var count = entries.length;
1454ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1455ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var self = this;
1456ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    function onDelete() {
1457ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (--count == 0)
1458ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen         self.rescanDirectory_();
1459ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
1460ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1461ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    for (var i = 0; i < entries.length; i++) {
1462ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      var entry = entries[i];
1463ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (entry.isFile) {
1464ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        entry.remove(
1465ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            onDelete,
1466ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            util.flog('Error deleting file: ' + entry.fullPath, onDelete));
1467ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      } else {
1468ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        entry.removeRecursively(
1469ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            onDelete,
1470ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            util.flog('Error deleting folder: ' + entry.fullPath, onDelete));
1471ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
1472ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
1473ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
1474ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1475ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  /**
1476ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * Invoked by the table dataModel after a sort completes.
1477ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   *
1478ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * We use this hook to make sure selected files stay visible after a sort.
1479ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   */
1480ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.onDataModelSorted_ = function() {
1481ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var i = this.currentList_.selectionModel.leadIndex;
1482ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.currentList_.scrollIntoView(i);
1483ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
1484ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1485ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  /**
1486ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * Update the selection summary UI when the selection summarization completes.
1487ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   */
1488ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.onSelectionSummarized_ = function() {
1489ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (this.selection.totalCount == 0) {
1490ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.previewSummary_.textContent = str('NOTHING_SELECTED');
1491ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1492ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    } else if (this.selection.totalCount == 1) {
1493ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.previewSummary_.textContent =
1494ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        strf('ONE_FILE_SELECTED', cr.locale.bytesToSi(this.selection.bytes));
1495ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1496ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    } else {
1497ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.previewSummary_.textContent =
1498ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        strf('MANY_FILES_SELECTED', this.selection.totalCount,
1499ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen             cr.locale.bytesToSi(this.selection.bytes));
1500ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
1501ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
1502ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1503ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  /**
1504ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * Handle a click event on a breadcrumb element.
1505ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   *
1506ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * @param {Event} event The click event.
1507ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   */
1508ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.onBreadcrumbClick_ = function(event) {
1509ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.changeDirectory(event.srcElement.path);
1510ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
1511ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1512ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.onCheckboxMouseDownUp_ = function(event) {
1513ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // If exactly one file is selected and its checkbox is *not* clicked,
1514ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // then this should be treated as a "normal" click (ie. the previous
1515ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // selection should be cleared).
1516ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (this.selection.totalCount == 1 && this.selection.entries[0].isFile) {
1517ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      var selectedIndex = this.selection.indexes[0];
1518ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      var listItem = this.currentList_.getListItemByIndex(selectedIndex);
1519ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      var checkbox = listItem.querySelector('input[type="checkbox"]');
1520ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (!checkbox.checked)
1521ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        return;
1522ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
1523ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1524ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Otherwise, treat clicking on a checkbox the same as a ctrl-click.
1525ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // The default properties of event.ctrlKey make it read-only, but
1526ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // don't prevent deletion, so we delete first, then set it true.
1527ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    delete event.ctrlKey;
1528ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    event.ctrlKey = true;
1529ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
1530ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1531ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.onCheckboxClick_ = function(event) {
1532ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (event.shiftKey) {
1533ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // Something about the timing of shift-clicks causes the checkbox
1534ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // to get selected and then very quickly unselected.  It appears that
1535ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // we forcibly select the checkbox as part of onSelectionChanged, and
1536ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // then the default action of this click event fires and toggles the
1537ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // checkbox back off.
1538ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      //
1539ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // Since we're going to force checkboxes into the correct state for any
1540ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // multi-selection, we can prevent this shift click from toggling the
1541ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // checkbox and avoid the trouble.
1542ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      event.preventDefault();
1543ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
1544ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
1545ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1546ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  /**
1547ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * Update the UI when the selection model changes.
1548ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   *
1549ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * @param {cr.Event} event The change event.
1550ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   */
1551ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.onSelectionChanged_ = function(event) {
1552ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var selectable;
1553ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1554ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.summarizeSelection_();
1555ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.updateOkButton_();
1556ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.updatePreview_();
1557ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1558ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var self = this;
1559ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    setTimeout(function() { self.onSelectionChangeComplete_(event) }, 0);
1560ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
1561ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1562ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.onSelectionChangeComplete_ = function(event) {
1563ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (!this.showCheckboxes_)
1564ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return;
1565ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1566ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    for (var i = 0; i < event.changes.length; i++) {
1567ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // Turn off any checkboxes for items that are no longer selected.
1568ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      var selectedIndex = event.changes[i].index;
1569ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      var listItem = this.currentList_.getListItemByIndex(selectedIndex);
1570ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (!listItem) {
1571ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        // When changing directories, we get notified about list items
1572ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        // that are no longer there.
1573ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        continue;
1574ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
1575ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1576ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (!event.changes[i].selected) {
1577ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        var checkbox = listItem.querySelector('input[type="checkbox"]');
1578ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        checkbox.checked = false;
1579ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
1580ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
1581ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1582ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (this.selection.fileCount > 1) {
1583ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // If more than one file is selected, make sure all checkboxes are lit
1584ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // up.
1585ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      for (var i = 0; i < this.selection.entries.length; i++) {
1586ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        if (!this.selection.entries[i].isFile)
1587ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          continue;
1588ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1589ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        var selectedIndex = this.selection.indexes[i];
1590ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        var listItem = this.currentList_.getListItemByIndex(selectedIndex);
1591ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        if (listItem)
1592ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          listItem.querySelector('input[type="checkbox"]').checked = true;
1593ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
1594ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
1595ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
1596ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1597ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.updateOkButton_ = function(event) {
1598ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (this.dialogType_ == FileManager.DialogType.SELECT_FOLDER) {
1599ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      selectable = this.selection.directoryCount == 1 &&
1600ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          this.selection.fileCount == 0;
1601ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    } else if (this.dialogType_ == FileManager.DialogType.SELECT_OPEN_FILE) {
1602ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      selectable = (this.selection.directoryCount == 0 &&
1603ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                    this.selection.fileCount == 1);
1604ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    } else if (this.dialogType_ ==
1605ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen               FileManager.DialogType.SELECT_OPEN_MULTI_FILE) {
1606ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      selectable = (this.selection.directoryCount == 0 &&
1607ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                    this.selection.fileCount >= 1);
1608ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    } else if (this.dialogType_ == FileManager.DialogType.SELECT_SAVEAS_FILE) {
1609ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (this.selection.leadEntry && this.selection.leadEntry.isFile)
1610ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        this.filenameInput_.value = this.selection.leadEntry.name;
1611ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1612ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (this.currentDirEntry_.fullPath == '/' ||
1613ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          this.currentDirEntry_.fullPath == MEDIA_DIRECTORY) {
1614ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        // Nothing can be saved in to the root or media/ directories.
1615ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        selectable = false;
1616ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      } else {
1617ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        selectable = !!this.filenameInput_.value;
1618ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
1619ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    } else if (this.dialogType_ == FileManager.DialogType.FULL_PAGE) {
1620ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // No "select" buttons on the full page UI.
1621ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      selectable = true;
1622ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    } else {
1623ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      throw new Error('Unknown dialog type');
1624ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
1625ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1626ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.okButton_.disabled = !selectable;
1627ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
1628ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1629ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  /**
1630ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * Handle a double-click event on an entry in the detail list.
1631ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   *
1632ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * @param {Event} event The click event.
1633ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   */
1634ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.onDetailDoubleClick_ = function(event) {
1635ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (this.renameInput_.currentEntry) {
1636ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // Don't pay attention to double clicks during a rename.
1637ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return;
1638ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
1639ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1640ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var i = this.currentList_.selectionModel.leadIndex;
1641ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var entry = this.dataModel_.item(i);
1642ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1643ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (entry.isDirectory)
1644ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return this.changeDirectory(entry.fullPath);
1645ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1646ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (!this.okButton_.disabled)
1647ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.onOk_();
1648ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1649ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
1650ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1651ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  /**
1652ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * Update the UI when the current directory changes.
1653ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   *
1654ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * @param {cr.Event} event The directory-changed event.
1655ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   */
1656ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.onDirectoryChanged_ = function(event) {
1657ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (event.saveHistory) {
1658ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      history.pushState(this.currentDirEntry_.fullPath,
1659ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                        this.currentDirEntry_.fullPath,
1660ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                        location.href);
1661ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
1662ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1663ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.updateOkButton_();
1664ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // New folder should never be enabled in the root or media/ directories.
1665ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.newFolderButton_.disabled =
1666ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        (this.currentDirEntry_.fullPath == '/' ||
1667ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen         this.currentDirEntry_.fullPath == MEDIA_DIRECTORY);
1668ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1669ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.document_.title = this.currentDirEntry_.fullPath;
1670ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.rescanDirectory_();
1671ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
1672ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1673ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  /**
1674ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * Update the UI when a disk is mounted or unmounted.
1675ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   *
1676ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * @param {string} path The path that has been mounted or unmounted.
1677ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   */
1678ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.onDiskChanged_ = function(event) {
1679ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (event.eventType == 'added') {
1680ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.changeDirectory(event.volumeInfo.mountPath);
1681ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    } else if (event.eventType == 'removed') {
1682ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (this.currentDirEntry_ &&
1683ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          isParentPath(event.volumeInfo.mountPath,
1684ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                       this.currentDirEntry_.fullPath)) {
1685ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        this.changeDirectory(getParentPath(event.volumeInfo.mountPath));
1686ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
1687ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
1688ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
1689ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1690ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  /**
1691ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * Rescan the current directory, refreshing the list.
1692ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   *
1693ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * @param {function()} opt_callback Optional function to invoke when the
1694ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   *     rescan is complete.
1695ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   */
1696ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.rescanDirectory_ = function(opt_callback) {
1697ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var self = this;
1698ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var reader;
1699ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1700ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    function onReadSome(entries) {
1701ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (entries.length == 0) {
1702ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        if (self.dataModel_.sortStatus.field != 'name')
1703ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          self.dataModel_.updateIndex(0);
1704ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1705ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        if (opt_callback)
1706ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          opt_callback();
1707ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        return;
1708ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
1709ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1710ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // Splice takes the to-be-spliced-in array as individual parameters,
1711ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // rather than as an array, so we need to perform some acrobatics...
1712ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      var spliceArgs = [].slice.call(entries);
1713ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1714ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // Hide files that start with a dot ('.').
1715ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // TODO(rginda): User should be able to override this.  Support for other
1716ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // commonly hidden patterns might be nice too.
1717ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (self.filterFiles_) {
1718ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        spliceArgs = spliceArgs.filter(function(e) {
1719ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            return e.name.substr(0, 1) != '.';
1720ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          });
1721ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
1722ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1723ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      spliceArgs.unshift(0, 0);  // index, deleteCount
1724ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      self.dataModel_.splice.apply(self.dataModel_, spliceArgs);
1725ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1726ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // Keep reading until entries.length is 0.
1727ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      reader.readEntries(onReadSome);
1728ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    };
1729ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1730ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.lastLabelClick_ = null;
1731ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1732ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Clear the table first.
1733ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.dataModel_.splice(0, this.dataModel_.length);
1734ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1735ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.updateBreadcrumbs_();
1736ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1737ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (this.currentDirEntry_.fullPath != '/') {
1738ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // If not the root directory, just read the contents.
1739ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      reader = this.currentDirEntry_.createReader();
1740ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      reader.readEntries(onReadSome);
1741ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return;
1742ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
1743ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1744ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Otherwise, use the provided list of root subdirectories, since the
1745ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // real local filesystem root directory (the one we use outside the
1746ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // harness) can't be enumerated yet.
1747ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var spliceArgs = [].slice.call(this.rootEntries_);
1748ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    spliceArgs.unshift(0, 0);  // index, deleteCount
1749ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    self.dataModel_.splice.apply(self.dataModel_, spliceArgs);
1750ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    self.dataModel_.updateIndex(0);
1751ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1752ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (opt_callback)
1753ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      opt_callback();
1754ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
1755ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1756ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.findListItem_ = function(event) {
1757ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var node = event.srcElement;
1758ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    while (node) {
1759ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (node.tagName == 'LI')
1760ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        break;
1761ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      node = node.parentNode;
1762ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
1763ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1764ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return node;
1765ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
1766ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1767ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.onGridMouseDown_ = function(event) {
1768ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.updateCommands_();
1769ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1770ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (this.allowRenameClick_(event, event.srcElement.parentNode)) {
1771ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      event.preventDefault();
1772ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.initiateRename_(event.srcElement);
1773ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
1774ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1775ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (event.button != 1)
1776ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return;
1777ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1778ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var li = this.findListItem_(event);
1779ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (!li)
1780ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return;
1781ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
1782ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1783ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.onTableMouseDown_ = function(event) {
1784ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.updateCommands_();
1785ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1786ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (this.allowRenameClick_(event,
1787ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                               event.srcElement.parentNode.parentNode)) {
1788ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      event.preventDefault();
1789ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.initiateRename_(event.srcElement);
1790ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
1791ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1792ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (event.button != 1)
1793ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return;
1794ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1795ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var li = this.findListItem_(event);
1796ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (!li) {
1797ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      console.log('li not found', event);
1798ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return;
1799ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
1800ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
1801ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1802ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  /**
1803ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * Determine whether or not a click should initiate a rename.
1804ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   *
1805ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * Renames can happen on mouse click if the user clicks on a label twice,
1806ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * at least a half second apart.
1807ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   */
1808ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.allowRenameClick_ = function(event, row) {
1809ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (this.dialogType_ != FileManager.DialogType.FULL_PAGE ||
1810ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        this.currentDirEntry_.name == '') {
1811ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // Renaming only enabled for full-page mode, outside of the root
1812ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // directory.
1813ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return false;
1814ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
1815ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1816ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Rename already in progress.
1817ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (this.renameInput_.currentEntry)
1818ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return false;
1819ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1820ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Didn't click on the label.
1821ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (event.srcElement.className != 'filename-label')
1822ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return false;
1823ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1824ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Wrong button or using a keyboard modifier.
1825ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (event.button != 0 || event.shiftKey || event.metaKey || event.altKey) {
1826ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.lastLabelClick_ = null;
1827ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return false;
1828ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
1829ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1830ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var now = new Date();
1831ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1832ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.lastLabelClick_ = this.lastLabelClick_ || now;
1833ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var delay = now - this.lastLabelClick_;
1834ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (!row.selected || delay < 500)
1835ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return false;
1836ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1837ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.lastLabelClick_ = now;
1838ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return true;
1839ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
1840ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1841ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.initiateRename_= function(label) {
1842ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var input = this.renameInput_;
1843ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1844ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    window.label = label;
1845ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1846ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    input.value = label.textContent;
1847ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    input.style.top = label.offsetTop + 'px';
1848ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    input.style.left = label.offsetLeft + 'px';
1849ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    input.style.width = label.clientWidth + 'px';
1850ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    label.parentNode.appendChild(input);
1851ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    input.focus();
1852ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var selectionEnd = input.value.lastIndexOf('.');
1853ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (selectionEnd == -1) {
1854ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      input.select();
1855ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    } else {
1856ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      input.selectionStart = 0;
1857ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      input.selectionEnd = selectionEnd;
1858ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
1859ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1860ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // This has to be set late in the process so we don't handle spurious
1861ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // blur events.
1862ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    input.currentEntry = label.entry;
1863ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
1864ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1865ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.onRenameInputKeyDown_ = function(event) {
1866ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (!this.renameInput_.currentEntry)
1867ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return;
1868ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1869ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    switch (event.keyCode) {
1870ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      case 27:  // Escape
1871ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        this.cancelRename_();
1872ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        event.preventDefault();
1873ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        break;
1874ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1875ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      case 13:  // Enter
1876ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        this.commitRename_();
1877ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        event.preventDefault();
1878ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        break;
1879ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
1880ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
1881ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1882ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.onRenameInputBlur_ = function(event) {
1883ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (this.renameInput_.currentEntry)
1884ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.cancelRename_();
1885ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
1886ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1887ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.commitRename_ = function() {
1888ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var entry = this.renameInput_.currentEntry;
1889ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var newName = this.renameInput_.value;
1890ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1891ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.renameInput_.currentEntry = null;
1892ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.lastLabelClick_ = null;
1893ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1894ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (this.renameInput_.parentNode)
1895ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.renameInput_.parentNode.removeChild(this.renameInput_);
1896ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1897ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var self = this;
1898ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    function onSuccess() {
1899ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      self.rescanDirectory_(function () {
1900ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        for (var i = 0; i < self.dataModel_.length; i++) {
1901ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          if (self.dataModel_.item(i).name == newName) {
1902ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            self.currentList_.selectionModel.selectedIndex = i;
1903ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            self.currentList_.scrollIndexIntoView(i);
1904ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            self.currentList_.focus();
1905ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            return;
1906ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          }
1907ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        }
1908ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      });
1909ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
1910ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1911ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    function onError(err) {
1912ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      window.alert(strf('ERROR_RENAMING', entry.name,
1913ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                        util.getFileErrorMnemonic(err.code)));
1914ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
1915ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1916ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    entry.moveTo(this.currentDirEntry_, newName, onSuccess, onError);
1917ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
1918ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1919ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.cancelRename_ = function(event) {
1920ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.renameInput_.currentEntry = null;
1921ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.lastLabelClick_ = null;
1922ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1923ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (this.renameInput_.parentNode)
1924ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.renameInput_.parentNode.removeChild(this.renameInput_);
1925ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
1926ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1927ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.onFilenameInputKeyUp_ = function(event) {
1928ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.okButton_.disabled = this.filenameInput_.value.length == 0;
1929ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1930ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (event.keyCode == 13 /* Enter */ && !this.okButton_.disabled)
1931ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.onOk_();
1932ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
1933ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1934ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.onFilenameInputFocus_ = function(event) {
1935ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var input = this.filenameInput_;
1936ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1937ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // On focus we want to select everything but the extension, but
1938ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Chrome will select-all after the focus event completes.  We
1939ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // schedule a timeout to alter the focus after that happens.
1940ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    setTimeout(function() {
1941ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        var selectionEnd = input.value.lastIndexOf('.');
1942ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        if (selectionEnd == -1) {
1943ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          input.select();
1944ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        } else {
1945ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          input.selectionStart = 0;
1946ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          input.selectionEnd = selectionEnd;
1947ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        }
1948ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }, 0);
1949ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
1950ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1951ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.onNewFolderButtonClick_ = function(event) {
1952ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var name = '';
1953ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1954ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    while (1) {
1955ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      name = window.prompt(str('NEW_FOLDER_PROMPT'), name);
1956ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (!name)
1957ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        return;
1958ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1959ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (name.indexOf('/') == -1)
1960ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        break;
1961ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1962ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      alert(strf('ERROR_INVALID_FOLDER_CHARACTER', '/'));
1963ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
1964ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1965ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var self = this;
1966ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1967ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    function onSuccess(dirEntry) {
1968ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      self.rescanDirectory_(function () {
1969ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        for (var i = 0; i < self.dataModel_.length; i++) {
1970ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          if (self.dataModel_.item(i).name == dirEntry.name) {
1971ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            self.currentList_.selectionModel.selectedIndex = i;
1972ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            self.currentList_.scrollIndexIntoView(i);
1973ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            self.currentList_.focus();
1974ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            return;
1975ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          }
1976ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        }
1977ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      });
1978ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
1979ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1980ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    function onError(err) {
1981ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      window.alert(strf('ERROR_CREATING_FOLDER', name,
1982ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                        util.getFileErrorMnemonic(err.code)));
1983ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
1984ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1985ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.currentDirEntry_.getDirectory(name, {create: true, exclusive: true},
1986ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                       onSuccess, onError);
1987ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
1988ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1989ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.onDetailViewButtonClick_ = function(event) {
1990ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.setListType(FileManager.ListType.DETAIL);
1991ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
1992ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1993ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.onThumbnailViewButtonClick_ = function(event) {
1994ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    this.setListType(FileManager.ListType.THUMBNAIL);
1995ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
1996ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1997ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.onKeyDown_ = function(event) {
1998ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (event.srcElement.tagName == 'INPUT')
1999ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return;
2000ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
2001ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    switch (event.keyCode) {
2002ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      case 8:  // Backspace => Up one directory.
2003ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        event.preventDefault();
2004ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        var path = this.currentDirEntry_.fullPath;
2005ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        if (path && path != '/') {
2006ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          var path = path.replace(/\/[^\/]+$/, '');
2007ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          this.changeDirectory(path || '/');
2008ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        }
2009ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        break;
2010ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
2011ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      case 13:  // Enter => Change directory or complete dialog.
2012ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        if (this.selection.totalCount == 1 &&
2013ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            this.selection.leadEntry.isDirectory &&
2014ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            this.dialogType_ != FileManager.SELECT_FOLDER) {
2015ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          this.changeDirectory(this.selection.leadEntry.fullPath);
2016ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        } else if (!this.okButton_.disabled) {
2017ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          this.onOk_();
2018ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        }
2019ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        break;
2020ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
2021ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      case 32:  // Ctrl-Space => New Folder.
2022ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        if (this.newFolderButton_.style.display != 'none' && event.ctrlKey) {
2023ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          event.preventDefault();
2024ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          this.onNewFolderButtonClick_();
2025ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        }
2026ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        break;
2027ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
2028ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      case 190:  // Ctrl-. => Toggle filter files.
2029ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        if (event.ctrlKey) {
2030ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          this.filterFiles_ = !this.filterFiles_;
2031ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          this.rescanDirectory_();
2032ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        }
2033ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        break;
2034ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
2035ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      case 46:  // Delete.
2036ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        if (this.dialogType_ == FileManager.DialogType.FULL_PAGE &&
2037ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            this.selection.totalCount > 0) {
2038ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          event.preventDefault();
2039ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          this.deleteEntries(this.selection.entries);
2040ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        }
2041ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        break;
2042ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
2043ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
2044ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
2045ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  /**
2046ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * Handle a click of the cancel button.  Closes the window.
2047ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   *
2048ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * @param {Event} event The click event.
2049ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   */
2050ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.onCancel_ = function(event) {
2051ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    chrome.fileBrowserPrivate.cancelDialog();
2052ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
2053ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
2054ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  /**
2055ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * Handle a click of the ok button.
2056ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   *
2057ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * The ok button has different UI labels depending on the type of dialog, but
2058ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * in code it's always referred to as 'ok'.
2059ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   *
2060ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * @param {Event} event The click event.
2061ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   */
2062ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FileManager.prototype.onOk_ = function(event) {
2063ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var currentDirUrl = this.currentDirEntry_.toURL();
2064ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
2065ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (currentDirUrl.charAt(currentDirUrl.length - 1) != '/')
2066ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      currentDirUrl += '/';
2067ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
2068ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (this.dialogType_ == FileManager.DialogType.SELECT_SAVEAS_FILE) {
2069ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // Save-as doesn't require a valid selection from the list, since
2070ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // we're going to take the filename from the text input.
2071ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      var filename = this.filenameInput_.value;
2072ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (!filename)
2073ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        throw new Error('Missing filename!');
2074ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
2075ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      chrome.fileBrowserPrivate.selectFile(currentDirUrl + encodeURI(filename),
2076ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                           0);
2077ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // Window closed by above call.
2078ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return;
2079ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
2080ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
2081ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var ary = [];
2082ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    var selectedIndexes = this.currentList_.selectionModel.selectedIndexes;
2083ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
2084ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // All other dialog types require at least one selected list item.
2085ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // The logic to control whether or not the ok button is enabled should
2086ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // prevent us from ever getting here, but we sanity check to be sure.
2087ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (!selectedIndexes.length)
2088ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      throw new Error('Nothing selected!');
2089ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
2090ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    for (var i = 0; i < selectedIndexes.length; i++) {
2091ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      var entry = this.dataModel_.item(selectedIndexes[i]);
2092ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (!entry) {
2093ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        console.log('Error locating selected file at index: ' + i);
2094ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        continue;
2095ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
2096ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
2097ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      ary.push(currentDirUrl + encodeURI(entry.name));
2098ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
2099ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
2100ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Multi-file selection has no other restrictions.
2101ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (this.dialogType_ == FileManager.DialogType.SELECT_OPEN_MULTI_FILE) {
2102ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      chrome.fileBrowserPrivate.selectFiles(ary);
2103ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // Window closed by above call.
2104ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return;
2105ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
2106ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
2107ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // In full screen mode, open all files for vieweing.
2108ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (this.dialogType_ == FileManager.DialogType.FULL_PAGE) {
2109ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      chrome.fileBrowserPrivate.viewFiles(ary, "default");
2110ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // Window stays open.
2111ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return;
2112ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
2113ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
2114ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Everything else must have exactly one.
2115ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (ary.length > 1)
2116ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      throw new Error('Too many files selected!');
2117ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
2118ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (this.dialogType_ == FileManager.DialogType.SELECT_FOLDER) {
2119ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (!this.selection.leadEntry.isDirectory)
2120ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        throw new Error('Selected entry is not a folder!');
2121ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    } else if (this.dialogType_ == FileManager.DialogType.SELECT_OPEN_FILE) {
2122ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (!this.selection.leadEntry.isFile)
2123ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        throw new Error('Selected entry is not a file!');
2124ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
2125ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
2126ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    chrome.fileBrowserPrivate.selectFile(ary[0], 0);
2127ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Window closed by above call.
2128ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
2129ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
2130ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen})();
2131