зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1302661 - Add multiple bookmark items when multiple URLs are dropped as single item. r=mak
This commit is contained in:
Родитель
63b579c075
Коммит
d2037e755b
|
@ -1488,29 +1488,31 @@ var PlacesControllerDragHelper = {
|
|||
continue;
|
||||
|
||||
let data = dt.mozGetDataAt(flavor, i);
|
||||
let dragged;
|
||||
let nodes;
|
||||
try {
|
||||
dragged = PlacesUtils.unwrapNodes(data, flavor)[0];
|
||||
nodes = PlacesUtils.unwrapNodes(data, flavor);
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Only bookmarks and urls can be dropped into tag containers.
|
||||
if (ip.isTag &&
|
||||
dragged.type != PlacesUtils.TYPE_X_MOZ_URL &&
|
||||
(dragged.type != PlacesUtils.TYPE_X_MOZ_PLACE ||
|
||||
(dragged.uri && dragged.uri.startsWith("place:")) ))
|
||||
return false;
|
||||
for (let dragged of nodes) {
|
||||
// Only bookmarks and urls can be dropped into tag containers.
|
||||
if (ip.isTag &&
|
||||
dragged.type != PlacesUtils.TYPE_X_MOZ_URL &&
|
||||
(dragged.type != PlacesUtils.TYPE_X_MOZ_PLACE ||
|
||||
(dragged.uri && dragged.uri.startsWith("place:")) ))
|
||||
return false;
|
||||
|
||||
// The following loop disallows the dropping of a folder on itself or
|
||||
// on any of its descendants.
|
||||
if (dragged.type == PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER ||
|
||||
(dragged.uri && dragged.uri.startsWith("place:")) ) {
|
||||
let parentId = ip.itemId;
|
||||
while (parentId != PlacesUtils.placesRootId) {
|
||||
if (dragged.concreteId == parentId || dragged.id == parentId)
|
||||
return false;
|
||||
parentId = PlacesUtils.bookmarks.getFolderIdForItem(parentId);
|
||||
// The following loop disallows the dropping of a folder on itself or
|
||||
// on any of its descendants.
|
||||
if (dragged.type == PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER ||
|
||||
(dragged.uri && dragged.uri.startsWith("place:")) ) {
|
||||
let parentId = ip.itemId;
|
||||
while (parentId != PlacesUtils.placesRootId) {
|
||||
if (dragged.concreteId == parentId || dragged.id == parentId)
|
||||
return false;
|
||||
parentId = PlacesUtils.bookmarks.getFolderIdForItem(parentId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1576,63 +1578,77 @@ var PlacesControllerDragHelper = {
|
|||
let parentGuid = PlacesUIUtils.useAsyncTransactions ?
|
||||
(yield insertionPoint.promiseGuid()) : null;
|
||||
let tagName = insertionPoint.tagName;
|
||||
|
||||
// Following flavors may contain duplicated data.
|
||||
let duplicable = new Map();
|
||||
duplicable.set(PlacesUtils.TYPE_UNICODE, new Set());
|
||||
duplicable.set(PlacesUtils.TYPE_X_MOZ_URL, new Set());
|
||||
|
||||
for (let i = 0; i < dropCount; ++i) {
|
||||
let flavor = this.getFirstValidFlavor(dt.mozTypesAt(i));
|
||||
if (!flavor)
|
||||
return;
|
||||
|
||||
let data = dt.mozGetDataAt(flavor, i);
|
||||
let unwrapped;
|
||||
if (duplicable.has(flavor)) {
|
||||
let handled = duplicable.get(flavor);
|
||||
if (handled.has(data))
|
||||
continue;
|
||||
handled.add(data);
|
||||
}
|
||||
|
||||
let nodes;
|
||||
if (flavor != TAB_DROP_TYPE) {
|
||||
// There's only ever one in the D&D case.
|
||||
unwrapped = PlacesUtils.unwrapNodes(data, flavor)[0];
|
||||
nodes = PlacesUtils.unwrapNodes(data, flavor);
|
||||
} else if (data instanceof XULElement && data.localName == "tab" &&
|
||||
data.ownerGlobal instanceof ChromeWindow) {
|
||||
let uri = data.linkedBrowser.currentURI;
|
||||
let spec = uri ? uri.spec : "about:blank";
|
||||
unwrapped = { uri: spec,
|
||||
title: data.label,
|
||||
type: PlacesUtils.TYPE_X_MOZ_URL};
|
||||
nodes = [{ uri: spec,
|
||||
title: data.label,
|
||||
type: PlacesUtils.TYPE_X_MOZ_URL}];
|
||||
} else
|
||||
throw new Error("bogus data was passed as a tab");
|
||||
|
||||
let index = insertionPoint.index;
|
||||
for (let unwrapped of nodes) {
|
||||
let index = insertionPoint.index;
|
||||
|
||||
// Adjust insertion index to prevent reversal of dragged items. When you
|
||||
// drag multiple elts upward: need to increment index or each successive
|
||||
// elt will be inserted at the same index, each above the previous.
|
||||
let dragginUp = insertionPoint.itemId == unwrapped.parent &&
|
||||
index < PlacesUtils.bookmarks.getItemIndex(unwrapped.id);
|
||||
if (index != -1 && dragginUp)
|
||||
index += movedCount++;
|
||||
// Adjust insertion index to prevent reversal of dragged items. When you
|
||||
// drag multiple elts upward: need to increment index or each successive
|
||||
// elt will be inserted at the same index, each above the previous.
|
||||
let dragginUp = insertionPoint.itemId == unwrapped.parent &&
|
||||
index < PlacesUtils.bookmarks.getItemIndex(unwrapped.id);
|
||||
if (index != -1 && dragginUp)
|
||||
index += movedCount++;
|
||||
|
||||
// If dragging over a tag container we should tag the item.
|
||||
if (insertionPoint.isTag) {
|
||||
let uri = NetUtil.newURI(unwrapped.uri);
|
||||
let tagItemId = insertionPoint.itemId;
|
||||
if (PlacesUIUtils.useAsyncTransactions)
|
||||
transactions.push(PlacesTransactions.Tag({ uri, tag: tagName }));
|
||||
else
|
||||
transactions.push(new PlacesTagURITransaction(uri, [tagItemId]));
|
||||
} else {
|
||||
// If this is not a copy, check for safety that we can move the source,
|
||||
// otherwise report an error and fallback to a copy.
|
||||
if (!doCopy && !PlacesControllerDragHelper.canMoveUnwrappedNode(unwrapped)) {
|
||||
Components.utils.reportError("Tried to move an unmovable Places " +
|
||||
"node, reverting to a copy operation.");
|
||||
doCopy = true;
|
||||
}
|
||||
if (PlacesUIUtils.useAsyncTransactions) {
|
||||
transactions.push(
|
||||
PlacesUIUtils.getTransactionForData(unwrapped,
|
||||
flavor,
|
||||
parentGuid,
|
||||
index,
|
||||
doCopy));
|
||||
// If dragging over a tag container we should tag the item.
|
||||
if (insertionPoint.isTag) {
|
||||
let uri = NetUtil.newURI(unwrapped.uri);
|
||||
let tagItemId = insertionPoint.itemId;
|
||||
if (PlacesUIUtils.useAsyncTransactions)
|
||||
transactions.push(PlacesTransactions.Tag({ uri, tag: tagName }));
|
||||
else
|
||||
transactions.push(new PlacesTagURITransaction(uri, [tagItemId]));
|
||||
} else {
|
||||
transactions.push(PlacesUIUtils.makeTransaction(unwrapped,
|
||||
flavor, insertionPoint.itemId,
|
||||
index, doCopy));
|
||||
// If this is not a copy, check for safety that we can move the
|
||||
// source, otherwise report an error and fallback to a copy.
|
||||
if (!doCopy && !PlacesControllerDragHelper.canMoveUnwrappedNode(unwrapped)) {
|
||||
Components.utils.reportError("Tried to move an unmovable Places " +
|
||||
"node, reverting to a copy operation.");
|
||||
doCopy = true;
|
||||
}
|
||||
if (PlacesUIUtils.useAsyncTransactions) {
|
||||
transactions.push(
|
||||
PlacesUIUtils.getTransactionForData(unwrapped,
|
||||
flavor,
|
||||
parentGuid,
|
||||
index,
|
||||
doCopy));
|
||||
} else {
|
||||
transactions.push(PlacesUIUtils.makeTransaction(unwrapped,
|
||||
flavor, insertionPoint.itemId,
|
||||
index, doCopy));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,7 +52,46 @@ add_task(function* test() {
|
|||
|
||||
// Verify that we removed the bookmark successfully.
|
||||
ok(!PlacesUtils.bookmarks.isBookmarked(uri), "URI should be removed");
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Simulates a drop of multiple URIs onto the bookmarks bar.
|
||||
*
|
||||
* @param aEffect
|
||||
* The effect to use for the drop operation: move, copy, or link.
|
||||
* @param aMimeType
|
||||
* The mime type to use for the drop operation.
|
||||
*/
|
||||
let simulateDragDropMultiple = function(aEffect, aMimeType) {
|
||||
const uriSpecs = [
|
||||
"http://www.mozilla.org/C54263C6-A484-46CF-8E2B-FE131586348A",
|
||||
"http://www.mozilla.org/71381257-61E6-4376-AF7C-BF3C5FD8870D",
|
||||
"http://www.mozilla.org/091A88BD-5743-4C16-A005-3D2EA3A3B71E"
|
||||
];
|
||||
let uris = uriSpecs.map(spec => makeURI(spec));
|
||||
let data;
|
||||
if (aMimeType == "text/x-moz-url")
|
||||
data = uriSpecs.map(spec => spec + "\n" + spec).join("\n");
|
||||
else
|
||||
data = uriSpecs.join("\n");
|
||||
EventUtils.synthesizeDrop(placesItems.childNodes[0],
|
||||
placesItems,
|
||||
[[{type: aMimeType,
|
||||
data}]],
|
||||
aEffect, window);
|
||||
|
||||
// Verify that the drop produces exactly one bookmark per each URL.
|
||||
for (let uri of uris) {
|
||||
let bookmarkIds = PlacesUtils.bookmarks
|
||||
.getBookmarkIdsForURI(uri);
|
||||
ok(bookmarkIds.length == 1, "There should be exactly one bookmark");
|
||||
|
||||
PlacesUtils.bookmarks.removeItem(bookmarkIds[0]);
|
||||
|
||||
// Verify that we removed the bookmark successfully.
|
||||
ok(!PlacesUtils.bookmarks.isBookmarked(uri), "URI should be removed");
|
||||
}
|
||||
};
|
||||
|
||||
// Simulate a bookmark drop for all of the mime types and effects.
|
||||
let mimeTypes = ["text/plain", "text/unicode", "text/x-moz-url"];
|
||||
|
@ -60,6 +99,7 @@ add_task(function* test() {
|
|||
effects.forEach(function(effect) {
|
||||
mimeTypes.forEach(function(mimeType) {
|
||||
simulateDragDrop(effect, mimeType);
|
||||
simulateDragDropMultiple(effect, mimeType);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Загрузка…
Ссылка в новой задаче