Commit 98f40af6 authored by jiaxi's avatar jiaxi Committed by Commit bot

[MD Bookmarks] Add Delete and Copy URL for Material Bookmarks.

This CL adds delete bookmarks and folders function and copy URL function.

BUG=651980
CQ_INCLUDE_TRYBOTS=master.tryserver.chromium.linux:closure_compilation

Review-Url: https://codereview.chromium.org/2613683002
Cr-Commit-Position: refs/heads/master@{#441864}
parent fc294079
...@@ -9,14 +9,14 @@ Polymer({ ...@@ -9,14 +9,14 @@ Polymer({
/** @type {BookmarkTreeNode} */ /** @type {BookmarkTreeNode} */
item: { item: {
type: Object, type: Object,
observer: 'onItemChanged_' observer: 'onItemChanged_',
}, },
isFolder_: Boolean, isFolder_: Boolean,
}, },
observers: [ observers: [
'updateFavicon_(item.url)' 'updateFavicon_(item.url)',
], ],
/** /**
...@@ -24,8 +24,9 @@ Polymer({ ...@@ -24,8 +24,9 @@ Polymer({
* @private * @private
*/ */
onMenuButtonOpenTap_: function(e) { onMenuButtonOpenTap_: function(e) {
this.fire('toggle-menu', { this.fire('open-item-menu', {
target: e.target target: e.target,
item: this.item
}); });
}, },
...@@ -37,5 +38,5 @@ Polymer({ ...@@ -37,5 +38,5 @@ Polymer({
/** @private */ /** @private */
updateFavicon_: function(url) { updateFavicon_: function(url) {
this.$.icon.style.backgroundImage = cr.icon.getFavicon(url); this.$.icon.style.backgroundImage = cr.icon.getFavicon(url);
} },
}); });
...@@ -8,17 +8,21 @@ Polymer({ ...@@ -8,17 +8,21 @@ Polymer({
properties: { properties: {
/** @type {BookmarkTreeNode} */ /** @type {BookmarkTreeNode} */
selectedNode: Object, selectedNode: Object,
/** @type {BookmarkTreeNode} */
menuItem_: Object,
}, },
listeners: { listeners: {
'toggle-menu': 'onToggleMenu_' 'open-item-menu': 'onOpenItemMenu_',
}, },
/** /**
* @param {Event} e * @param {Event} e
* @private * @private
*/ */
onToggleMenu_: function(e) { onOpenItemMenu_: function(e) {
this.menuItem_ = e.detail.item;
var menu = /** @type {!CrActionMenuElement} */ ( var menu = /** @type {!CrActionMenuElement} */ (
this.$.dropdown); this.$.dropdown);
menu.showAt(/** @type {!Element} */ (e.detail.target)); menu.showAt(/** @type {!Element} */ (e.detail.target));
...@@ -32,11 +36,24 @@ Polymer({ ...@@ -32,11 +36,24 @@ Polymer({
/** @private */ /** @private */
onCopyURLTap_: function() { onCopyURLTap_: function() {
var idList = [this.menuItem_.id];
chrome.bookmarkManagerPrivate.copy(idList, function() {
// TODO(jiaxi): Add toast later.
});
this.closeDropdownMenu_(); this.closeDropdownMenu_();
}, },
/** @private */ /** @private */
onDeleteTap_: function() { onDeleteTap_: function() {
if (this.menuItem_.children) {
chrome.bookmarks.removeTree(this.menuItem_.id, function() {
// TODO(jiaxi): Add toast later.
}.bind(this));
} else {
chrome.bookmarks.remove(this.menuItem_.id, function() {
// TODO(jiaxi): Add toast later.
}.bind(this));
}
this.closeDropdownMenu_(); this.closeDropdownMenu_();
}, },
......
...@@ -55,6 +55,7 @@ Polymer({ ...@@ -55,6 +55,7 @@ Polymer({
chrome.bookmarks.getTree(function(results) { chrome.bookmarks.getTree(function(results) {
this.setupStore_(results[0]); this.setupStore_(results[0]);
}.bind(this)); }.bind(this));
chrome.bookmarks.onRemoved.addListener(this.onBookmarkRemoved_.bind(this));
}, },
/** /**
...@@ -65,6 +66,7 @@ Polymer({ ...@@ -65,6 +66,7 @@ Polymer({
this.rootNode = rootNode; this.rootNode = rootNode;
this.idToNodeMap_ = {}; this.idToNodeMap_ = {};
this.rootNode.path = 'rootNode'; this.rootNode.path = 'rootNode';
this.generatePaths_(rootNode, 0);
this.initNodes_(this.rootNode); this.initNodes_(this.rootNode);
this.fire('selected-folder-changed', this.rootNode.children[0].id); this.fire('selected-folder-changed', this.rootNode.children[0].id);
}, },
...@@ -114,11 +116,29 @@ Polymer({ ...@@ -114,11 +116,29 @@ Polymer({
this._setSelectedNode(selectedNode); this._setSelectedNode(selectedNode);
}, },
/**
* Callback for when a bookmark node is removed.
* If a folder is selected or is an ancestor of a selected folder, the parent
* of the removed folder will be selected.
* @param {string} id The id of the removed bookmark node.
* @param {!{index: number,
* parentId: string,
* node: BookmarkTreeNode}} removeInfo
*/
onBookmarkRemoved_: function(id, removeInfo) {
if (this.isAncestorOfSelected_(this.idToNodeMap_[id]))
this.fire('selected-folder-changed', removeInfo.parentId);
var parentNode = this.idToNodeMap_[removeInfo.parentId];
this.splice(parentNode.path + '.children', removeInfo.index, 1);
this.removeDescendantsFromMap_(id);
this.generatePaths_(parentNode, removeInfo.index);
},
/** /**
* Initializes the nodes in the bookmarks tree as follows: * Initializes the nodes in the bookmarks tree as follows:
* - Populates |idToNodeMap_| with a mapping of all node ids to their * - Populates |idToNodeMap_| with a mapping of all node ids to their
* corresponding BookmarkTreeNode. * corresponding BookmarkTreeNode.
* - Stores the path from the store to a node inside the node.
* - Sets all the nodes to not selected and open by default. * - Sets all the nodes to not selected and open by default.
* @param {BookmarkTreeNode} bookmarkNode * @param {BookmarkTreeNode} bookmarkNode
* @private * @private
...@@ -131,8 +151,40 @@ Polymer({ ...@@ -131,8 +151,40 @@ Polymer({
bookmarkNode.isSelected = false; bookmarkNode.isSelected = false;
bookmarkNode.isOpen = true; bookmarkNode.isOpen = true;
for (var i = 0; i < bookmarkNode.children.length; i++) { for (var i = 0; i < bookmarkNode.children.length; i++) {
bookmarkNode.children[i].path = bookmarkNode.path + '.children.' + i;
this.initNodes_(bookmarkNode.children[i]); this.initNodes_(bookmarkNode.children[i]);
} }
}, },
/**
* Stores the path from the store to a node inside the node.
* @param {BookmarkTreeNode} bookmarkNode
* @param {number} startIndex
* @private
*/
generatePaths_: function(bookmarkNode, startIndex) {
if (!bookmarkNode.children)
return;
for (var i = startIndex; i < bookmarkNode.children.length; i++) {
bookmarkNode.children[i].path = bookmarkNode.path + '.children.#' + i;
this.generatePaths_(bookmarkNode.children[i], 0);
}
},
/**
* Remove all descendants of a given node from the map.
* @param {string} id
* @private
*/
removeDescendantsFromMap_: function(id) {
var node = this.idToNodeMap_[id];
if (!node)
return;
if (node.children) {
for (var i = 0; i < node.children.length; i++)
this.removeDescendantsFromMap_(node.children[i].id);
}
delete this.idToNodeMap_[id];
}
}); });
...@@ -4,7 +4,10 @@ ...@@ -4,7 +4,10 @@
suite('<bookmarks-store>', function() { suite('<bookmarks-store>', function() {
var store; var store;
var TEST_TREE = { var TEST_TREE;
setup(function() {
TEST_TREE = {
id: '0', id: '0',
children: [ children: [
{ {
...@@ -19,9 +22,7 @@ suite('<bookmarks-store>', function() { ...@@ -19,9 +22,7 @@ suite('<bookmarks-store>', function() {
] ]
}; };
setup(function() {
store = document.createElement('bookmarks-store'); store = document.createElement('bookmarks-store');
store.isTesting_ = true;
replaceBody(store); replaceBody(store);
store.setupStore_(TEST_TREE); store.setupStore_(TEST_TREE);
}); });
...@@ -53,11 +54,11 @@ suite('<bookmarks-store>', function() { ...@@ -53,11 +54,11 @@ suite('<bookmarks-store>', function() {
test('correct paths generated for nodes', function() { test('correct paths generated for nodes', function() {
var TEST_PATHS = { var TEST_PATHS = {
'0': 'rootNode', '0': 'rootNode',
'1': 'rootNode.children.0', '1': 'rootNode.children.#0',
'2': 'rootNode.children.0.children.0', '2': 'rootNode.children.#0.children.#0',
'3': 'rootNode.children.0.children.1', '3': 'rootNode.children.#0.children.#1',
'4': 'rootNode.children.1', '4': 'rootNode.children.#1',
'5': 'rootNode.children.2', '5': 'rootNode.children.#2',
}; };
for (var id in store.idToNodeMap_) for (var id in store.idToNodeMap_)
...@@ -110,4 +111,64 @@ suite('<bookmarks-store>', function() { ...@@ -110,4 +111,64 @@ suite('<bookmarks-store>', function() {
assertTrue(store.idToNodeMap_['1'].isSelected); assertTrue(store.idToNodeMap_['1'].isSelected);
assertFalse(store.idToNodeMap_['3'].isSelected); assertFalse(store.idToNodeMap_['3'].isSelected);
}); });
test('deleting a node updates the tree', function() {
// Remove an empty folder/bookmark.
store.onBookmarkRemoved_('4', {parentId: '0', index: '1'});
// Check the tree is correct.
assertEquals('5', store.rootNode.children[1].id);
// idToNodeMap_ has been updated.
assertEquals(undefined, store.idToNodeMap_['4']);
assertEquals(store.rootNode.children[1], store.idToNodeMap_['5']);
// Paths have been updated.
var TEST_PATHS = {
'0': 'rootNode',
'1': 'rootNode.children.#0',
'2': 'rootNode.children.#0.children.#0',
'3': 'rootNode.children.#0.children.#1',
'5': 'rootNode.children.#1',
};
for (var id in store.idToNodeMap_)
assertEquals(TEST_PATHS[id], store.idToNodeMap_[id].path);
// Remove a folder with children.
store.onBookmarkRemoved_('1', {parentId: '0', index: '0'});
// Check the tree is correct.
assertEquals('5', store.rootNode.children[0].id);
// idToNodeMap_ has been updated.
assertEquals(undefined, store.idToNodeMap_['1']);
assertEquals(undefined, store.idToNodeMap_['2']);
assertEquals(undefined, store.idToNodeMap_['3']);
assertEquals(undefined, store.idToNodeMap_['4']);
assertEquals(store.rootNode.children[0], store.idToNodeMap_['5']);
// Paths have been updated.
TEST_PATHS = {
'0': 'rootNode',
'5': 'rootNode.children.#0',
};
for (var id in store.idToNodeMap_)
assertEquals(TEST_PATHS[id], store.idToNodeMap_[id].path);
});
test('selectedId updates after removing a selected folder', function() {
// Selected folder gets removed.
store.selectedId = '2';
store.onBookmarkRemoved_('2', {parentId:'1', index:'0'});
assertTrue(store.idToNodeMap_['1'].isSelected);
assertEquals('1', store.selectedId);
// A folder with selected folder in it gets removed.
store.selectedId = '3';
store.onBookmarkRemoved_('1', {parentId:'0', index:'0'});
assertTrue(store.idToNodeMap_['0'].isSelected);
assertEquals('0', store.selectedId);
});
}); });
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment