Merge "UI index: enable drag and drop on a collection"

This commit is contained in:
Brad Fitzpatrick 2013-07-16 00:37:57 +00:00 committed by Gerrit Code Review
commit a6eac7fa35
5 changed files with 154 additions and 34 deletions

View File

@ -84,3 +84,12 @@
text-decoration: underline;
background: #999;
}
.cam-blobitem-dropactive {
outline: 0; /* Do not show an outline when container has focus. */
border-width: 5px;
border-color: #acf;
border-style: dashed;
position: relative;
border-radius: 5px;
}

View File

@ -133,6 +133,7 @@ camlistore.BlobItem.prototype.isCollection = function() {
return true;
};
/**
* @return {string}
*/
@ -282,8 +283,48 @@ camlistore.BlobItem.prototype.disposeInternal = function() {
* Called when component's element is known to be in the document.
*/
camlistore.BlobItem.prototype.enterDocument = function() {
camlistore.BlobItem.superClass_.enterDocument.call(this);
// Add event handlers here
camlistore.BlobItem.superClass_.enterDocument.call(this);
var thumbLink = goog.dom.getFirstElementChild(this.getElement());
this.eh_.listen(
thumbLink,
goog.events.EventType.DRAGENTER,
this.handleFileDragEnter_);
this.eh_.listen(
thumbLink,
goog.events.EventType.DRAGLEAVE,
this.handleFileDragLeave_);
};
/**
* @param {goog.events.Event} e The drag drop event.
* @private
*/
camlistore.BlobItem.prototype.handleFileDragEnter_ = function(e) {
e.preventDefault();
e.stopPropagation();
if (this.isCollection()) {
goog.dom.classes.add(this.getElement(), 'cam-blobitem-dropactive');
// we could dispatch another custom event to the container, but why bother
// since we can directly access it?
var container = this.getParent();
container.notifyDragEnter_(this);
}
};
/**
* @param {goog.events.Event} e The drag drop event.
* @private
*/
camlistore.BlobItem.prototype.handleFileDragLeave_ = function(e) {
e.preventDefault();
e.stopPropagation();
if (this.isCollection()) {
goog.dom.classes.remove(this.getElement(), 'cam-blobitem-dropactive');
var container = this.getParent();
container.notifyDragLeave_(this);
}
};
@ -293,5 +334,5 @@ camlistore.BlobItem.prototype.enterDocument = function() {
*/
camlistore.BlobItem.prototype.exitDocument = function() {
camlistore.BlobItem.superClass_.exitDocument.call(this);
// Clear event handlers here
this.eh_.removeAll();
};

View File

@ -203,14 +203,6 @@ camlistore.BlobItemContainer.prototype.enterDocument = function() {
this.fileDropHandler_,
goog.events.FileDropHandler.EventType.DROP,
this.handleFileDrop_);
this.eh_.listen(
this.getElement(),
goog.events.EventType.DRAGENTER,
this.handleFileDragEnter_);
this.eh_.listen(
this.getElement(),
goog.events.EventType.DRAGLEAVE,
this.handleFileDragLeave_);
};
@ -531,16 +523,25 @@ camlistore.BlobItemContainer.prototype.resetChildren_ = function() {
* @private
*/
camlistore.BlobItemContainer.prototype.handleFileDrop_ = function(e) {
this.resetDragState_();
var files = e.getBrowserEvent().dataTransfer.files;
for (var i = 0, n = files.length; i < n; i++) {
var file = files[i];
// TODO(bslatkin): Add an uploading item placeholder while the upload
// is in progress. Somehow pipe through the POST progress.
this.connection_.uploadFile(
file, goog.bind(this.handleUploadSuccess_, this, file));
}
var recipient = this.dragActiveElement_;
// TODO(mpl): I should adapt resetDragState_, but maybe Brett wanted
// to do something different with the whole d&d story, so leaving it
// as it is for now, and not using it.
this.dragActiveElement_ = null;
if (!recipient) {
console.log("No valid target to drag and drop on.");
return;
}
goog.dom.classes.remove(recipient.getElement(), 'cam-blobitem-dropactive');
var files = e.getBrowserEvent().dataTransfer.files;
for (var i = 0, n = files.length; i < n; i++) {
var file = files[i];
// TODO(bslatkin): Add an uploading item placeholder while the upload
// is in progress. Somehow pipe through the POST progress.
this.connection_.uploadFile(
file, goog.bind(this.handleUploadSuccess_, this, file, recipient.blobRef_));
}
};
@ -550,9 +551,9 @@ camlistore.BlobItemContainer.prototype.handleFileDrop_ = function(e) {
* @private
*/
camlistore.BlobItemContainer.prototype.handleUploadSuccess_ =
function(file, blobRef) {
function(file, recipient, blobRef) {
this.connection_.createPermanode(
goog.bind(this.handleCreatePermanodeSuccess_, this, file, blobRef));
goog.bind(this.handleCreatePermanodeSuccess_, this, file, recipient, blobRef));
};
@ -563,11 +564,11 @@ camlistore.BlobItemContainer.prototype.handleUploadSuccess_ =
* @private
*/
camlistore.BlobItemContainer.prototype.handleCreatePermanodeSuccess_ =
function(file, blobRef, permanode) {
function(file, recipient, blobRef, permanode) {
this.connection_.newSetAttributeClaim(
permanode, 'camliContent', blobRef,
goog.bind(this.handleSetAttributeSuccess_, this,
file, blobRef, permanode));
file, recipient, blobRef, permanode));
};
@ -578,11 +579,11 @@ camlistore.BlobItemContainer.prototype.handleCreatePermanodeSuccess_ =
* @private
*/
camlistore.BlobItemContainer.prototype.handleSetAttributeSuccess_ =
function(file, blobRef, permanode) {
this.connection_.describeWithThumbnails(
permanode,
this.thumbnailSize_,
goog.bind(this.handleDescribeSuccess_, this, permanode));
function(file, recipient, blobRef, permanode) {
this.connection_.describeWithThumbnails(
permanode,
this.thumbnailSize_,
goog.bind(this.handleDescribeSuccess_, this, recipient, permanode));
};
@ -592,9 +593,20 @@ camlistore.BlobItemContainer.prototype.handleSetAttributeSuccess_ =
* @private
*/
camlistore.BlobItemContainer.prototype.handleDescribeSuccess_ =
function(permanode, describeResult) {
var item = new camlistore.BlobItem(permanode, describeResult.meta);
this.addChildAt(item, this.hasCreateItem_ ? 1 : 0, true);
function(recipient, permanode, describeResult) {
var item = new camlistore.BlobItem(permanode, describeResult.meta);
this.addChildAt(item, this.hasCreateItem_ ? 1 : 0, true);
if (!recipient) {
return;
}
if (this.hasCreateItem_) {
var createItem = this.getChildAt(0);
if (!createItem || recipient == createItem) {
return;
}
}
this.connection_.newAddAttributeClaim(
recipient, 'camliMember', permanode);
};
@ -608,7 +620,30 @@ camlistore.BlobItemContainer.prototype.resetDragState_ = function() {
this.dragDepth_ = 0;
};
/**
* @param {camlistore.BlobItem} blobitem the target collection where we want to drop
* @private
*/
camlistore.BlobItemContainer.prototype.notifyDragEnter_ =
function(blobitem) {
if (this.dragActiveElement_ == null) {
// TODO(mpl): show the drag-message; need to figure out the flickering issue
this.dragActiveElement_ = blobitem;
}
};
/**
* @param {camlistore.BlobItem} blobitem the target collection where we want to drop
* @private
*/
camlistore.BlobItemContainer.prototype.notifyDragLeave_ =
function(blobitem) {
if (this.dragActiveElement_ === blobitem) {
this.dragActiveElement_ = null;
}
};
// TODO(mpl): not using it anymore. remove if Brett is ok with it.
/**
* @param {goog.events.Event} e The drag enter event.
* @private
@ -622,6 +657,7 @@ camlistore.BlobItemContainer.prototype.handleFileDragEnter_ = function(e) {
};
// TODO(mpl): not using it anymore. remove if Brett is ok with it.
/**
* @param {goog.events.Event} e The drag leave event.
* @private

View File

@ -71,8 +71,40 @@ camlistore.CreateItem.prototype.disposeInternal = function() {
*/
camlistore.CreateItem.prototype.enterDocument = function() {
camlistore.CreateItem.superClass_.enterDocument.call(this);
var plusEl = goog.dom.getFirstElementChild(this.getElement());
this.eh_.listen(
plusEl,
goog.events.EventType.DRAGENTER,
this.handleFileDragEnter_);
this.eh_.listen(
plusEl,
goog.events.EventType.DRAGLEAVE,
this.handleFileDragLeave_);
};
/**
* @param {goog.events.Event} e The drag drop event.
* @private
*/
camlistore.CreateItem.prototype.handleFileDragEnter_ = function(e) {
e.preventDefault();
e.stopPropagation();
goog.dom.classes.add(this.getElement(), 'cam-blobitem-dropactive');
var container = this.getParent();
container.notifyDragEnter_(this);
};
/**
* @param {goog.events.Event} e The drag drop event.
* @private
*/
camlistore.CreateItem.prototype.handleFileDragLeave_ = function(e) {
e.preventDefault();
e.stopPropagation();
goog.dom.classes.remove(this.getElement(), 'cam-blobitem-dropactive');
var container = this.getParent();
container.notifyDragLeave_(this);
};
/**
* Called when component's element is known to have been removed from the

View File

@ -447,7 +447,9 @@ function(blobref, success, opt_fail, e) {
alert("upload permanode fail, expected blobRef not in response");
return;
}
success(blobref);
if (success) {
success(blobref);
}
},
this.safeFail_(opt_fail),
e