Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(283)

Side by Side Diff: chrome/browser/resources/file_manager/js/file_manager.js

Issue 10187004: [filemanager] Move GData properties to metadata cache. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Merged, review fixes. Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 /** 5 /**
6 * FileManager constructor. 6 * FileManager constructor.
7 * 7 *
8 * FileManager objects encapsulate the functionality of the file selector 8 * FileManager objects encapsulate the functionality of the file selector
9 * dialogs, as well as the full screen file manager application (though the 9 * dialogs, as well as the full screen file manager application (though the
10 * latter is not yet implemented). 10 * latter is not yet implemented).
(...skipping 11 matching lines...) Expand all
22 22
23 this.listType_ = null; 23 this.listType_ = null;
24 24
25 this.selection = null; 25 this.selection = null;
26 26
27 this.butterTimer_ = null; 27 this.butterTimer_ = null;
28 this.currentButter_ = null; 28 this.currentButter_ = null;
29 this.butterLastShowTime_ = 0; 29 this.butterLastShowTime_ = 0;
30 30
31 this.watchedDirectoryUrl_ = null; 31 this.watchedDirectoryUrl_ = null;
32 this.metadataObserverId_ = null; 32 this.filesystemObserverId_ = null;
33 this.gdataObserverId_ = null;
33 34
34 this.commands_ = {}; 35 this.commands_ = {};
35 36
36 this.thumbnailUrlCache_ = {}; 37 this.thumbnailUrlCache_ = {};
37 38
38 this.document_ = dialogDom.ownerDocument; 39 this.document_ = dialogDom.ownerDocument;
39 this.dialogType_ = this.params_.type || FileManager.DialogType.FULL_PAGE; 40 this.dialogType_ = this.params_.type || FileManager.DialogType.FULL_PAGE;
40 41
41 metrics.recordEnum('Create', this.dialogType_, 42 metrics.recordEnum('Create', this.dialogType_,
42 [FileManager.DialogType.SELECT_FOLDER, 43 [FileManager.DialogType.SELECT_FOLDER,
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 * 179 *
179 * @param {string} path The file path. 180 * @param {string} path The file path.
180 */ 181 */
181 function normalizeAbsolutePath(x) { 182 function normalizeAbsolutePath(x) {
182 if (x[0] == '/') 183 if (x[0] == '/')
183 return x.slice(1); 184 return x.slice(1);
184 else 185 else
185 return x; 186 return x;
186 } 187 }
187 188
188
189 /**
190 * Call an asynchronous method on dirEntry, batching multiple callers.
191 *
192 * This batches multiple callers into a single invocation, calling all
193 * interested parties back when the async call completes.
194 *
195 * The Entry method to be invoked should take two callbacks as parameters
196 * (one for success and one for failure), and it should invoke those
197 * callbacks with a single parameter representing the result of the call.
198 * Example methods are Entry.getMetadata() and FileEntry.file().
199 *
200 * Warning: Because this method caches the first result, subsequent changes
201 * to the entry will not be visible to callers.
202 *
203 * Error results are never cached.
204 *
205 * @param {DirectoryEntry} dirEntry The DirectoryEntry to apply the method
206 * to.
207 * @param {string} methodName The name of the method to dispatch.
208 * @param {function(*)} successCallback The function to invoke if the method
209 * succeeds. The result of the method will be the one parameter to this
210 * callback.
211 * @param {function(*)} opt_errorCallback The function to invoke if the
212 * method fails. The result of the method will be the one parameter to
213 * this callback. If not provided, the default errorCallback will throw
214 * an exception.
215 */
216 function batchAsyncCall(entry, methodName, successCallback,
217 opt_errorCallback) {
218 var resultCache = methodName + '_resultCache_';
219
220 if (entry[resultCache]) {
221 // The result cache for this method already exists. Just invoke the
222 // successCallback with the result of the previuos call.
223 // Callback via a setTimeout so the sync/async semantics don't change
224 // based on whether or not the value is cached.
225 setTimeout(function() { successCallback(entry[resultCache]) }, 0);
226 return;
227 }
228
229 if (!opt_errorCallback) {
230 opt_errorCallback = util.ferr('Error calling ' + methodName + ' for: ' +
231 entry.fullPath);
232 }
233
234 var observerList = methodName + '_observers_';
235
236 if (entry[observerList]) {
237 // The observer list already exists, indicating we have a pending call
238 // out to this method. Add this caller to the list of observers and
239 // bail out.
240 entry[observerList].push([successCallback, opt_errorCallback]);
241 return;
242 }
243
244 entry[observerList] = [[successCallback, opt_errorCallback]];
245
246 function onComplete(success, result) {
247 if (success)
248 entry[resultCache] = result;
249
250 for (var i = 0; i < entry[observerList].length; i++) {
251 entry[observerList][i][success ? 0 : 1](result);
252 }
253
254 delete entry[observerList];
255 };
256
257 entry[methodName](function(rv) { onComplete(true, rv) },
258 function(rv) { onComplete(false, rv) });
259 }
260
261 /**
262 * Invoke callback in sync/async manner.
263 * @param {function(*)?} callback The callback. If null, nothing is called.
264 * @param {boolean} sync True iff the callback should be called synchronously.
265 * @param {*} callback_args... The rest are callback arguments.
266 */
267 function invokeCallback(callback, sync, callback_args) {
268 if (!callback)
269 return;
270 var args = Array.prototype.slice.call(arguments, 2);
271 if (sync) {
272 callback.apply(null, args);
273 } else {
274 setTimeout(function() { callback.apply(null, args); }, 0);
275 }
276 }
277
278 function cacheGDataProps(entry, successCallback,
279 opt_errorCallback, opt_sync) {
280 if ('gdata_' in entry) {
281 invokeCallback(successCallback, !!opt_sync, entry);
282 return;
283 }
284
285 entry.getGDataFileProperties = entry.getGDataFileProperties ||
286 function(callback) {
287 var queue = cacheGDataProps.queue_;
288 queue.callbacks.push(callback);
289 queue.urls.push(entry.toURL());
290 if (!queue.scheduled) {
291 queue.scheduled = true;
292 setTimeout(function() {
293 queue.scheduled = false;
294 var callbacks = queue.callbacks;
295 var urls = queue.urls;
296 chrome.fileBrowserPrivate.getGDataFileProperties(urls,
297 function(props) {
298 for (var i = 0; i < callbacks.length; i++) {
299 callbacks[i](props[i]);
300 }
301 });
302 queue.callbacks = [];
303 queue.urls = [];
304 }, 0);
305 }
306 };
307
308 batchAsyncCall(entry, 'getGDataFileProperties', function(props) {
309 entry.gdata_ = props;
310 if (successCallback)
311 successCallback(entry);
312 }, opt_errorCallback);
313 }
314
315 cacheGDataProps.queue_ = {
316 callbacks: [],
317 urls: [],
318 scheduled: false
319 };
320
321 function removeChildren(element) { 189 function removeChildren(element) {
322 element.textContent = ''; 190 element.textContent = '';
323 } 191 }
324 192
325 // Public statics. 193 // Public statics.
326 194
327 /** 195 /**
328 * List of dialog types. 196 * List of dialog types.
329 * 197 *
330 * Keep this in sync with FileManagerDialog::GetDialogTypeAsString, except 198 * Keep this in sync with FileManagerDialog::GetDialogTypeAsString, except
(...skipping 878 matching lines...) Expand 10 before | Expand all | Expand 10 after
1209 cr.ui.contextMenuHandler.setContextMenu(this.grid_, this.fileContextMenu_); 1077 cr.ui.contextMenuHandler.setContextMenu(this.grid_, this.fileContextMenu_);
1210 }; 1078 };
1211 1079
1212 /** 1080 /**
1213 * Initialize the file list table. 1081 * Initialize the file list table.
1214 */ 1082 */
1215 FileManager.prototype.initTable_ = function() { 1083 FileManager.prototype.initTable_ = function() {
1216 var renderFunction = this.table_.getRenderFunction(); 1084 var renderFunction = this.table_.getRenderFunction();
1217 this.table_.setRenderFunction(function(entry, parent) { 1085 this.table_.setRenderFunction(function(entry, parent) {
1218 var item = renderFunction(entry, parent); 1086 var item = renderFunction(entry, parent);
1219 this.styleGDataItem_(entry, item); 1087 this.displayGDataStyleInItem_(
1088 item, entry, this.metadataCache_.getCached(entry, 'gdata'));
1220 return item; 1089 return item;
1221 }.bind(this)); 1090 }.bind(this));
1222 1091
1223 var fullPage = (this.dialogType_ == FileManager.DialogType.FULL_PAGE); 1092 var fullPage = (this.dialogType_ == FileManager.DialogType.FULL_PAGE);
1224 1093
1225 var columns = [ 1094 var columns = [
1226 new cr.ui.table.TableColumn('name', str('NAME_COLUMN_LABEL'), 1095 new cr.ui.table.TableColumn('name', str('NAME_COLUMN_LABEL'),
1227 fullPage ? 64 : 324), 1096 fullPage ? 64 : 324),
1228 new cr.ui.table.TableColumn('size', str('SIZE_COLUMN_LABEL'), 1097 new cr.ui.table.TableColumn('size', str('SIZE_COLUMN_LABEL'),
1229 fullPage ? 15.5 : 92, true), 1098 fullPage ? 15.5 : 92, true),
(...skipping 537 matching lines...) Expand 10 before | Expand all | Expand 10 after
1767 }; 1636 };
1768 1637
1769 FileManager.prototype.decorateThumbnail_ = function(li, entry) { 1638 FileManager.prototype.decorateThumbnail_ = function(li, entry) {
1770 li.className = 'thumbnail-item'; 1639 li.className = 'thumbnail-item';
1771 1640
1772 if (this.showCheckboxes_) 1641 if (this.showCheckboxes_)
1773 li.appendChild(this.renderSelectionCheckbox_(entry)); 1642 li.appendChild(this.renderSelectionCheckbox_(entry));
1774 1643
1775 li.appendChild(this.renderThumbnailBox_(entry, false)); 1644 li.appendChild(this.renderThumbnailBox_(entry, false));
1776 li.appendChild(this.renderFileNameLabel_(entry)); 1645 li.appendChild(this.renderFileNameLabel_(entry));
1777 this.styleGDataItem_(entry, li); 1646 this.displayGDataStyleInItem_(
1647 li, entry, this.metadataCache_.getCached(entry, 'gdata'));
1778 }; 1648 };
1779 1649
1780 /** 1650 /**
1781 * Render the type column of the detail table. 1651 * Render the type column of the detail table.
1782 * 1652 *
1783 * Invoked by cr.ui.Table when a file needs to be rendered. 1653 * Invoked by cr.ui.Table when a file needs to be rendered.
1784 * 1654 *
1785 * @param {Entry} entry The Entry object to render. 1655 * @param {Entry} entry The Entry object to render.
1786 * @param {string} columnId The id of the column to be rendered. 1656 * @param {string} columnId The id of the column to be rendered.
1787 * @param {cr.ui.Table} table The table doing the rendering. 1657 * @param {cr.ui.Table} table The table doing the rendering.
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
1888 /** 1758 /**
1889 * Unmounts device. 1759 * Unmounts device.
1890 * @param {Entry} entry The entry to unmount. 1760 * @param {Entry} entry The entry to unmount.
1891 */ 1761 */
1892 FileManager.prototype.unmountVolume_ = function(entry) { 1762 FileManager.prototype.unmountVolume_ = function(entry) {
1893 this.directoryModel_.prepareUnmount(entry.fullPath); 1763 this.directoryModel_.prepareUnmount(entry.fullPath);
1894 this.unmountRequests_.push(entry.fullPath); 1764 this.unmountRequests_.push(entry.fullPath);
1895 chrome.fileBrowserPrivate.removeMount(entry.toURL()); 1765 chrome.fileBrowserPrivate.removeMount(entry.toURL());
1896 }; 1766 };
1897 1767
1898 FileManager.prototype.styleGDataItem_ = function(entry, listItem) { 1768 FileManager.prototype.displayGDataStyleInItem_ = function(
1899 if (!this.isOnGData()) 1769 listItem, entry, gdata) {
1770 if (!this.isOnGData() || !gdata)
1900 return; 1771 return;
1901 1772
1902 cacheGDataProps(entry, function(entry) { 1773 if (gdata.hosted) {
1903 if (!entry.gdata_) 1774 listItem.classList.add('gdata-hosted');
1904 return; 1775 }
1905 1776 if (entry.isDirectory || gdata.availableOffline) {
1906 if (entry.gdata_.isHosted) { 1777 listItem.classList.add('gdata-present');
1907 listItem.classList.add('gdata-hosted'); 1778 }
1908 }
1909 if (entry.isDirectory || FileManager.isAvaliableOffline_(entry.gdata_)) {
1910 listItem.classList.add('gdata-present');
1911 }
1912 }.bind(this));
1913 }; 1779 };
1914 1780
1915 /** 1781 /**
1916 * Render the Name column of the detail table. 1782 * Render the Name column of the detail table.
1917 * 1783 *
1918 * Invoked by cr.ui.Table when a file needs to be rendered. 1784 * Invoked by cr.ui.Table when a file needs to be rendered.
1919 * 1785 *
1920 * @param {Entry} entry The Entry object to render. 1786 * @param {Entry} entry The Entry object to render.
1921 * @param {string} columnId The id of the column to be rendered. 1787 * @param {string} columnId The id of the column to be rendered.
1922 * @param {cr.ui.Table} table The table doing the rendering. 1788 * @param {cr.ui.Table} table The table doing the rendering.
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
2055 var div = doc.createElement('div'); 1921 var div = doc.createElement('div');
2056 div.className = 'offline'; 1922 div.className = 'offline';
2057 1923
2058 if (entry.isDirectory) 1924 if (entry.isDirectory)
2059 return div; 1925 return div;
2060 1926
2061 var checkbox = this.renderCheckbox_(); 1927 var checkbox = this.renderCheckbox_();
2062 checkbox.classList.add('pin'); 1928 checkbox.classList.add('pin');
2063 checkbox.addEventListener('click', 1929 checkbox.addEventListener('click',
2064 this.onPinClick_.bind(this, checkbox, entry)); 1930 this.onPinClick_.bind(this, checkbox, entry));
1931 checkbox.style.display = 'none';
1932 div.appendChild(checkbox);
2065 1933
2066 if (this.isOnGData()) { 1934 if (this.isOnGData()) {
2067 cacheGDataProps(entry, function(entry) { 1935 this.displayOfflineInDiv_(
2068 if (entry.gdata_.isHosted) 1936 div, this.metadataCache_.getCached(entry, 'gdata'));
2069 return;
2070 checkbox.checked = entry.gdata_.isPinned;
2071 div.appendChild(checkbox);
2072 });
2073 } 1937 }
2074 return div; 1938 return div;
2075 }; 1939 };
2076 1940
1941 FileManager.prototype.displayOfflineInDiv_ = function(div, gdata) {
1942 if (!gdata) return;
1943 if (gdata.hosted) return;
1944 var checkbox = div.querySelector('.pin');
1945 if (!checkbox) return;
1946 checkbox.style.display = '';
1947 checkbox.checked = gdata.pinned;
1948 };
1949
2077 FileManager.prototype.refreshCurrentDirectoryMetadata_ = function() { 1950 FileManager.prototype.refreshCurrentDirectoryMetadata_ = function() {
2078 var entries = this.directoryModel_.getFileList().slice(); 1951 var entries = this.directoryModel_.getFileList().slice();
2079 this.metadataCache_.clear(entries, 'filesystem');
2080 // We don't pass callback here. When new metadata arrives, we have an 1952 // We don't pass callback here. When new metadata arrives, we have an
2081 // observer registered to update the UI. 1953 // observer registered to update the UI.
1954
1955 this.metadataCache_.clear(entries, 'filesystem');
2082 this.metadataCache_.get(entries, 'filesystem', null); 1956 this.metadataCache_.get(entries, 'filesystem', null);
1957 if (this.isOnGData()) {
1958 this.metadataCache_.clear(entries, 'gdata');
1959 this.metadataCache_.get(entries, 'gdata', null);
1960 }
2083 }; 1961 };
2084 1962
2085 FileManager.prototype.updateFilesystemPropertiesInUI_ = function( 1963 FileManager.prototype.updateMetadataInUI_ = function(
2086 urls, properties) { 1964 type, urls, properties) {
2087 if (this.listType_ != FileManager.ListType.DETAIL) return; 1965 if (this.listType_ != FileManager.ListType.DETAIL) return;
2088 1966
2089 var items = {}; 1967 var items = {};
1968 var entries = {};
2090 var dm = this.directoryModel_.getFileList(); 1969 var dm = this.directoryModel_.getFileList();
2091 for (var index = 0; index < dm.length; index++) { 1970 for (var index = 0; index < dm.length; index++) {
2092 var listItem = this.currentList_.getListItemByIndex(index); 1971 var listItem = this.currentList_.getListItemByIndex(index);
2093 if (!listItem) continue; 1972 if (!listItem) continue;
2094 var entry = dm.item(index); 1973 var entry = dm.item(index);
2095 items[entry.toURL()] = listItem; 1974 var url = entry.toURL();
1975 items[url] = listItem;
1976 entries[url] = entry;
2096 } 1977 }
2097 1978
2098 for (var index = 0; index < urls.length; index++) { 1979 for (var index = 0; index < urls.length; index++) {
2099 var url = urls[index]; 1980 var url = urls[index];
2100 if (!(url in items)) continue; 1981 if (!(url in items)) continue;
2101 var listItem = items[url]; 1982 var listItem = items[url];
1983 var entry = entries[url];
2102 var props = properties[index]; 1984 var props = properties[index];
2103 this.displayDateInDiv_(listItem.querySelector('.date'), props); 1985 if (type == 'filesystem') {
2104 this.displaySizeInDiv_(listItem.querySelector('.size'), props); 1986 this.displayDateInDiv_(listItem.querySelector('.date'), props);
2105 this.displayTypeInDiv_(listItem.querySelector('.type'), props); 1987 this.displaySizeInDiv_(listItem.querySelector('.size'), props);
1988 this.displayTypeInDiv_(listItem.querySelector('.type'), props);
1989 } else if (type == 'gdata') {
1990 this.displayOfflineInDiv_(listItem.querySelector('.offline'), props);
1991 this.displayGDataStyleInItem_(listItem, entry, props);
1992 }
2106 } 1993 }
2107 }; 1994 };
2108 1995
2109 /** 1996 /**
2110 * Restore the item which is being renamed while refreshing the file list. Do 1997 * Restore the item which is being renamed while refreshing the file list. Do
2111 * nothing if no item is being renamed or such an item disappeared. 1998 * nothing if no item is being renamed or such an item disappeared.
2112 * 1999 *
2113 * While refreshing file list it gets repopulated with new file entries. 2000 * While refreshing file list it gets repopulated with new file entries.
2114 * There is not a big difference wether DOM items stay the same or not. 2001 * There is not a big difference wether DOM items stay the same or not.
2115 * Except for the item that the user is renaming. 2002 * Except for the item that the user is renaming.
(...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after
2569 // For internal tasks we do not listen to the event to avoid 2456 // For internal tasks we do not listen to the event to avoid
2570 // handling the same task instance from multiple tabs. 2457 // handling the same task instance from multiple tabs.
2571 // So, we manually execute the task. 2458 // So, we manually execute the task.
2572 this.onFileTaskExecute_(task_parts[1], urls); 2459 this.onFileTaskExecute_(task_parts[1], urls);
2573 } 2460 }
2574 }.bind(this)); 2461 }.bind(this));
2575 }; 2462 };
2576 2463
2577 FileManager.prototype.executeIfAvailable_ = function(urls, callback) { 2464 FileManager.prototype.executeIfAvailable_ = function(urls, callback) {
2578 if (this.isOnGDataOffline()) { 2465 if (this.isOnGDataOffline()) {
2579 chrome.fileBrowserPrivate.getGDataFileProperties(urls, function(props) { 2466 this.metadataCache_.get(urls, 'gdata', function(props) {
2580 for (var i = 0; i != props.length; i++) { 2467 for (var i = 0; i != props.length; i++) {
2581 if (!FileManager.isAvaliableOffline_(props[i])) { 2468 if (!props[i].availableOffline) {
2582 this.alert.showHtml( 2469 this.alert.showHtml(
2583 str('OFFLINE_HEADER'), 2470 str('OFFLINE_HEADER'),
2584 strf( 2471 strf(
2585 urls.length == 1 ? 2472 urls.length == 1 ?
2586 'OFFLINE_MESSAGE' : 2473 'OFFLINE_MESSAGE' :
2587 'OFFLINE_MESSAGE_PLURAL', 2474 'OFFLINE_MESSAGE_PLURAL',
2588 str('OFFLINE_COLUMN_LABEL'))); 2475 str('OFFLINE_COLUMN_LABEL')));
2589 return; 2476 return;
2590 } 2477 }
2591 } 2478 }
2592 callback(urls); 2479 callback(urls);
2593 }.bind(this)); 2480 }.bind(this));
2594 } else { 2481 } else {
2595 callback(urls); 2482 callback(urls);
2596 } 2483 }
2597 }; 2484 };
2598 2485
2599 FileManager.isAvaliableOffline_ = function(gdata) {
2600 return gdata.isPresent && !gdata.isHosted;
2601 };
2602
2603 FileManager.prototype.isOffline = function() { 2486 FileManager.prototype.isOffline = function() {
2604 return !navigator.onLine; 2487 return !navigator.onLine;
2605 }; 2488 };
2606 2489
2607 FileManager.prototype.onOnlineOffline_ = function() { 2490 FileManager.prototype.onOnlineOffline_ = function() {
2608 if (this.isOffline()) { 2491 if (this.isOffline()) {
2609 console.log('OFFLINE'); 2492 console.log('OFFLINE');
2610 this.dialogContainer_.setAttribute('offline', true); 2493 this.dialogContainer_.setAttribute('offline', true);
2611 } else { 2494 } else {
2612 console.log('ONLINE'); 2495 console.log('ONLINE');
(...skipping 554 matching lines...) Expand 10 before | Expand all | Expand 10 after
3167 this.directoryModel_.changeDirectory(event.srcElement.path); 3050 this.directoryModel_.changeDirectory(event.srcElement.path);
3168 }; 3051 };
3169 3052
3170 FileManager.prototype.onCheckboxClick_ = function(event) { 3053 FileManager.prototype.onCheckboxClick_ = function(event) {
3171 var sm = this.directoryModel_.getFileListSelection(); 3054 var sm = this.directoryModel_.getFileListSelection();
3172 var listItem = this.findListItemForEvent_(event); 3055 var listItem = this.findListItemForEvent_(event);
3173 sm.setIndexSelected(listItem.listIndex, event.target.checked); 3056 sm.setIndexSelected(listItem.listIndex, event.target.checked);
3174 }; 3057 };
3175 3058
3176 FileManager.prototype.onPinClick_ = function(checkbox, entry, event) { 3059 FileManager.prototype.onPinClick_ = function(checkbox, entry, event) {
3060 // TODO(dgozman): revisit this method when gdata properties updated event
3061 // will be available.
3177 var self = this; 3062 var self = this;
3178 function callback(props) { 3063 function callback(props) {
3179 if (props.errorCode) { 3064 if (props.errorCode) {
3180 // TODO(serya): Do not show the message if unpin failed. 3065 // TODO(serya): Do not show the message if unpin failed.
3181 self.metadataCache_.get(entry, 'filesystem', function(filesystem) { 3066 self.metadataCache_.get(entry, 'filesystem', function(filesystem) {
3182 self.alert.showHtml(str('GDATA_OUT_OF_SPACE_HEADER'), 3067 self.alert.showHtml(str('GDATA_OUT_OF_SPACE_HEADER'),
3183 strf('GDATA_OUT_OF_SPACE_MESSAGE', 3068 strf('GDATA_OUT_OF_SPACE_MESSAGE',
3184 util.bytesToSi(filesystem.size))); 3069 util.bytesToSi(filesystem.size)));
3185 }); 3070 });
3186 } 3071 }
3187 checkbox.checked = entry.gdata_.isPinned = props[0].isPinned; 3072 // We don't have update events yet, so clear the cached data.
3073 self.metadataCache_.clear(entry, 'gdata');
3074 checkbox.checked = props[0].isPinned;
3188 } 3075 }
3189 var pin = checkbox.checked; 3076 var pin = checkbox.checked;
3190 cacheGDataProps(entry, function(entry) { 3077 this.metadataCache_.get(entry, 'gdata', function(gdata) {
3191 if (self.isOffline() && pin && !entry.gdata_.isPresent) { 3078 if (self.isOffline() && pin && !gdata.present) {
3192 // If we are offline, we cannot pin a file that is not already present. 3079 // If we are offline, we cannot pin a file that is not already present.
3193 checkbox.checked = false; // Revert the default action. 3080 checkbox.checked = false; // Revert the default action.
3194 self.alert.showHtml( 3081 self.alert.showHtml(
3195 str('OFFLINE_HEADER'), 3082 str('OFFLINE_HEADER'),
3196 strf('OFFLINE_MESSAGE', str('OFFLINE_COLUMN_LABEL'))); 3083 strf('OFFLINE_MESSAGE', str('OFFLINE_COLUMN_LABEL')));
3197 return; 3084 return;
3198 } 3085 }
3199 chrome.fileBrowserPrivate.pinGDataFile([entry.toURL()], pin, callback); 3086 chrome.fileBrowserPrivate.pinGDataFile([entry.toURL()], pin, callback);
3200 }); 3087 });
3201 event.preventDefault(); 3088 event.preventDefault();
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
3427 // then for real). Do not update the location then. 3314 // then for real). Do not update the location then.
3428 if (event.newDirEntry.fullPath != event.previousDirEntry.fullPath) { 3315 if (event.newDirEntry.fullPath != event.previousDirEntry.fullPath) {
3429 this.updateLocation_(event.initial, event.newDirEntry.fullPath); 3316 this.updateLocation_(event.initial, event.newDirEntry.fullPath);
3430 } 3317 }
3431 3318
3432 this.checkFreeSpace_(this.getCurrentDirectory()); 3319 this.checkFreeSpace_(this.getCurrentDirectory());
3433 3320
3434 // TODO(dgozman): title may be better than this. 3321 // TODO(dgozman): title may be better than this.
3435 this.document_.title = this.getCurrentDirectory().substr(1); 3322 this.document_.title = this.getCurrentDirectory().substr(1);
3436 3323
3437 if (this.metadataObserverId_) 3324 if (this.filesystemObserverId_)
3438 this.metadataCache_.removeObserver(this.metadataObserverId_); 3325 this.metadataCache_.removeObserver(this.filesystemObserverId_);
3326 if (this.gdataObserverId_)
3327 this.metadataCache_.removeObserver(this.gdataObserverId_);
3439 3328
3440 this.metadataObserverId_ = this.metadataCache_.addObserver( 3329 this.filesystemObserverId_ = this.metadataCache_.addObserver(
3441 this.directoryModel_.getCurrentDirEntry(), 3330 this.directoryModel_.getCurrentDirEntry(),
3442 MetadataCache.CHILDREN, 3331 MetadataCache.CHILDREN,
3443 'filesystem', 3332 'filesystem',
3444 this.updateFilesystemPropertiesInUI_.bind(this)); 3333 this.updateMetadataInUI_.bind(this, 'filesystem'));
3334
3335 if (this.isOnGData()) {
3336 this.gdataObserverId_ = this.metadataCache_.addObserver(
3337 this.directoryModel_.getCurrentDirEntry(),
3338 MetadataCache.CHILDREN,
3339 'gdata',
3340 this.updateMetadataInUI_.bind(this, 'gdata'));
3341 }
3445 3342
3446 var self = this; 3343 var self = this;
3447 3344
3448 if (this.watchedDirectoryUrl_) { 3345 if (this.watchedDirectoryUrl_) {
3449 if (this.watchedDirectoryUrl_ != event.previousDirEntry.toURL()) { 3346 if (this.watchedDirectoryUrl_ != event.previousDirEntry.toURL()) {
3450 console.warn('event.previousDirEntry does not match File Manager state', 3347 console.warn('event.previousDirEntry does not match File Manager state',
3451 event, this.watchedDirectoryUrl_); 3348 event, this.watchedDirectoryUrl_);
3452 } 3349 }
3453 chrome.fileBrowserPrivate.removeFileWatch(this.watchedDirectoryUrl_, 3350 chrome.fileBrowserPrivate.removeFileWatch(this.watchedDirectoryUrl_,
3454 function(result) { 3351 function(result) {
(...skipping 602 matching lines...) Expand 10 before | Expand all | Expand 10 after
4057 3954
4058 var onResolved = function(resolvedUrls) { 3955 var onResolved = function(resolvedUrls) {
4059 if (cancelled) return; 3956 if (cancelled) return;
4060 cleanup(); 3957 cleanup();
4061 selection.urls = resolvedUrls; 3958 selection.urls = resolvedUrls;
4062 // Call next method on a timeout, as it's unsafe to 3959 // Call next method on a timeout, as it's unsafe to
4063 // close a window from a callback. 3960 // close a window from a callback.
4064 setTimeout(this.callSelectFilesApiAndClose_.bind(this, selection), 0); 3961 setTimeout(this.callSelectFilesApiAndClose_.bind(this, selection), 0);
4065 }.bind(this); 3962 }.bind(this);
4066 3963
4067 var onGotProperties = function(properties) { 3964 var onProperties = function(properties) {
4068 for (var i = 0; i < properties.length; i++) { 3965 for (var i = 0; i < properties.length; i++) {
4069 if (properties[i].isPresent) { 3966 if (properties[i].present) {
4070 // For files already in GCache, we don't get any transfer updates. 3967 // For files already in GCache, we don't get any transfer updates.
4071 filesTotal--; 3968 filesTotal--;
4072 } 3969 }
4073 } 3970 }
4074 this.resolveSelectResults_(selection.urls, onResolved); 3971 this.resolveSelectResults_(selection.urls, onResolved);
4075 }.bind(this); 3972 }.bind(this);
4076 3973
4077 setup(); 3974 setup();
4078 chrome.fileBrowserPrivate.getGDataFileProperties( 3975 this.metadataCache_.get(selection.urls, 'gdata', onProperties);
4079 selection.urls, onGotProperties);
4080 }; 3976 };
4081 3977
4082 /** 3978 /**
4083 * Handle a click of the ok button. 3979 * Handle a click of the ok button.
4084 * 3980 *
4085 * The ok button has different UI labels depending on the type of dialog, but 3981 * The ok button has different UI labels depending on the type of dialog, but
4086 * in code it's always referred to as 'ok'. 3982 * in code it's always referred to as 'ok'.
4087 * 3983 *
4088 * @param {Event} event The click event. 3984 * @param {Event} event The click event.
4089 */ 3985 */
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
4329 4225
4330 handleSplitterDragEnd: function(e) { 4226 handleSplitterDragEnd: function(e) {
4331 Splitter.prototype.handleSplitterDragEnd.apply(this, arguments); 4227 Splitter.prototype.handleSplitterDragEnd.apply(this, arguments);
4332 this.ownerDocument.documentElement.classList.remove('col-resize'); 4228 this.ownerDocument.documentElement.classList.remove('col-resize');
4333 } 4229 }
4334 }; 4230 };
4335 4231
4336 customSplitter.decorate(splitterElement); 4232 customSplitter.decorate(splitterElement);
4337 }; 4233 };
4338 })(); 4234 })();
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698