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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/resources/file_manager/js/file_manager.js
===================================================================
--- chrome/browser/resources/file_manager/js/file_manager.js (revision 133422)
+++ chrome/browser/resources/file_manager/js/file_manager.js (working copy)
@@ -29,7 +29,8 @@
this.butterLastShowTime_ = 0;
this.watchedDirectoryUrl_ = null;
- this.metadataObserverId_ = null;
+ this.filesystemObserverId_ = null;
+ this.gdataObserverId_ = null;
this.commands_ = {};
@@ -185,139 +186,6 @@
return x;
}
-
- /**
- * Call an asynchronous method on dirEntry, batching multiple callers.
- *
- * This batches multiple callers into a single invocation, calling all
- * interested parties back when the async call completes.
- *
- * The Entry method to be invoked should take two callbacks as parameters
- * (one for success and one for failure), and it should invoke those
- * callbacks with a single parameter representing the result of the call.
- * Example methods are Entry.getMetadata() and FileEntry.file().
- *
- * Warning: Because this method caches the first result, subsequent changes
- * to the entry will not be visible to callers.
- *
- * Error results are never cached.
- *
- * @param {DirectoryEntry} dirEntry The DirectoryEntry to apply the method
- * to.
- * @param {string} methodName The name of the method to dispatch.
- * @param {function(*)} successCallback The function to invoke if the method
- * succeeds. The result of the method will be the one parameter to this
- * callback.
- * @param {function(*)} opt_errorCallback The function to invoke if the
- * method fails. The result of the method will be the one parameter to
- * this callback. If not provided, the default errorCallback will throw
- * an exception.
- */
- function batchAsyncCall(entry, methodName, successCallback,
- opt_errorCallback) {
- var resultCache = methodName + '_resultCache_';
-
- if (entry[resultCache]) {
- // The result cache for this method already exists. Just invoke the
- // successCallback with the result of the previuos call.
- // Callback via a setTimeout so the sync/async semantics don't change
- // based on whether or not the value is cached.
- setTimeout(function() { successCallback(entry[resultCache]) }, 0);
- return;
- }
-
- if (!opt_errorCallback) {
- opt_errorCallback = util.ferr('Error calling ' + methodName + ' for: ' +
- entry.fullPath);
- }
-
- var observerList = methodName + '_observers_';
-
- if (entry[observerList]) {
- // The observer list already exists, indicating we have a pending call
- // out to this method. Add this caller to the list of observers and
- // bail out.
- entry[observerList].push([successCallback, opt_errorCallback]);
- return;
- }
-
- entry[observerList] = [[successCallback, opt_errorCallback]];
-
- function onComplete(success, result) {
- if (success)
- entry[resultCache] = result;
-
- for (var i = 0; i < entry[observerList].length; i++) {
- entry[observerList][i][success ? 0 : 1](result);
- }
-
- delete entry[observerList];
- };
-
- entry[methodName](function(rv) { onComplete(true, rv) },
- function(rv) { onComplete(false, rv) });
- }
-
- /**
- * Invoke callback in sync/async manner.
- * @param {function(*)?} callback The callback. If null, nothing is called.
- * @param {boolean} sync True iff the callback should be called synchronously.
- * @param {*} callback_args... The rest are callback arguments.
- */
- function invokeCallback(callback, sync, callback_args) {
- if (!callback)
- return;
- var args = Array.prototype.slice.call(arguments, 2);
- if (sync) {
- callback.apply(null, args);
- } else {
- setTimeout(function() { callback.apply(null, args); }, 0);
- }
- }
-
- function cacheGDataProps(entry, successCallback,
- opt_errorCallback, opt_sync) {
- if ('gdata_' in entry) {
- invokeCallback(successCallback, !!opt_sync, entry);
- return;
- }
-
- entry.getGDataFileProperties = entry.getGDataFileProperties ||
- function(callback) {
- var queue = cacheGDataProps.queue_;
- queue.callbacks.push(callback);
- queue.urls.push(entry.toURL());
- if (!queue.scheduled) {
- queue.scheduled = true;
- setTimeout(function() {
- queue.scheduled = false;
- var callbacks = queue.callbacks;
- var urls = queue.urls;
- chrome.fileBrowserPrivate.getGDataFileProperties(urls,
- function(props) {
- for (var i = 0; i < callbacks.length; i++) {
- callbacks[i](props[i]);
- }
- });
- queue.callbacks = [];
- queue.urls = [];
- }, 0);
- }
- };
-
- batchAsyncCall(entry, 'getGDataFileProperties', function(props) {
- entry.gdata_ = props;
- if (successCallback)
- successCallback(entry);
- }, opt_errorCallback);
- }
-
- cacheGDataProps.queue_ = {
- callbacks: [],
- urls: [],
- scheduled: false
- };
-
function removeChildren(element) {
element.textContent = '';
}
@@ -1218,7 +1086,8 @@
var renderFunction = this.table_.getRenderFunction();
this.table_.setRenderFunction(function(entry, parent) {
var item = renderFunction(entry, parent);
- this.styleGDataItem_(entry, item);
+ this.displayGDataStyleInItem_(
+ item, entry, this.metadataCache_.getCached(entry, 'gdata'));
return item;
}.bind(this));
@@ -1777,7 +1646,8 @@
li.appendChild(this.renderThumbnailBox_(entry, false));
li.appendChild(this.renderFileNameLabel_(entry));
- this.styleGDataItem_(entry, li);
+ this.displayGDataStyleInItem_(
+ li, entry, this.metadataCache_.getCached(entry, 'gdata'));
};
/**
@@ -1895,21 +1765,17 @@
chrome.fileBrowserPrivate.removeMount(entry.toURL());
};
- FileManager.prototype.styleGDataItem_ = function(entry, listItem) {
- if (!this.isOnGData())
+ FileManager.prototype.displayGDataStyleInItem_ = function(
+ listItem, entry, gdata) {
+ if (!this.isOnGData() || !gdata)
return;
- cacheGDataProps(entry, function(entry) {
- if (!entry.gdata_)
- return;
-
- if (entry.gdata_.isHosted) {
- listItem.classList.add('gdata-hosted');
- }
- if (entry.isDirectory || FileManager.isAvaliableOffline_(entry.gdata_)) {
- listItem.classList.add('gdata-present');
- }
- }.bind(this));
+ if (gdata.hosted) {
+ listItem.classList.add('gdata-hosted');
+ }
+ if (entry.isDirectory || gdata.availableOffline) {
+ listItem.classList.add('gdata-present');
+ }
};
/**
@@ -2061,47 +1927,68 @@
checkbox.classList.add('pin');
checkbox.addEventListener('click',
this.onPinClick_.bind(this, checkbox, entry));
+ checkbox.style.display = 'none';
+ div.appendChild(checkbox);
if (this.isOnGData()) {
- cacheGDataProps(entry, function(entry) {
- if (entry.gdata_.isHosted)
- return;
- checkbox.checked = entry.gdata_.isPinned;
- div.appendChild(checkbox);
- });
+ this.displayOfflineInDiv_(
+ div, this.metadataCache_.getCached(entry, 'gdata'));
}
return div;
};
+ FileManager.prototype.displayOfflineInDiv_ = function(div, gdata) {
+ if (!gdata) return;
+ if (gdata.hosted) return;
+ var checkbox = div.querySelector('.pin');
+ if (!checkbox) return;
+ checkbox.style.display = '';
+ checkbox.checked = gdata.pinned;
+ };
+
FileManager.prototype.refreshCurrentDirectoryMetadata_ = function() {
var entries = this.directoryModel_.fileList.slice();
- this.metadataCache_.clear(entries, 'filesystem');
// We don't pass callback here. When new metadata arrives, we have an
// observer registered to update the UI.
+
+ this.metadataCache_.clear(entries, 'filesystem');
this.metadataCache_.get(entries, 'filesystem', null);
+ if (this.isOnGData()) {
+ this.metadataCache_.clear(entries, 'gdata');
+ this.metadataCache_.get(entries, 'gdata', null);
+ }
};
- FileManager.prototype.updateFilesystemPropertiesInUI_ = function(
- urls, properties) {
+ FileManager.prototype.updateMetadataInUI_ = function(
+ type, urls, properties) {
if (this.listType_ != FileManager.ListType.DETAIL) return;
var items = {};
+ var entries = {};
var dm = this.directoryModel_.fileList;
for (var index = 0; index < dm.length; index++) {
var listItem = this.currentList_.getListItemByIndex(index);
if (!listItem) continue;
var entry = dm.item(index);
- items[entry.toURL()] = listItem;
+ var url = entry.toURL();
+ items[url] = listItem;
+ entries[url] = entry;
}
for (var index = 0; index < urls.length; index++) {
var url = urls[index];
if (!(url in items)) continue;
var listItem = items[url];
+ var entry = entries[url];
var props = properties[index];
- this.displayDateInDiv_(listItem.querySelector('.date'), props);
- this.displaySizeInDiv_(listItem.querySelector('.size'), props);
- this.displayTypeInDiv_(listItem.querySelector('.type'), props);
+ if (type == 'filesystem') {
+ this.displayDateInDiv_(listItem.querySelector('.date'), props);
+ this.displaySizeInDiv_(listItem.querySelector('.size'), props);
+ this.displayTypeInDiv_(listItem.querySelector('.type'), props);
+ } else if (type == 'gdata') {
+ this.displayOfflineInDiv_(listItem.querySelector('.offline'), props);
+ this.displayGDataStyleInItem_(listItem, entry, props);
+ }
}
};
@@ -2574,9 +2461,9 @@
FileManager.prototype.executeIfAvailable_ = function(urls, callback) {
if (this.isOnGDataOffline()) {
- chrome.fileBrowserPrivate.getGDataFileProperties(urls, function(props) {
+ this.metadataCache_.get(urls, 'gdata', function(props) {
for (var i = 0; i != props.length; i++) {
- if (!FileManager.isAvaliableOffline_(props[i])) {
+ if (!props[i].availableOffline) {
this.alert.showHtml(
str('OFFLINE_HEADER'),
strf(
@@ -2594,10 +2481,6 @@
}
};
- FileManager.isAvaliableOffline_ = function(gdata) {
- return gdata.isPresent && !gdata.isHosted;
- };
-
FileManager.prototype.isOffline = function() {
return !navigator.onLine;
};
@@ -3168,6 +3051,8 @@
};
FileManager.prototype.onPinClick_ = function(checkbox, entry, event) {
+ // TODO(dgozman): revisit this method when gdata properties updated event
+ // will be available.
var self = this;
function callback(props) {
if (props.errorCode) {
@@ -3178,11 +3063,13 @@
util.bytesToSi(filesystem.size)));
});
}
- checkbox.checked = entry.gdata_.isPinned = props[0].isPinned;
+ // We don't have update events yet, so clear the cached data.
+ self.metadataCache_.clear(entry, 'gdata');
+ checkbox.checked = props[0].isPinned;
}
var pin = checkbox.checked;
- cacheGDataProps(entry, function(entry) {
- if (self.isOffline() && pin && !entry.gdata_.isPresent) {
+ this.metadataCache_.get(entry, 'gdata', function(gdata) {
+ if (self.isOffline() && pin && !gdata.present) {
// If we are offline, we cannot pin a file that is not already present.
checkbox.checked = false; // Revert the default action.
self.alert.showHtml(
@@ -3428,15 +3315,25 @@
// TODO(dgozman): title may be better than this.
this.document_.title = this.getCurrentDirectory().substr(1);
- if (this.metadataObserverId_)
- this.metadataCache_.removeObserver(this.metadataObserverId_);
+ if (this.filesystemObserverId_)
+ this.metadataCache_.removeObserver(this.filesystemObserverId_);
+ if (this.gdataObserverId_)
+ this.metadataCache_.removeObserver(this.gdataObserverId_);
- this.metadataObserverId_ = this.metadataCache_.addObserver(
+ this.filesystemObserverId_ = this.metadataCache_.addObserver(
this.directoryModel_.currentEntry,
MetadataCache.CHILDREN,
'filesystem',
- this.updateFilesystemPropertiesInUI_.bind(this));
+ this.updateMetadataInUI_.bind(this, 'filesystem'));
+ if (this.isOnGData()) {
+ this.gdataObserverId_ = this.metadataCache_.addObserver(
+ this.directoryModel_.currentEntry,
+ MetadataCache.CHILDREN,
+ 'gdata',
+ this.updateMetadataInUI_.bind(this, 'gdata'));
+ }
+
var self = this;
if (this.watchedDirectoryUrl_) {
@@ -4058,9 +3955,9 @@
setTimeout(this.callSelectFilesApiAndClose_.bind(this, selection), 0);
}.bind(this);
- var onGotProperties = function(properties) {
+ var onProperties = function(properties) {
for (var i = 0; i < properties.length; i++) {
- if (properties[i].isPresent) {
+ if (properties[i].present) {
// For files already in GCache, we don't get any transfer updates.
filesTotal--;
}
@@ -4069,8 +3966,7 @@
}.bind(this);
setup();
- chrome.fileBrowserPrivate.getGDataFileProperties(
- selection.urls, onGotProperties);
+ this.metadataCache_.get(selection.urls, 'gdata', onProperties);
};
/**

Powered by Google App Engine
This is Rietveld 408576698