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

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: 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 880 matching lines...) Expand 10 before | Expand all | Expand 10 after
1211 cr.ui.contextMenuHandler.setContextMenu(this.grid_, this.fileContextMenu_); 1079 cr.ui.contextMenuHandler.setContextMenu(this.grid_, this.fileContextMenu_);
1212 }; 1080 };
1213 1081
1214 /** 1082 /**
1215 * Initialize the file list table. 1083 * Initialize the file list table.
1216 */ 1084 */
1217 FileManager.prototype.initTable_ = function() { 1085 FileManager.prototype.initTable_ = function() {
1218 var renderFunction = this.table_.getRenderFunction(); 1086 var renderFunction = this.table_.getRenderFunction();
1219 this.table_.setRenderFunction(function(entry, parent) { 1087 this.table_.setRenderFunction(function(entry, parent) {
1220 var item = renderFunction(entry, parent); 1088 var item = renderFunction(entry, parent);
1221 this.styleGDataItem_(entry, item); 1089 this.displayGDataStyleInItem_(
1090 item, entry, this.metadataCache_.getCached(entry, 'gdata'));
1222 return item; 1091 return item;
1223 }.bind(this)); 1092 }.bind(this));
1224 1093
1225 var fullPage = (this.dialogType_ == FileManager.DialogType.FULL_PAGE); 1094 var fullPage = (this.dialogType_ == FileManager.DialogType.FULL_PAGE);
1226 1095
1227 var columns = [ 1096 var columns = [
1228 new cr.ui.table.TableColumn('name', str('NAME_COLUMN_LABEL'), 1097 new cr.ui.table.TableColumn('name', str('NAME_COLUMN_LABEL'),
1229 fullPage ? 64 : 324), 1098 fullPage ? 64 : 324),
1230 new cr.ui.table.TableColumn('size', str('SIZE_COLUMN_LABEL'), 1099 new cr.ui.table.TableColumn('size', str('SIZE_COLUMN_LABEL'),
1231 fullPage ? 15.5 : 92, true), 1100 fullPage ? 15.5 : 92, true),
(...skipping 538 matching lines...) Expand 10 before | Expand all | Expand 10 after
1770 }; 1639 };
1771 1640
1772 FileManager.prototype.decorateThumbnail_ = function(li, entry) { 1641 FileManager.prototype.decorateThumbnail_ = function(li, entry) {
1773 li.className = 'thumbnail-item'; 1642 li.className = 'thumbnail-item';
1774 1643
1775 if (this.showCheckboxes_) 1644 if (this.showCheckboxes_)
1776 li.appendChild(this.renderSelectionCheckbox_(entry)); 1645 li.appendChild(this.renderSelectionCheckbox_(entry));
1777 1646
1778 li.appendChild(this.renderThumbnailBox_(entry, false)); 1647 li.appendChild(this.renderThumbnailBox_(entry, false));
1779 li.appendChild(this.renderFileNameLabel_(entry)); 1648 li.appendChild(this.renderFileNameLabel_(entry));
1780 this.styleGDataItem_(entry, li); 1649 this.displayGDataStyleInItem_(
1650 li, entry, this.metadataCache_.getCached(entry, 'gdata'));
1781 }; 1651 };
1782 1652
1783 /** 1653 /**
1784 * Render the type column of the detail table. 1654 * Render the type column of the detail table.
1785 * 1655 *
1786 * Invoked by cr.ui.Table when a file needs to be rendered. 1656 * Invoked by cr.ui.Table when a file needs to be rendered.
1787 * 1657 *
1788 * @param {Entry} entry The Entry object to render. 1658 * @param {Entry} entry The Entry object to render.
1789 * @param {string} columnId The id of the column to be rendered. 1659 * @param {string} columnId The id of the column to be rendered.
1790 * @param {cr.ui.Table} table The table doing the rendering. 1660 * @param {cr.ui.Table} table The table doing the rendering.
(...skipping 97 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 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
2054 var div = doc.createElement('div'); 1920 var div = doc.createElement('div');
2055 div.className = 'offline'; 1921 div.className = 'offline';
2056 1922
2057 if (entry.isDirectory) 1923 if (entry.isDirectory)
2058 return div; 1924 return div;
2059 1925
2060 var checkbox = this.renderCheckbox_(); 1926 var checkbox = this.renderCheckbox_();
2061 checkbox.classList.add('pin'); 1927 checkbox.classList.add('pin');
2062 checkbox.addEventListener('click', 1928 checkbox.addEventListener('click',
2063 this.onPinClick_.bind(this, checkbox, entry)); 1929 this.onPinClick_.bind(this, checkbox, entry));
1930 checkbox.style.display = 'none';
1931 div.appendChild(checkbox);
2064 1932
2065 if (this.isOnGData()) { 1933 if (this.isOnGData()) {
2066 cacheGDataProps(entry, function(entry) { 1934 this.displayOfflineInDiv_(
2067 if (entry.gdata_.isHosted) 1935 div, this.metadataCache_.getCached(entry, 'gdata'));
2068 return;
2069 checkbox.checked = entry.gdata_.isPinned;
2070 div.appendChild(checkbox);
2071 });
2072 } 1936 }
2073 return div; 1937 return div;
2074 }; 1938 };
2075 1939
1940 FileManager.prototype.displayOfflineInDiv_ = function(div, gdata) {
1941 if (!gdata) return;
1942 if (gdata.hosted) return;
1943 var checkbox = div.querySelector('.pin');
1944 if (!checkbox) return;
1945 checkbox.style.display = '';
1946 checkbox.checked = gdata.pinned;
1947 };
1948
2076 FileManager.prototype.refreshCurrentDirectoryMetadata_ = function() { 1949 FileManager.prototype.refreshCurrentDirectoryMetadata_ = function() {
2077 var entries = this.directoryModel_.fileList.slice(); 1950 var entries = this.directoryModel_.fileList.slice();
2078 this.metadataCache_.clear(entries, 'filesystem');
2079 // We don't pass callback here. When new metadata arrives, we have an 1951 // We don't pass callback here. When new metadata arrives, we have an
2080 // observer registered to update the UI. 1952 // observer registered to update the UI.
1953
1954 this.metadataCache_.clear(entries, 'filesystem');
2081 this.metadataCache_.get(entries, 'filesystem', null); 1955 this.metadataCache_.get(entries, 'filesystem', null);
1956 if (this.isOnGData()) {
1957 this.metadataCache_.clear(entries, 'gdata');
1958 this.metadataCache_.get(entries, 'gdata', null);
1959 }
2082 }; 1960 };
2083 1961
2084 FileManager.prototype.updateFilesystemPropertiesInUI_ = function( 1962 FileManager.prototype.updateMetadataInUI_ = function(
2085 urls, properties) { 1963 type, urls, properties) {
2086 if (this.listType_ != FileManager.ListType.DETAIL) return; 1964 if (this.listType_ != FileManager.ListType.DETAIL) return;
2087 1965
2088 var items = {}; 1966 var items = {};
1967 var entries = {};
2089 var dm = this.directoryModel_.fileList; 1968 var dm = this.directoryModel_.fileList;
2090 for (var index = 0; index < dm.length; index++) { 1969 for (var index = 0; index < dm.length; index++) {
2091 var listItem = this.currentList_.getListItemByIndex(index); 1970 var listItem = this.currentList_.getListItemByIndex(index);
2092 if (!listItem) continue; 1971 if (!listItem) continue;
2093 var entry = dm.item(index); 1972 var entry = dm.item(index);
2094 items[entry.toURL()] = listItem; 1973 var url = entry.toURL();
1974 items[url] = listItem;
1975 entries[url] = entry;
2095 } 1976 }
2096 1977
2097 for (var index = 0; index < urls.length; index++) { 1978 for (var index = 0; index < urls.length; index++) {
2098 var url = urls[index]; 1979 var url = urls[index];
2099 if (!(url in items)) continue; 1980 if (!(url in items)) continue;
2100 var listItem = items[url]; 1981 var listItem = items[url];
1982 var entry = entries[url];
2101 var props = properties[index]; 1983 var props = properties[index];
2102 this.displayDateInDiv_(listItem.querySelector('.date'), props); 1984 if (type == 'filesystem') {
2103 this.displaySizeInDiv_(listItem.querySelector('.size'), props); 1985 this.displayDateInDiv_(listItem.querySelector('.date'), props);
2104 this.displayTypeInDiv_(listItem.querySelector('.type'), props); 1986 this.displaySizeInDiv_(listItem.querySelector('.size'), props);
1987 this.displayTypeInDiv_(listItem.querySelector('.type'), props);
1988 } else if (type == 'gdata') {
1989 this.displayOfflineInDiv_(listItem.querySelector('.offline'), props);
1990 this.displayGDataStyleInItem_(listItem, entry, props);
1991 }
2105 } 1992 }
2106 }; 1993 };
2107 1994
2108 /** 1995 /**
2109 * Restore the item which is being renamed while refreshing the file list. Do 1996 * Restore the item which is being renamed while refreshing the file list. Do
2110 * nothing if no item is being renamed or such an item disappeared. 1997 * nothing if no item is being renamed or such an item disappeared.
2111 * 1998 *
2112 * While refreshing file list it gets repopulated with new file entries. 1999 * While refreshing file list it gets repopulated with new file entries.
2113 * There is not a big difference wether DOM items stay the same or not. 2000 * There is not a big difference wether DOM items stay the same or not.
2114 * Except for the item that the user is renaming. 2001 * Except for the item that the user is renaming.
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after
2567 // For internal tasks we do not listen to the event to avoid 2454 // For internal tasks we do not listen to the event to avoid
2568 // handling the same task instance from multiple tabs. 2455 // handling the same task instance from multiple tabs.
2569 // So, we manually execute the task. 2456 // So, we manually execute the task.
2570 this.onFileTaskExecute_(task_parts[1], urls); 2457 this.onFileTaskExecute_(task_parts[1], urls);
2571 } 2458 }
2572 }.bind(this)); 2459 }.bind(this));
2573 }; 2460 };
2574 2461
2575 FileManager.prototype.executeIfAvailable_ = function(urls, callback) { 2462 FileManager.prototype.executeIfAvailable_ = function(urls, callback) {
2576 if (this.isOnGDataOffline()) { 2463 if (this.isOnGDataOffline()) {
2577 chrome.fileBrowserPrivate.getGDataFileProperties(urls, function(props) { 2464 this.metadataCache_.get(urls, 'gdata', function(props) {
2578 for (var i = 0; i != props.length; i++) { 2465 for (var i = 0; i != props.length; i++) {
2579 if (!FileManager.isAvaliableOffline_(props[i])) { 2466 if (!props[i].availableOffline) {
2580 this.alert.showHtml( 2467 this.alert.showHtml(
2581 str('OFFLINE_HEADER'), 2468 str('OFFLINE_HEADER'),
2582 strf( 2469 strf(
2583 urls.length == 1 ? 2470 urls.length == 1 ?
2584 'OFFLINE_MESSAGE' : 2471 'OFFLINE_MESSAGE' :
2585 'OFFLINE_MESSAGE_PLURAL', 2472 'OFFLINE_MESSAGE_PLURAL',
2586 str('OFFLINE_COLUMN_LABEL'))); 2473 str('OFFLINE_COLUMN_LABEL')));
2587 return; 2474 return;
2588 } 2475 }
2589 } 2476 }
2590 callback(urls); 2477 callback(urls);
2591 }.bind(this)); 2478 }.bind(this));
2592 } else { 2479 } else {
2593 callback(urls); 2480 callback(urls);
2594 } 2481 }
2595 }; 2482 };
2596 2483
2597 FileManager.isAvaliableOffline_ = function(gdata) {
2598 return gdata.isPresent && !gdata.isHosted;
2599 };
2600
2601 FileManager.prototype.isOffline = function() { 2484 FileManager.prototype.isOffline = function() {
2602 return !navigator.onLine; 2485 return !navigator.onLine;
2603 }; 2486 };
2604 2487
2605 FileManager.prototype.onOnlineOffline_ = function() { 2488 FileManager.prototype.onOnlineOffline_ = function() {
2606 if (this.isOffline()) { 2489 if (this.isOffline()) {
2607 console.log('OFFLINE'); 2490 console.log('OFFLINE');
2608 this.dialogContainer_.setAttribute('offline', true); 2491 this.dialogContainer_.setAttribute('offline', true);
2609 } else { 2492 } else {
2610 console.log('ONLINE'); 2493 console.log('ONLINE');
(...skipping 550 matching lines...) Expand 10 before | Expand all | Expand 10 after
3161 this.directoryModel_.changeDirectory(event.srcElement.path); 3044 this.directoryModel_.changeDirectory(event.srcElement.path);
3162 }; 3045 };
3163 3046
3164 FileManager.prototype.onCheckboxClick_ = function(event) { 3047 FileManager.prototype.onCheckboxClick_ = function(event) {
3165 var sm = this.directoryModel_.fileListSelection; 3048 var sm = this.directoryModel_.fileListSelection;
3166 var listItem = this.findListItemForEvent_(event); 3049 var listItem = this.findListItemForEvent_(event);
3167 sm.setIndexSelected(listItem.listIndex, event.target.checked); 3050 sm.setIndexSelected(listItem.listIndex, event.target.checked);
3168 }; 3051 };
3169 3052
3170 FileManager.prototype.onPinClick_ = function(checkbox, entry, event) { 3053 FileManager.prototype.onPinClick_ = function(checkbox, entry, event) {
3054 // TODO(dgozman): revisit this method when gdata properties updated event
3055 // will be available.
3171 var self = this; 3056 var self = this;
3172 function callback(props) { 3057 function callback(props) {
3173 if (props.errorCode) { 3058 if (props.errorCode) {
3174 // TODO(serya): Do not show the message if unpin failed. 3059 // TODO(serya): Do not show the message if unpin failed.
3175 self.metadataCache_.get(entry, 'filesystem', function(filesystem) { 3060 self.metadataCache_.get(entry, 'filesystem', function(filesystem) {
3176 self.alert.showHtml(str('GDATA_OUT_OF_SPACE_HEADER'), 3061 self.alert.showHtml(str('GDATA_OUT_OF_SPACE_HEADER'),
3177 strf('GDATA_OUT_OF_SPACE_MESSAGE', 3062 strf('GDATA_OUT_OF_SPACE_MESSAGE',
3178 util.bytesToSi(filesystem.size))); 3063 util.bytesToSi(filesystem.size)));
3179 }); 3064 });
3180 } 3065 }
3181 checkbox.checked = entry.gdata_.isPinned = props[0].isPinned; 3066 // We don't have update events yet, so clear the cached data.
3067 self.metadataCache_.clear(entry, 'gdata');
3068 checkbox.checked = props[0].isPinned;
3182 } 3069 }
3183 var pin = checkbox.checked; 3070 var pin = checkbox.checked;
3184 cacheGDataProps(entry, function(entry) { 3071 this.metadataCache_.get(entry, 'gdata', function(gdata) {
3185 if (self.isOffline() && pin && !entry.gdata_.isPresent) { 3072 if (self.isOffline() && pin && !gdata.present) {
3186 // If we are offline, we cannot pin a file that is not already present. 3073 // If we are offline, we cannot pin a file that is not already present.
3187 checkbox.checked = false; // Revert the default action. 3074 checkbox.checked = false; // Revert the default action.
3188 self.alert.showHtml( 3075 self.alert.showHtml(
3189 str('OFFLINE_HEADER'), 3076 str('OFFLINE_HEADER'),
3190 strf('OFFLINE_MESSAGE', str('OFFLINE_COLUMN_LABEL'))); 3077 strf('OFFLINE_MESSAGE', str('OFFLINE_COLUMN_LABEL')));
3191 return; 3078 return;
3192 } 3079 }
3193 chrome.fileBrowserPrivate.pinGDataFile([entry.toURL()], pin, callback); 3080 chrome.fileBrowserPrivate.pinGDataFile([entry.toURL()], pin, callback);
3194 }); 3081 });
3195 event.preventDefault(); 3082 event.preventDefault();
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
3421 // then for real). Do not update the location then. 3308 // then for real). Do not update the location then.
3422 if (event.newDirEntry.fullPath != event.previousDirEntry.fullPath) { 3309 if (event.newDirEntry.fullPath != event.previousDirEntry.fullPath) {
3423 this.updateLocation_(event.initial, event.newDirEntry.fullPath); 3310 this.updateLocation_(event.initial, event.newDirEntry.fullPath);
3424 } 3311 }
3425 3312
3426 this.checkFreeSpace_(this.getCurrentDirectory()); 3313 this.checkFreeSpace_(this.getCurrentDirectory());
3427 3314
3428 // TODO(dgozman): title may be better than this. 3315 // TODO(dgozman): title may be better than this.
3429 this.document_.title = this.getCurrentDirectory().substr(1); 3316 this.document_.title = this.getCurrentDirectory().substr(1);
3430 3317
3431 if (this.metadataObserverId_) 3318 if (this.filesystemObserverId_)
3432 this.metadataCache_.removeObserver(this.metadataObserverId_); 3319 this.metadataCache_.removeObserver(this.filesystemObserverId_);
3320 if (this.gdataObserverId_)
3321 this.metadataCache_.removeObserver(this.gdataObserverId_);
3433 3322
3434 this.metadataObserverId_ = this.metadataCache_.addObserver( 3323 this.filesystemObserverId_ = this.metadataCache_.addObserver(
3435 this.directoryModel_.currentEntry, 3324 this.directoryModel_.currentEntry,
3436 MetadataCache.CHILDREN, 3325 MetadataCache.CHILDREN,
3437 'filesystem', 3326 'filesystem',
3438 this.updateFilesystemPropertiesInUI_.bind(this)); 3327 this.updateMetadataInUI_.bind(this, 'filesystem'));
3328
3329 if (this.isOnGData()) {
3330 this.gdataObserverId_ = this.metadataCache_.addObserver(
3331 this.directoryModel_.currentEntry,
3332 MetadataCache.CHILDREN,
3333 'gdata',
3334 this.updateMetadataInUI_.bind(this, 'gdata'));
3335 }
3439 3336
3440 var self = this; 3337 var self = this;
3441 3338
3442 if (this.watchedDirectoryUrl_) { 3339 if (this.watchedDirectoryUrl_) {
3443 if (this.watchedDirectoryUrl_ != event.previousDirEntry.toURL()) { 3340 if (this.watchedDirectoryUrl_ != event.previousDirEntry.toURL()) {
3444 console.warn('event.previousDirEntry does not match File Manager state', 3341 console.warn('event.previousDirEntry does not match File Manager state',
3445 event, this.watchedDirectoryUrl_); 3342 event, this.watchedDirectoryUrl_);
3446 } 3343 }
3447 chrome.fileBrowserPrivate.removeFileWatch(this.watchedDirectoryUrl_, 3344 chrome.fileBrowserPrivate.removeFileWatch(this.watchedDirectoryUrl_,
3448 function(result) { 3345 function(result) {
(...skipping 602 matching lines...) Expand 10 before | Expand all | Expand 10 after
4051 3948
4052 var onResolved = function(resolvedUrls) { 3949 var onResolved = function(resolvedUrls) {
4053 if (cancelled) return; 3950 if (cancelled) return;
4054 cleanup(); 3951 cleanup();
4055 selection.urls = resolvedUrls; 3952 selection.urls = resolvedUrls;
4056 // Call next method on a timeout, as it's unsafe to 3953 // Call next method on a timeout, as it's unsafe to
4057 // close a window from a callback. 3954 // close a window from a callback.
4058 setTimeout(this.callSelectFilesApiAndClose_.bind(this, selection), 0); 3955 setTimeout(this.callSelectFilesApiAndClose_.bind(this, selection), 0);
4059 }.bind(this); 3956 }.bind(this);
4060 3957
4061 var onGotProperties = function(properties) { 3958 var onProperties = function(properties) {
4062 for (var i = 0; i < properties.length; i++) { 3959 for (var i = 0; i < properties.length; i++) {
4063 if (properties[i].isPresent) { 3960 if (properties[i].present) {
4064 // For files already in GCache, we don't get any transfer updates. 3961 // For files already in GCache, we don't get any transfer updates.
4065 filesTotal--; 3962 filesTotal--;
4066 } 3963 }
4067 } 3964 }
4068 this.resolveSelectResults_(selection.urls, onResolved); 3965 this.resolveSelectResults_(selection.urls, onResolved);
4069 }.bind(this); 3966 }.bind(this);
4070 3967
4071 setup(); 3968 setup();
4072 chrome.fileBrowserPrivate.getGDataFileProperties( 3969 this.metadataCache_.get(selection.urls, 'gdata', onProperties);
4073 selection.urls, onGotProperties);
4074 }; 3970 };
4075 3971
4076 /** 3972 /**
4077 * Handle a click of the ok button. 3973 * Handle a click of the ok button.
4078 * 3974 *
4079 * The ok button has different UI labels depending on the type of dialog, but 3975 * The ok button has different UI labels depending on the type of dialog, but
4080 * in code it's always referred to as 'ok'. 3976 * in code it's always referred to as 'ok'.
4081 * 3977 *
4082 * @param {Event} event The click event. 3978 * @param {Event} event The click event.
4083 */ 3979 */
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
4323 4219
4324 handleSplitterDragEnd: function(e) { 4220 handleSplitterDragEnd: function(e) {
4325 Splitter.prototype.handleSplitterDragEnd.apply(this, arguments); 4221 Splitter.prototype.handleSplitterDragEnd.apply(this, arguments);
4326 this.ownerDocument.documentElement.classList.remove('col-resize'); 4222 this.ownerDocument.documentElement.classList.remove('col-resize');
4327 } 4223 }
4328 }; 4224 };
4329 4225
4330 customSplitter.decorate(splitterElement); 4226 customSplitter.decorate(splitterElement);
4331 }; 4227 };
4332 })(); 4228 })();
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698