summaryrefslogtreecommitdiffstats
path: root/chromium/chrome/browser/resources/enhanced_bookmark_manager
diff options
context:
space:
mode:
authorJocelyn Turcotte <jocelyn.turcotte@digia.com>2014-08-08 14:30:41 +0200
committerJocelyn Turcotte <jocelyn.turcotte@digia.com>2014-08-12 13:49:54 +0200
commitab0a50979b9eb4dfa3320eff7e187e41efedf7a9 (patch)
tree498dfb8a97ff3361a9f7486863a52bb4e26bb898 /chromium/chrome/browser/resources/enhanced_bookmark_manager
parent4ce69f7403811819800e7c5ae1318b2647e778d1 (diff)
Update Chromium to beta version 37.0.2062.68
Change-Id: I188e3b5aff1bec75566014291b654eb19f5bc8ca Reviewed-by: Andras Becsi <andras.becsi@digia.com>
Diffstat (limited to 'chromium/chrome/browser/resources/enhanced_bookmark_manager')
-rw-r--r--chromium/chrome/browser/resources/enhanced_bookmark_manager/css/bmm.css381
-rw-r--r--chromium/chrome/browser/resources/enhanced_bookmark_manager/css/bmm.css.js17
-rw-r--r--chromium/chrome/browser/resources/enhanced_bookmark_manager/images/2x/bookmark_manager_recent.pngbin1641 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/enhanced_bookmark_manager/images/2x/bookmark_manager_search.pngbin1904 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/enhanced_bookmark_manager/images/2x/bookmark_manager_search_rtl.pngbin1888 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/enhanced_bookmark_manager/images/2x/bookmarks_section_32.pngbin4772 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/enhanced_bookmark_manager/images/bookmark_manager_recent.pngbin694 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/enhanced_bookmark_manager/images/bookmark_manager_search.pngbin737 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/enhanced_bookmark_manager/images/bookmark_manager_search_rtl.pngbin737 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/enhanced_bookmark_manager/images/bookmarks_section_32.pngbin1948 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/enhanced_bookmark_manager/js/bmm.js248
-rw-r--r--chromium/chrome/browser/resources/enhanced_bookmark_manager/js/bmm/bookmark_list.js566
-rw-r--r--chromium/chrome/browser/resources/enhanced_bookmark_manager/js/bmm/bookmark_tree.js307
-rw-r--r--chromium/chrome/browser/resources/enhanced_bookmark_manager/js/bmm_test.html117
-rw-r--r--chromium/chrome/browser/resources/enhanced_bookmark_manager/js/dnd.js502
-rw-r--r--chromium/chrome/browser/resources/enhanced_bookmark_manager/js/main.js1308
-rw-r--r--chromium/chrome/browser/resources/enhanced_bookmark_manager/main.html158
-rw-r--r--chromium/chrome/browser/resources/enhanced_bookmark_manager/manifest.json25
18 files changed, 0 insertions, 3629 deletions
diff --git a/chromium/chrome/browser/resources/enhanced_bookmark_manager/css/bmm.css b/chromium/chrome/browser/resources/enhanced_bookmark_manager/css/bmm.css
deleted file mode 100644
index 8c61a3e7a51..00000000000
--- a/chromium/chrome/browser/resources/enhanced_bookmark_manager/css/bmm.css
+++ /dev/null
@@ -1,381 +0,0 @@
-/* Copyright 2013 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file. */
-
-html,
-body {
- cursor: default;
- height: 100%;
- margin: 0;
- overflow: hidden;
- width: 100%;
-}
-
-body {
- -webkit-flex-direction: column;
- display: -webkit-flex;
-}
-
-list {
- display: block;
- overflow-x: hidden;
- overflow-y: visible; /* let the container do the scrolling */
-}
-
-list > * {
- -webkit-padding-end: 20px;
- -webkit-padding-start: 3px;
- color: hsl(0, 0%, 70%);
- display: -webkit-flex;
- line-height: 20px;
- margin: 0;
- overflow: visible;
- padding-bottom: 0;
- padding-top: 0;
- text-decoration: none;
- white-space: nowrap;
-}
-
-list > * > * {
- -webkit-padding-start: 20px;
- background: 0 50% no-repeat;
- box-sizing: border-box;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: pre; /* Don't collapse whitespace */
-}
-
-list > * > .label {
- -webkit-transition: all 150ms;
- color: black;
- display: inline-block; /* We need to use inline-block here due to RTL. */
-}
-
-list > * > .url {
- -webkit-flex: 1;
- direction: ltr; /* URLs always read LTR */
- display: none;
- /* TODO(arv): Remove min-width once bug is fixed:
- * https://bugs.webkit.org/show_bug.cgi?id=111790 */
- min-width: 0;
-}
-
-list > :hover > .url,
-list > [selected] > .url {
- display: block;
-}
-
-/* Handle proper padding for URL field in an RTL context, where field order is
- * |div.url||div.label| - so we need padding at the right of URL, not at the
- * left. And since url is always LTR, that is padding at the end, not the start.
- */
-html[dir=rtl] .url {
- -webkit-padding-end: 20px;
- -webkit-padding-start: 0;
-}
-
-html[dir=rtl] list .label {
- background-position: 100% 50%;
-}
-
-list > .folder > .label {
- background-image: -webkit-image-set(
- url('../../../../../ui/resources/default_100_percent/common/folder_closed.png') 1x,
- url('../../../../../ui/resources/default_200_percent/common/folder_closed.png') 2x);
-}
-
-/* We need to ensure that even empty labels take up space */
-list > * > .label:empty::after,
-list > * > .url:empty::after {
- content: ' ';
- white-space: pre;
-}
-
-list > .folder > .url:empty::after {
- content: '';
-}
-
-list > * > button {
- -webkit-transition: opacity 150ms;
- background: #fff -webkit-canvas(drop-down-arrow) no-repeat center center;
- border: 1px solid hsl(214, 91%, 85%);
- border-radius: 3px;
- bottom: 1px;
- display: none;
- overflow: hidden;
- padding: 0;
- position: absolute;
- right: 3px;
- top: 1px;
- width: 15px;
-}
-
-list > [selected]:hover > button,
-list > * > button[menu-shown] {
- border-color: hsl(214, 91%, 65%);
-}
-
-list > :hover > button {
- display: block;
-}
-
-list > * > button:hover,
-list > * > button[menu-shown] {
- display: block;
-}
-
-html[dir=rtl] list > * > button {
- left: 3px;
- right: auto;
-}
-
-/* Edit mode */
-
-list [editing] .label input,
-list [editing] .url input {
- -webkit-margin-end: 4px;
- -webkit-margin-start: -4px;
- -webkit-padding-end: 3px;
- -webkit-padding-start: 3px;
- box-sizing: content-box;
- font-family: inherit;
- font-size: inherit;
- font-weight: inherit;
- /* Do not inherit the line-height. */
- line-height: normal;
- margin-bottom: 0;
- margin-top: 0;
- min-height: 0;
- text-decoration: none;
- vertical-align: baseline;
-}
-
-.tree-item [editing] input {
- line-height: normal;
- margin: 0;
- min-height: 0;
- padding: 1px 0;
-}
-
-<if expr="is_macosx">
-list .label input,
-list .url input {
- outline: none;
-}
-</if>
-
-list > [editing] {
- overflow: visible;
-}
-
-list [editing] .label,
-list [editing] .url,
-list [editing] > * {
- overflow: visible;
-}
-
-list [editing] .url {
- -webkit-padding-start: 5px;
-}
-
-list [editing] input {
- padding: 1px 0;
-}
-
-/* end editing */
-
-html[dir=rtl] list > .folder > .label {
- background-image: -webkit-image-set(
- url('../../../../../ui/resources/default_100_percent/common/folder_closed_rtl.png') 1x,
- url('../../../../../ui/resources/default_200_percent/common/folder_closed_rtl.png') 2x);
-}
-
-<if expr="is_macosx">
-list > .folder > .label,
-.tree-label,
-.tree-row[may-have-children] > .tree-label,
-.tree-item[expanded] > .tree-row > .tree-label {
- background-image: -webkit-image-set(
- url('../../../../app/theme/default_100_percent/mac/bookmark_bar_folder.png') 1x,
- url('../../../../app/theme/default_200_percent/mac/bookmark_bar_folder.png') 2x);
-}
-</if>
-
-.main {
- -webkit-flex: 1;
- display: -webkit-flex;
- /* TODO(arv): Remove min-height once bug is fixed:
- * https://bugs.webkit.org/show_bug.cgi?id=111790 */
- min-height: 0;
-}
-
-#tree-container {
- -webkit-padding-end: 5px;
- -webkit-padding-start: 10px;
- box-sizing: border-box;
- /* min-width and max-width are used by the split pane. */
- max-width: 50%;
- min-width: 50px;
- overflow: auto;
- padding-bottom: 5px;
- padding-top: 5px;
- width: 200px;
-}
-
-#tree {
- display: inline-block;
- min-width: 100%;
- overflow: visible; /* let the container do the scrolling */
-}
-
-.tree-item > .tree-row {
- line-height: 20px;
-}
-
-.tree-row .expand-icon {
- top: 2px;
-}
-
-#list {
- -webkit-flex: 1;
- -webkit-padding-end: 5px;
- box-sizing: border-box;
- /* TODO(arv): Remove min-width once bug is fixed:
- * https://bugs.webkit.org/show_bug.cgi?id=111790 */
- min-width: 0;
- padding-bottom: 5px;
- padding-top: 5px;
-}
-
-.splitter {
- -webkit-border-end: 15px solid white;
- -webkit-border-start: 0;
- background-color: rgb(235, 239, 249);
- cursor: e-resize;
- width: 5px;
-<if expr="is_macosx">
- cursor: col-resize;
-</if>
-}
-
-.logo {
- -webkit-appearance: none;
- background: url('../images/bookmarks_section_32.png') no-repeat 50% 50%;
- border: 0;
- cursor: pointer;
- float: left;
- height: 32px;
- margin: 10px;
- width: 32px;
-}
-
-html:not(.focus-outline-visible) .logo:focus {
- outline: none;
-}
-
-.header form {
- float: left;
- margin: 14px 2px 0 2px;
- width: 171px;
-}
-
-.header {
- min-width: 400px;
-}
-
-html[dir=rtl] .logo,
-html[dir=rtl] .header > div,
-html[dir=rtl] .header form {
- float: right;
-}
-
-.tree-row.drag-on,
-.drag-on {
- background-color: hsla(214, 91%, 85%, .5);
- border: 1px solid hsl(214, 91%, 85%);
- border-radius: 3px;
- box-sizing: border-box;
-}
-
-.drag-above::before,
-.drag-below::after {
- background-clip: padding-box;
- background-color: black;
- border: 3px solid black;
- border-bottom-color: transparent;
- border-radius: 0;
- border-top-color: transparent;
- box-sizing: border-box;
- content: '';
- display: block;
- height: 8px;
- left: 0;
- position: absolute;
- right: 0;
- z-index: 10;
-}
-
-.drag-above::before {
- top: calc((8px/2 + 1px) * -1)
-}
-
-.drag-below::after {
- bottom: calc((8px/2 + 1px) * -1)
-}
-
-list.drag-above::before {
- top: 0
-}
-
-list > .drag-below,
-list > .drag-above {
- overflow : visible;
-}
-
-.summary {
- background-color: rgb(235, 239, 249);
- border-top: 1px solid rgb(156, 194, 239);
- clear: both;
- padding: 5px 10px;
- white-space: nowrap;
-}
-
-.summary > * {
- display: inline-block;
- font-size: 100%;
- margin: 0;
-}
-
-.summary button {
- -webkit-appearance: none;
- -webkit-margin-start: 10px;
- -webkit-padding-end: 11px;
- -webkit-padding-start: 0;
- background: transparent -webkit-canvas(drop-down-arrow)
- no-repeat right center;
- border: 0;
- font: inherit;
- padding-bottom: 0;
- padding-top: 0;
-}
-
-html[dir=rtl] .summary button {
- background-position: left center;
-}
-
-@media (pointer:coarse) {
- list > *,
- menu > button,
- .tree-item > .tree-row {
- line-height: 28px;
- }
-
- list [editing] input,
- .tree-item [editing] input {
- padding: 3px 0;
- }
-
- .tree-row .expand-icon {
- top: 6px;
- }
-}
diff --git a/chromium/chrome/browser/resources/enhanced_bookmark_manager/css/bmm.css.js b/chromium/chrome/browser/resources/enhanced_bookmark_manager/css/bmm.css.js
deleted file mode 100644
index 83787e622e1..00000000000
--- a/chromium/chrome/browser/resources/enhanced_bookmark_manager/css/bmm.css.js
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Create the drop down arrow for the drop down buttons.
-(function() {
- var ctx = document.getCSSCanvasContext('2d', 'drop-down-arrow', 9, 4);
- ctx.fillStyle = '#000';
- ctx.translate(1.5, .5);
- ctx.beginPath();
- ctx.moveTo(0, 0);
- ctx.lineTo(6, 0);
- ctx.lineTo(3, 3);
- ctx.closePath();
- ctx.fill();
- ctx.stroke();
-})();
diff --git a/chromium/chrome/browser/resources/enhanced_bookmark_manager/images/2x/bookmark_manager_recent.png b/chromium/chrome/browser/resources/enhanced_bookmark_manager/images/2x/bookmark_manager_recent.png
deleted file mode 100644
index d39e505240b..00000000000
--- a/chromium/chrome/browser/resources/enhanced_bookmark_manager/images/2x/bookmark_manager_recent.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/enhanced_bookmark_manager/images/2x/bookmark_manager_search.png b/chromium/chrome/browser/resources/enhanced_bookmark_manager/images/2x/bookmark_manager_search.png
deleted file mode 100644
index 438c6782b6b..00000000000
--- a/chromium/chrome/browser/resources/enhanced_bookmark_manager/images/2x/bookmark_manager_search.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/enhanced_bookmark_manager/images/2x/bookmark_manager_search_rtl.png b/chromium/chrome/browser/resources/enhanced_bookmark_manager/images/2x/bookmark_manager_search_rtl.png
deleted file mode 100644
index 439055ba71c..00000000000
--- a/chromium/chrome/browser/resources/enhanced_bookmark_manager/images/2x/bookmark_manager_search_rtl.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/enhanced_bookmark_manager/images/2x/bookmarks_section_32.png b/chromium/chrome/browser/resources/enhanced_bookmark_manager/images/2x/bookmarks_section_32.png
deleted file mode 100644
index 76fc975cb9b..00000000000
--- a/chromium/chrome/browser/resources/enhanced_bookmark_manager/images/2x/bookmarks_section_32.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/enhanced_bookmark_manager/images/bookmark_manager_recent.png b/chromium/chrome/browser/resources/enhanced_bookmark_manager/images/bookmark_manager_recent.png
deleted file mode 100644
index 245042a365a..00000000000
--- a/chromium/chrome/browser/resources/enhanced_bookmark_manager/images/bookmark_manager_recent.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/enhanced_bookmark_manager/images/bookmark_manager_search.png b/chromium/chrome/browser/resources/enhanced_bookmark_manager/images/bookmark_manager_search.png
deleted file mode 100644
index 46b88a769e1..00000000000
--- a/chromium/chrome/browser/resources/enhanced_bookmark_manager/images/bookmark_manager_search.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/enhanced_bookmark_manager/images/bookmark_manager_search_rtl.png b/chromium/chrome/browser/resources/enhanced_bookmark_manager/images/bookmark_manager_search_rtl.png
deleted file mode 100644
index 2ad79680ab5..00000000000
--- a/chromium/chrome/browser/resources/enhanced_bookmark_manager/images/bookmark_manager_search_rtl.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/enhanced_bookmark_manager/images/bookmarks_section_32.png b/chromium/chrome/browser/resources/enhanced_bookmark_manager/images/bookmarks_section_32.png
deleted file mode 100644
index 555d3400db6..00000000000
--- a/chromium/chrome/browser/resources/enhanced_bookmark_manager/images/bookmarks_section_32.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/enhanced_bookmark_manager/js/bmm.js b/chromium/chrome/browser/resources/enhanced_bookmark_manager/js/bmm.js
deleted file mode 100644
index b238f4deabe..00000000000
--- a/chromium/chrome/browser/resources/enhanced_bookmark_manager/js/bmm.js
+++ /dev/null
@@ -1,248 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-cr.define('bmm', function() {
- var Promise = cr.Promise;
-
- /**
- * Whether a node contains another node.
- * TODO(yosin): Once JavaScript style guide is updated and linter follows
- * that, we'll remove useless documentations for |parent| and |descendant|.
- * TODO(yosin): bmm.contains() should be method of BookmarkTreeNode.
- * @param {!BookmarkTreeNode} parent .
- * @param {!BookmarkTreeNode} descendant .
- * @return {boolean} Whether the parent contains the descendant.
- */
- function contains(parent, descendant) {
- if (descendant.parentId == parent.id)
- return true;
- // the bmm.treeLookup contains all folders
- var parentTreeItem = bmm.treeLookup[descendant.parentId];
- if (!parentTreeItem || !parentTreeItem.bookmarkNode)
- return false;
- return this.contains(parent, parentTreeItem.bookmarkNode);
- }
-
- /**
- * @param {!BookmarkTreeNode} node The node to test.
- * @return {boolean} Whether a bookmark node is a folder.
- */
- function isFolder(node) {
- return !('url' in node);
- }
-
- var loadingPromises = {};
-
- /**
- * Loads a subtree of the bookmark tree and returns a {@code cr.Promise} that
- * will be fulfilled when done. This reuses multiple loads so that we do not
- * load the same subtree more than once at the same time.
- * @return {!cr.Promise} The future promise for the load.
- */
- function loadSubtree(id) {
- var p = new Promise;
- if (!(id in loadingPromises)) {
- loadingPromises[id] = new Promise;
- loadingPromises[id].addListener(function(n) {
- p.value = n;
- });
- chrome.bookmarkManagerPrivate.getSubtree(id, false, function(nodes) {
- loadingPromises[id].value = nodes && nodes[0];
- delete loadingPromises[id];
- });
- } else {
- loadingPromises[id].addListener(function(n) {
- p.value = n;
- });
- }
- return p;
- }
-
- /**
- * Loads the entire bookmark tree and returns a {@code cr.Promise} that will
- * be fulfilled when done. This reuses multiple loads so that we do not load
- * the same tree more than once at the same time.
- * @return {!cr.Promise} The future promise for the load.
- */
- function loadTree() {
- return loadSubtree('');
- }
-
- var bookmarkCache = {
- /**
- * Removes the cached item from both the list and tree lookups.
- */
- remove: function(id) {
- var treeItem = bmm.treeLookup[id];
- if (treeItem) {
- var items = treeItem.items; // is an HTMLCollection
- for (var i = 0; i < items.length; ++i) {
- var item = items[i];
- var bookmarkNode = item.bookmarkNode;
- delete bmm.treeLookup[bookmarkNode.id];
- }
- delete bmm.treeLookup[id];
- }
- },
-
- /**
- * Updates the underlying bookmark node for the tree items and list items by
- * querying the bookmark backend.
- * @param {string} id The id of the node to update the children for.
- * @param {Function=} opt_f A funciton to call when done.
- */
- updateChildren: function(id, opt_f) {
- function updateItem(bookmarkNode) {
- var treeItem = bmm.treeLookup[bookmarkNode.id];
- if (treeItem) {
- treeItem.bookmarkNode = bookmarkNode;
- }
- }
-
- chrome.bookmarks.getChildren(id, function(children) {
- if (children)
- children.forEach(updateItem);
-
- if (opt_f)
- opt_f(children);
- });
- }
- };
-
- /**
- * Called when the title of a bookmark changes.
- * @param {string} id The id of changed bookmark node.
- * @param {!Object} changeInfo The information about how the node changed.
- */
- function handleBookmarkChanged(id, changeInfo) {
- if (bmm.tree)
- bmm.tree.handleBookmarkChanged(id, changeInfo);
- if (bmm.list)
- bmm.list.handleBookmarkChanged(id, changeInfo);
- }
-
- /**
- * Callback for when the user reorders by title.
- * @param {string} id The id of the bookmark folder that was reordered.
- * @param {!Object} reorderInfo The information about how the items where
- * reordered.
- */
- function handleChildrenReordered(id, reorderInfo) {
- if (bmm.tree)
- bmm.tree.handleChildrenReordered(id, reorderInfo);
- if (bmm.list)
- bmm.list.handleChildrenReordered(id, reorderInfo);
- bookmarkCache.updateChildren(id);
- }
-
- /**
- * Callback for when a bookmark node is created.
- * @param {string} id The id of the newly created bookmark node.
- * @param {!Object} bookmarkNode The new bookmark node.
- */
- function handleCreated(id, bookmarkNode) {
- if (bmm.list)
- bmm.list.handleCreated(id, bookmarkNode);
- if (bmm.tree)
- bmm.tree.handleCreated(id, bookmarkNode);
- bookmarkCache.updateChildren(bookmarkNode.parentId);
- }
-
- /**
- * Callback for when a bookmark node is moved.
- * @param {string} id The id of the moved bookmark node.
- * @param {!Object} moveInfo The information about move.
- */
- function handleMoved(id, moveInfo) {
- if (bmm.list)
- bmm.list.handleMoved(id, moveInfo);
- if (bmm.tree)
- bmm.tree.handleMoved(id, moveInfo);
-
- bookmarkCache.updateChildren(moveInfo.parentId);
- if (moveInfo.parentId != moveInfo.oldParentId)
- bookmarkCache.updateChildren(moveInfo.oldParentId);
- }
-
- /**
- * Callback for when a bookmark node is removed.
- * @param {string} id The id of the removed bookmark node.
- * @param {!Object} bookmarkNode The information about removed.
- */
- function handleRemoved(id, removeInfo) {
- if (bmm.list)
- bmm.list.handleRemoved(id, removeInfo);
- if (bmm.tree)
- bmm.tree.handleRemoved(id, removeInfo);
-
- bookmarkCache.updateChildren(removeInfo.parentId);
- bookmarkCache.remove(id);
- }
-
- /**
- * Callback for when all bookmark nodes have been deleted.
- */
- function handleRemoveAll() {
- // Reload the list and the tree.
- if (bmm.list)
- bmm.list.reload();
- if (bmm.tree)
- bmm.tree.reload();
- }
-
- /**
- * Callback for when importing bookmark is started.
- */
- function handleImportBegan() {
- chrome.bookmarks.onCreated.removeListener(handleCreated);
- chrome.bookmarks.onChanged.removeListener(handleBookmarkChanged);
- }
-
- /**
- * Callback for when importing bookmark node is finished.
- */
- function handleImportEnded() {
- // When importing is done we reload the tree and the list.
-
- function f() {
- bmm.tree.removeEventListener('load', f);
-
- chrome.bookmarks.onCreated.addListener(handleCreated);
- chrome.bookmarks.onChanged.addListener(handleBookmarkChanged);
-
- if (!bmm.list)
- return;
-
- // TODO(estade): this should navigate to the newly imported folder, which
- // may be the bookmark bar if there were no previous bookmarks.
- bmm.list.reload();
- }
-
- if (bmm.tree) {
- bmm.tree.addEventListener('load', f);
- bmm.tree.reload();
- }
- }
-
- /**
- * Adds the listeners for the bookmark model change events.
- */
- function addBookmarkModelListeners() {
- chrome.bookmarks.onChanged.addListener(handleBookmarkChanged);
- chrome.bookmarks.onChildrenReordered.addListener(handleChildrenReordered);
- chrome.bookmarks.onCreated.addListener(handleCreated);
- chrome.bookmarks.onMoved.addListener(handleMoved);
- chrome.bookmarks.onRemoved.addListener(handleRemoved);
- chrome.bookmarks.onImportBegan.addListener(handleImportBegan);
- chrome.bookmarks.onImportEnded.addListener(handleImportEnded);
- };
-
- return {
- contains: contains,
- isFolder: isFolder,
- loadSubtree: loadSubtree,
- loadTree: loadTree,
- addBookmarkModelListeners: addBookmarkModelListeners
- };
-});
diff --git a/chromium/chrome/browser/resources/enhanced_bookmark_manager/js/bmm/bookmark_list.js b/chromium/chrome/browser/resources/enhanced_bookmark_manager/js/bmm/bookmark_list.js
deleted file mode 100644
index 9d491c69ff5..00000000000
--- a/chromium/chrome/browser/resources/enhanced_bookmark_manager/js/bmm/bookmark_list.js
+++ /dev/null
@@ -1,566 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// TODO(arv): Now that this is driven by a data model, implement a data model
-// that handles the loading and the events from the bookmark backend.
-
-cr.define('bmm', function() {
- var List = cr.ui.List;
- var ListItem = cr.ui.ListItem;
- var ArrayDataModel = cr.ui.ArrayDataModel;
- var ContextMenuButton = cr.ui.ContextMenuButton;
-
- var list;
-
- /**
- * Basic array data model for use with bookmarks.
- * @param {!Array.<!BookmarkTreeNode>} items The bookmark items.
- * @constructor
- * @extends {ArrayDataModel}
- */
- function BookmarksArrayDataModel(items) {
- ArrayDataModel.call(this, items);
- }
-
- BookmarksArrayDataModel.prototype = {
- __proto__: ArrayDataModel.prototype,
-
- /**
- * Finds the index of the bookmark with the given ID.
- * @param {string} id The ID of the bookmark node to find.
- * @return {number} The index of the found node or -1 if not found.
- */
- findIndexById: function(id) {
- for (var i = 0; i < this.length; i++) {
- if (this.item(i).id == id)
- return i;
- }
- return -1;
- }
- };
-
- /**
- * Removes all children and appends a new child.
- * @param {!Node} parent The node to remove all children from.
- * @param {!Node} newChild The new child to append.
- */
- function replaceAllChildren(parent, newChild) {
- var n;
- while ((n = parent.lastChild)) {
- parent.removeChild(n);
- }
- parent.appendChild(newChild);
- }
-
- /**
- * Creates a new bookmark list.
- * @param {Object=} opt_propertyBag Optional properties.
- * @constructor
- * @extends {HTMLButtonElement}
- */
- var BookmarkList = cr.ui.define('list');
-
- BookmarkList.prototype = {
- __proto__: List.prototype,
-
- /** @override */
- decorate: function() {
- List.prototype.decorate.call(this);
- this.addEventListener('mousedown', this.handleMouseDown_);
-
- // HACK(arv): http://crbug.com/40902
- window.addEventListener('resize', this.redraw.bind(this));
-
- // We could add the ContextMenuButton in the BookmarkListItem but it slows
- // down redraws a lot so we do this on mouseovers instead.
- this.addEventListener('mouseover', this.handleMouseOver_.bind(this));
-
- bmm.list = this;
- },
-
- createItem: function(bookmarkNode) {
- return new BookmarkListItem(bookmarkNode);
- },
-
- parentId_: '',
-
- /**
- * Reloads the list from the bookmarks backend.
- */
- reload: function() {
- var parentId = this.parentId;
-
- var callback = this.handleBookmarkCallback_.bind(this);
- this.loading_ = true;
-
- if (!parentId)
- callback([]);
- else if (/^q=/.test(parentId))
- chrome.bookmarks.search(parentId.slice(2), callback);
- else
- chrome.bookmarks.getChildren(parentId, callback);
- },
-
- /**
- * Callback function for loading items.
- * @param {Array.<!BookmarkTreeNode>} items The loaded items.
- * @private
- */
- handleBookmarkCallback_: function(items) {
- if (!items) {
- // Failed to load bookmarks. Most likely due to the bookmark being
- // removed.
- cr.dispatchSimpleEvent(this, 'invalidId');
- this.loading_ = false;
- return;
- }
-
- this.dataModel = new BookmarksArrayDataModel(items);
-
- this.loading_ = false;
- this.fixWidth_();
- cr.dispatchSimpleEvent(this, 'load');
- },
-
- /**
- * The bookmark node that the list is currently displaying. If we are
- * currently displaying search this returns null.
- * @type {BookmarkTreeNode}
- */
- get bookmarkNode() {
- if (this.isSearch())
- return null;
- var treeItem = bmm.treeLookup[this.parentId];
- return treeItem && treeItem.bookmarkNode;
- },
-
- /**
- * @return {boolean} Whether we are currently showing search results.
- */
- isSearch: function() {
- return this.parentId_[0] == 'q';
- },
-
- /**
- * Handles mouseover on the list so that we can add the context menu button
- * lazily.
- * @private
- * @param {!Event} e The mouseover event object.
- */
- handleMouseOver_: function(e) {
- var el = e.target;
- while (el && el.parentNode != this) {
- el = el.parentNode;
- }
-
- if (el && el.parentNode == this &&
- !el.editing &&
- !(el.lastChild instanceof ContextMenuButton)) {
- el.appendChild(new ContextMenuButton);
- }
- },
-
- /**
- * Dispatches an urlClicked event which is used to open URLs in new
- * tabs etc.
- * @private
- * @param {string} url The URL that was clicked.
- * @param {!Event} originalEvent The original click event object.
- */
- dispatchUrlClickedEvent_: function(url, originalEvent) {
- var event = new Event('urlClicked', {bubbles: true});
- event.url = url;
- event.originalEvent = originalEvent;
- this.dispatchEvent(event);
- },
-
- /**
- * Handles mousedown events so that we can prevent the auto scroll as
- * necessary.
- * @private
- * @param {!MouseEvent} e The mousedown event object.
- */
- handleMouseDown_: function(e) {
- if (e.button == 1) {
- // WebKit no longer fires click events for middle clicks so we manually
- // listen to mouse up to dispatch a click event.
- this.addEventListener('mouseup', this.handleMiddleMouseUp_);
-
- // When the user does a middle click we need to prevent the auto scroll
- // in case the user is trying to middle click to open a bookmark in a
- // background tab.
- // We do not do this in case the target is an input since middle click
- // is also paste on Linux and we don't want to break that.
- if (e.target.tagName != 'INPUT')
- e.preventDefault();
- }
- },
-
- /**
- * WebKit no longer dispatches click events for middle clicks so we need
- * to emulate it.
- * @private
- * @param {!MouseEvent} e The mouse up event object.
- */
- handleMiddleMouseUp_: function(e) {
- this.removeEventListener('mouseup', this.handleMiddleMouseUp_);
- if (e.button == 1) {
- var el = e.target;
- while (el.parentNode != this) {
- el = el.parentNode;
- }
- var node = el.bookmarkNode;
- if (node && !bmm.isFolder(node))
- this.dispatchUrlClickedEvent_(node.url, e);
- }
- },
-
- // Bookmark model update callbacks
- handleBookmarkChanged: function(id, changeInfo) {
- var dataModel = this.dataModel;
- var index = dataModel.findIndexById(id);
- if (index != -1) {
- var bookmarkNode = this.dataModel.item(index);
- bookmarkNode.title = changeInfo.title;
- if ('url' in changeInfo)
- bookmarkNode.url = changeInfo['url'];
-
- dataModel.updateIndex(index);
- }
- },
-
- handleChildrenReordered: function(id, reorderInfo) {
- if (this.parentId == id) {
- // We create a new data model with updated items in the right order.
- var dataModel = this.dataModel;
- var items = {};
- for (var i = this.dataModel.length - 1; i >= 0; i--) {
- var bookmarkNode = dataModel.item(i);
- items[bookmarkNode.id] = bookmarkNode;
- }
- var newArray = [];
- for (var i = 0; i < reorderInfo.childIds.length; i++) {
- newArray[i] = items[reorderInfo.childIds[i]];
- newArray[i].index = i;
- }
-
- this.dataModel = new BookmarksArrayDataModel(newArray);
- }
- },
-
- handleCreated: function(id, bookmarkNode) {
- if (this.parentId == bookmarkNode.parentId)
- this.dataModel.splice(bookmarkNode.index, 0, bookmarkNode);
- },
-
- handleMoved: function(id, moveInfo) {
- if (moveInfo.parentId == this.parentId ||
- moveInfo.oldParentId == this.parentId) {
-
- var dataModel = this.dataModel;
-
- if (moveInfo.oldParentId == moveInfo.parentId) {
- // Reorder within this folder
-
- this.startBatchUpdates();
-
- var bookmarkNode = this.dataModel.item(moveInfo.oldIndex);
- this.dataModel.splice(moveInfo.oldIndex, 1);
- this.dataModel.splice(moveInfo.index, 0, bookmarkNode);
-
- this.endBatchUpdates();
- } else {
- if (moveInfo.oldParentId == this.parentId) {
- // Move out of this folder
-
- var index = dataModel.findIndexById(id);
- if (index != -1)
- dataModel.splice(index, 1);
- }
-
- if (moveInfo.parentId == this.parentId) {
- // Move to this folder
- var self = this;
- chrome.bookmarks.get(id, function(bookmarkNodes) {
- var bookmarkNode = bookmarkNodes[0];
- dataModel.splice(bookmarkNode.index, 0, bookmarkNode);
- });
- }
- }
- }
- },
-
- handleRemoved: function(id, removeInfo) {
- var dataModel = this.dataModel;
- var index = dataModel.findIndexById(id);
- if (index != -1)
- dataModel.splice(index, 1);
- },
-
- /**
- * Workaround for http://crbug.com/40902
- * @private
- */
- fixWidth_: function() {
- var list = bmm.list;
- if (this.loading_ || !list)
- return;
-
- // The width of the list is wrong after its content has changed.
- // Fortunately the reported offsetWidth is correct so we can detect the
- //incorrect width.
- if (list.offsetWidth != list.parentNode.clientWidth - list.offsetLeft) {
- // Set the width to the correct size. This causes the relayout.
- list.style.width = list.parentNode.clientWidth - list.offsetLeft + 'px';
- // Remove the temporary style.width in a timeout. Once the timer fires
- // the size should not change since we already fixed the width.
- window.setTimeout(function() {
- list.style.width = '';
- }, 0);
- }
- }
- };
-
- /**
- * The ID of the bookmark folder we are displaying.
- * @type {string}
- */
- cr.defineProperty(BookmarkList, 'parentId', cr.PropertyKind.JS,
- function() {
- this.reload();
- });
-
- /**
- * The contextMenu property.
- * @type {cr.ui.Menu}
- */
- cr.ui.contextMenuHandler.addContextMenuProperty(BookmarkList);
-
- /**
- * Creates a new bookmark list item.
- * @param {!BookmarkTreeNode} bookmarkNode The bookmark node this represents.
- * @constructor
- * @extends {cr.ui.ListItem}
- */
- function BookmarkListItem(bookmarkNode) {
- var el = cr.doc.createElement('div');
- el.bookmarkNode = bookmarkNode;
- BookmarkListItem.decorate(el);
- return el;
- }
-
- /**
- * Decorates an element as a bookmark list item.
- * @param {!HTMLElement} el The element to decorate.
- */
- BookmarkListItem.decorate = function(el) {
- el.__proto__ = BookmarkListItem.prototype;
- el.decorate();
- };
-
- BookmarkListItem.prototype = {
- __proto__: ListItem.prototype,
-
- /** @override */
- decorate: function() {
- ListItem.prototype.decorate.call(this);
-
- var bookmarkNode = this.bookmarkNode;
-
- this.draggable = true;
-
- var labelEl = this.ownerDocument.createElement('div');
- labelEl.className = 'label';
- labelEl.textContent = bookmarkNode.title;
-
- var urlEl = this.ownerDocument.createElement('div');
- urlEl.className = 'url';
-
- if (bmm.isFolder(bookmarkNode)) {
- this.className = 'folder';
- } else {
- labelEl.style.backgroundImage = getFaviconImageSet(bookmarkNode.url);
- labelEl.style.backgroundSize = '16px';
- urlEl.textContent = bookmarkNode.url;
- }
-
- this.appendChild(labelEl);
- this.appendChild(urlEl);
-
- // Initially the ContextMenuButton was added here but it slowed down
- // rendering a lot so it is now added using mouseover.
- },
-
- /**
- * The ID of the bookmark folder we are currently showing or loading.
- * @type {string}
- */
- get bookmarkId() {
- return this.bookmarkNode.id;
- },
-
- /**
- * Whether the user is currently able to edit the list item.
- * @type {boolean}
- */
- get editing() {
- return this.hasAttribute('editing');
- },
- set editing(editing) {
- var oldEditing = this.editing;
- if (oldEditing == editing)
- return;
-
- var url = this.bookmarkNode.url;
- var title = this.bookmarkNode.title;
- var isFolder = bmm.isFolder(this.bookmarkNode);
- var listItem = this;
- var labelEl = this.firstChild;
- var urlEl = labelEl.nextSibling;
- var labelInput, urlInput;
-
- // Handles enter and escape which trigger reset and commit respectively.
- function handleKeydown(e) {
- // Make sure that the tree does not handle the key.
- e.stopPropagation();
-
- // Calling list.focus blurs the input which will stop editing the list
- // item.
- switch (e.keyIdentifier) {
- case 'U+001B': // Esc
- labelInput.value = title;
- if (!isFolder)
- urlInput.value = url;
- // fall through
- cr.dispatchSimpleEvent(listItem, 'canceledit', true);
- case 'Enter':
- if (listItem.parentNode)
- listItem.parentNode.focus();
- }
- }
-
- function handleBlur(e) {
- // When the blur event happens we do not know who is getting focus so we
- // delay this a bit since we want to know if the other input got focus
- // before deciding if we should exit edit mode.
- var doc = e.target.ownerDocument;
- window.setTimeout(function() {
- var activeElement = doc.hasFocus() && doc.activeElement;
- if (activeElement != urlInput && activeElement != labelInput) {
- listItem.editing = false;
- }
- }, 50);
- }
-
- var doc = this.ownerDocument;
- if (editing) {
- this.setAttribute('editing', '');
- this.draggable = false;
-
- labelInput = doc.createElement('input');
- labelInput.placeholder =
- loadTimeData.getString('name_input_placeholder');
- replaceAllChildren(labelEl, labelInput);
- labelInput.value = title;
-
- if (!isFolder) {
- urlInput = doc.createElement('input');
- urlInput.type = 'url';
- urlInput.required = true;
- urlInput.placeholder =
- loadTimeData.getString('url_input_placeholder');
-
- // We also need a name for the input for the CSS to work.
- urlInput.name = '-url-input-' + cr.createUid();
- replaceAllChildren(urlEl, urlInput);
- urlInput.value = url;
- }
-
- function stopPropagation(e) {
- e.stopPropagation();
- }
-
- var eventsToStop =
- ['mousedown', 'mouseup', 'contextmenu', 'dblclick', 'paste'];
- eventsToStop.forEach(function(type) {
- labelInput.addEventListener(type, stopPropagation);
- });
- labelInput.addEventListener('keydown', handleKeydown);
- labelInput.addEventListener('blur', handleBlur);
- cr.ui.limitInputWidth(labelInput, this, 100, 0.5);
- labelInput.focus();
- labelInput.select();
-
- if (!isFolder) {
- eventsToStop.forEach(function(type) {
- urlInput.addEventListener(type, stopPropagation);
- });
- urlInput.addEventListener('keydown', handleKeydown);
- urlInput.addEventListener('blur', handleBlur);
- cr.ui.limitInputWidth(urlInput, this, 200, 0.5);
- }
-
- } else {
- // Check that we have a valid URL and if not we do not change the
- // editing mode.
- if (!isFolder) {
- var urlInput = this.querySelector('.url input');
- var newUrl = urlInput.value;
- if (!newUrl) {
- cr.dispatchSimpleEvent(this, 'canceledit', true);
- return;
- }
-
- if (!urlInput.validity.valid) {
- // WebKit does not do URL fix up so we manually test if prepending
- // 'http://' would make the URL valid.
- // https://bugs.webkit.org/show_bug.cgi?id=29235
- urlInput.value = 'http://' + newUrl;
- if (!urlInput.validity.valid) {
- // still invalid
- urlInput.value = newUrl;
-
- // In case the item was removed before getting here we should
- // not alert.
- if (listItem.parentNode) {
- // Select the item again.
- var dataModel = this.parentNode.dataModel;
- var index = dataModel.indexOf(this.bookmarkNode);
- var sm = this.parentNode.selectionModel;
- sm.selectedIndex = sm.leadIndex = sm.anchorIndex = index;
-
- alert(loadTimeData.getString('invalid_url'));
- }
- urlInput.focus();
- urlInput.select();
- return;
- }
- newUrl = 'http://' + newUrl;
- }
- urlEl.textContent = this.bookmarkNode.url = newUrl;
- }
-
- this.removeAttribute('editing');
- this.draggable = true;
-
- labelInput = this.querySelector('.label input');
- var newLabel = labelInput.value;
- labelEl.textContent = this.bookmarkNode.title = newLabel;
-
- if (isFolder) {
- if (newLabel != title) {
- cr.dispatchSimpleEvent(this, 'rename', true);
- }
- } else if (newLabel != title || newUrl != url) {
- cr.dispatchSimpleEvent(this, 'edit', true);
- }
- }
- }
- };
-
- return {
- BookmarkList: BookmarkList,
- list: list
- };
-});
diff --git a/chromium/chrome/browser/resources/enhanced_bookmark_manager/js/bmm/bookmark_tree.js b/chromium/chrome/browser/resources/enhanced_bookmark_manager/js/bmm/bookmark_tree.js
deleted file mode 100644
index 8098b07e1f0..00000000000
--- a/chromium/chrome/browser/resources/enhanced_bookmark_manager/js/bmm/bookmark_tree.js
+++ /dev/null
@@ -1,307 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-
-cr.define('bmm', function() {
- /**
- * The id of the bookmark root.
- * @type {string}
- * @const
- */
- var ROOT_ID = '0';
-
- /** @const */ var Tree = cr.ui.Tree;
- /** @const */ var TreeItem = cr.ui.TreeItem;
-
- var treeLookup = {};
- var tree;
-
- // Manager for persisting the expanded state.
- var expandedManager = {
- /**
- * A map of the collapsed IDs.
- * @type {Object}
- */
- map: 'bookmarkTreeState' in localStorage ?
- JSON.parse(localStorage['bookmarkTreeState']) : {},
-
- /**
- * Set the collapsed state for an ID.
- * @param {string} The bookmark ID of the tree item that was expanded or
- * collapsed.
- * @param {boolean} expanded Whether the tree item was expanded.
- */
- set: function(id, expanded) {
- if (expanded)
- delete this.map[id];
- else
- this.map[id] = 1;
-
- this.save();
- },
-
- /**
- * @param {string} id The bookmark ID.
- * @return {boolean} Whether the tree item should be expanded.
- */
- get: function(id) {
- return !(id in this.map);
- },
-
- /**
- * Callback for the expand and collapse events from the tree.
- * @param {!Event} e The collapse or expand event.
- */
- handleEvent: function(e) {
- this.set(e.target.bookmarkId, e.type == 'expand');
- },
-
- /**
- * Cleans up old bookmark IDs.
- */
- cleanUp: function() {
- for (var id in this.map) {
- // If the id is no longer in the treeLookup the bookmark no longer
- // exists.
- if (!(id in treeLookup))
- delete this.map[id];
- }
- this.save();
- },
-
- timer: null,
-
- /**
- * Saves the expanded state to the localStorage.
- */
- save: function() {
- clearTimeout(this.timer);
- var map = this.map;
- // Save in a timeout so that we can coalesce multiple changes.
- this.timer = setTimeout(function() {
- localStorage['bookmarkTreeState'] = JSON.stringify(map);
- }, 100);
- }
- };
-
- // Clean up once per session but wait until things settle down a bit.
- setTimeout(expandedManager.cleanUp.bind(expandedManager), 1e4);
-
- /**
- * Creates a new tree item for a bookmark node.
- * @param {!Object} bookmarkNode The bookmark node.
- * @constructor
- * @extends {TreeItem}
- */
- function BookmarkTreeItem(bookmarkNode) {
- var ti = new TreeItem({
- label: bookmarkNode.title,
- bookmarkNode: bookmarkNode,
- // Bookmark toolbar and Other bookmarks are not draggable.
- draggable: bookmarkNode.parentId != ROOT_ID
- });
- ti.__proto__ = BookmarkTreeItem.prototype;
- treeLookup[bookmarkNode.id] = ti;
- return ti;
- }
-
- BookmarkTreeItem.prototype = {
- __proto__: TreeItem.prototype,
-
- /**
- * The ID of the bookmark this tree item represents.
- * @type {string}
- */
- get bookmarkId() {
- return this.bookmarkNode.id;
- }
- };
-
- /**
- * Asynchronousy adds a tree item at the correct index based on the bookmark
- * backend.
- *
- * Since the bookmark tree only contains folders the index we get from certain
- * callbacks is not very useful so we therefore have this async call which
- * gets the children of the parent and adds the tree item at the desired
- * index.
- *
- * This also exoands the parent so that newly added children are revealed.
- *
- * @param {!cr.ui.TreeItem} parent The parent tree item.
- * @param {!cr.ui.TreeItem} treeItem The tree item to add.
- * @param {Function=} f A function which gets called after the item has been
- * added at the right index.
- */
- function addTreeItem(parent, treeItem, opt_f) {
- chrome.bookmarks.getChildren(parent.bookmarkNode.id, function(children) {
- var index = children.filter(bmm.isFolder).map(function(item) {
- return item.id;
- }).indexOf(treeItem.bookmarkNode.id);
- parent.addAt(treeItem, index);
- parent.expanded = true;
- if (opt_f)
- opt_f();
- });
- }
-
-
- /**
- * Creates a new bookmark list.
- * @param {Object=} opt_propertyBag Optional properties.
- * @constructor
- * @extends {HTMLButtonElement}
- */
- var BookmarkTree = cr.ui.define('tree');
-
- BookmarkTree.prototype = {
- __proto__: Tree.prototype,
-
- decorate: function() {
- Tree.prototype.decorate.call(this);
- this.addEventListener('expand', expandedManager);
- this.addEventListener('collapse', expandedManager);
-
- bmm.tree = this;
- },
-
- handleBookmarkChanged: function(id, changeInfo) {
- var treeItem = treeLookup[id];
- if (treeItem)
- treeItem.label = treeItem.bookmarkNode.title = changeInfo.title;
- },
-
- handleChildrenReordered: function(id, reorderInfo) {
- var parentItem = treeLookup[id];
- // The tree only contains folders.
- var dirIds = reorderInfo.childIds.filter(function(id) {
- return id in treeLookup;
- }).forEach(function(id, i) {
- parentItem.addAt(treeLookup[id], i);
- });
- },
-
- handleCreated: function(id, bookmarkNode) {
- if (bmm.isFolder(bookmarkNode)) {
- var parentItem = treeLookup[bookmarkNode.parentId];
- var newItem = new BookmarkTreeItem(bookmarkNode);
- addTreeItem(parentItem, newItem);
- }
- },
-
- handleMoved: function(id, moveInfo) {
- var treeItem = treeLookup[id];
- if (treeItem) {
- var oldParentItem = treeLookup[moveInfo.oldParentId];
- oldParentItem.remove(treeItem);
- var newParentItem = treeLookup[moveInfo.parentId];
- // The tree only shows folders so the index is not the index we want. We
- // therefore get the children need to adjust the index.
- addTreeItem(newParentItem, treeItem);
- }
- },
-
- handleRemoved: function(id, removeInfo) {
- var parentItem = treeLookup[removeInfo.parentId];
- var itemToRemove = treeLookup[id];
- if (parentItem && itemToRemove)
- parentItem.remove(itemToRemove);
- },
-
- insertSubtree: function(folder) {
- if (!bmm.isFolder(folder))
- return;
- var children = folder.children;
- this.handleCreated(folder.id, folder);
- for (var i = 0; i < children.length; i++) {
- var child = children[i];
- this.insertSubtree(child);
- }
- },
-
- /**
- * Returns the bookmark node with the given ID. The tree only maintains
- * folder nodes.
- * @param {string} id The ID of the node to find.
- * @return {BookmarkTreeNode} The bookmark tree node or null if not found.
- */
- getBookmarkNodeById: function(id) {
- var treeItem = treeLookup[id];
- if (treeItem)
- return treeItem.bookmarkNode;
- return null;
- },
-
- /**
- * Returns the selected bookmark folder node as an array.
- * @type {!Array} Array of bookmark nodes.
- */
- get selectedFolders() {
- return this.selectedItem && this.selectedItem.bookmarkNode ?
- [this.selectedItem.bookmarkNode] : [];
- },
-
- /**
- * Fetches the bookmark items and builds the tree control.
- */
- reload: function() {
- /**
- * Recursive helper function that adds all the directories to the
- * parentTreeItem.
- * @param {!cr.ui.Tree|!cr.ui.TreeItem} parentTreeItem The parent tree
- * element to append to.
- * @param {!Array.<BookmarkTreeNode>} bookmarkNodes A list of bookmark
- * nodes to be added.
- * @return {boolean} Whether any directories where added.
- */
- function buildTreeItems(parentTreeItem, bookmarkNodes) {
- var hasDirectories = false;
- for (var i = 0, bookmarkNode; bookmarkNode = bookmarkNodes[i]; i++) {
- if (bmm.isFolder(bookmarkNode)) {
- hasDirectories = true;
- var item = new BookmarkTreeItem(bookmarkNode);
- parentTreeItem.add(item);
- var anyChildren = buildTreeItems(item, bookmarkNode.children);
- item.expanded = anyChildren && expandedManager.get(bookmarkNode.id);
- }
- }
- return hasDirectories;
- }
-
- var self = this;
- chrome.bookmarkManagerPrivate.getSubtree('', true, function(root) {
- self.clear();
- buildTreeItems(self, root[0].children);
- cr.dispatchSimpleEvent(self, 'load');
- });
- },
-
- /**
- * Clears the tree.
- */
- clear: function() {
- // Remove all fields without recreating the object since other code
- // references it.
- for (var id in treeLookup) {
- delete treeLookup[id];
- }
- this.textContent = '';
- },
-
- /** @override */
- remove: function(child) {
- Tree.prototype.remove.call(this, child);
- if (child.bookmarkNode)
- delete treeLookup[child.bookmarkNode.id];
- }
- };
-
- return {
- BookmarkTree: BookmarkTree,
- BookmarkTreeItem: BookmarkTreeItem,
- treeLookup: treeLookup,
- tree: tree,
- ROOT_ID: ROOT_ID
- };
-});
diff --git a/chromium/chrome/browser/resources/enhanced_bookmark_manager/js/bmm_test.html b/chromium/chrome/browser/resources/enhanced_bookmark_manager/js/bmm_test.html
deleted file mode 100644
index 88e8cbee91e..00000000000
--- a/chromium/chrome/browser/resources/enhanced_bookmark_manager/js/bmm_test.html
+++ /dev/null
@@ -1,117 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<!-- TODO(arv): Check in Closure unit tests and make this run as part of the
- tests -->
-<script src="http://closure-library.googlecode.com/svn/trunk/closure/goog/base.js"></script>
-<script src="cr.js"></script>
-<script src="cr/promise.js"></script>
-<script src="bmm/treeiterator.js"></script>
-<script src="bmm.js"></script>
-<script>
-
-goog.require('goog.testing.jsunit');
-
-</script>
-</head>
-<body>
-<script>
-
-var tree = {
- id: 0,
- children: [
- {
- id: 1,
- children: [
- {id: 2},
- {id: 3, children: []}
- ]
- },
- {id: 4},
- {id: 5}
- ]
-};
-
-// Mock chrome.bookmarkManagerPrivate.getSubtree
-chrome = chrome || {};
-chrome.bookmarkManagerPrivate = chrome.bookmarkManagerPrivate || {};
-
-var callbacks = {};
-
-chrome.bookmarkManagerPrivate.getSubtree = function(id, foldersOnly, callback) {
- callbacks[id] = callbacks[id] || [];
- callbacks[id].push(callback);
- callbacks[id].$calls = callbacks[id].$calls ? callbacks[id].$calls++ : 1;
-};
-
-chrome.bookmarkManagerPrivate.getSubtree.load = function(node) {
- // getSubtree gets the root tree when id is ''.
- var id = node.id;
- if (id == tree.id)
- id = '';
- for (var i = 0; i < callbacks[id].length; i++) {
- callbacks[id][i].call(null, [node]);
- }
-};
-
-function setUp() {
- callbacks = {}
-}
-
-function testLoadSingle() {
- var calls = 0;
- function f(node) {
- calls++;
- assertEquals(tree, node);
- }
- var p = bmm.loadTree();
- p.addListener(f);
-
- chrome.bookmarkManagerPrivate.getSubtree.load(tree);
-
- assertEquals(1, calls);
- assertEquals(1, callbacks[''].$calls);
-}
-
-function testLoadMultiple() {
- var calls1 = 0;
- var calls2 = 0;
- function f1(node) {
- calls1++;
- assertEquals(tree, node);
- }
- function f2(node) {
- calls2++;
- assertEquals(tree, node);
- }
-
- var p = bmm.loadTree();
- var p2 = bmm.loadTree();
- p.addListener(f1);
- p2.addListener(f2);
-
- chrome.bookmarkManagerPrivate.getSubtree.load(tree);
-
- assertEquals(1, calls1);
- assertEquals(1, calls2);
- assertEquals(1, callbacks[''].$calls);
-}
-
-function testLoadSubtree() {
- var calls = 0;
- function f(node) {
- calls++;
- assertEquals(tree.children[0], node);
- }
- var p = bmm.loadSubtree(1);
- p.addListener(f);
-
- chrome.bookmarkManagerPrivate.getSubtree.load(tree.children[0]);
-
- assertEquals(1, calls);
- assertEquals(1, callbacks[1].$calls);
-}
-
-</script>
-</body>
-</html>
diff --git a/chromium/chrome/browser/resources/enhanced_bookmark_manager/js/dnd.js b/chromium/chrome/browser/resources/enhanced_bookmark_manager/js/dnd.js
deleted file mode 100644
index b4859a6310a..00000000000
--- a/chromium/chrome/browser/resources/enhanced_bookmark_manager/js/dnd.js
+++ /dev/null
@@ -1,502 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-cr.define('dnd', function() {
- 'use strict';
-
- /** @const */ var BookmarkList = bmm.BookmarkList;
- /** @const */ var ListItem = cr.ui.ListItem;
- /** @const */ var TreeItem = cr.ui.TreeItem;
-
- /**
- * Enumeration of valid drop locations relative to an element. These are
- * bit masks to allow combining multiple locations in a single value.
- * @enum {number}
- * @const
- */
- var DropPosition = {
- NONE: 0,
- ABOVE: 1,
- ON: 2,
- BELOW: 4
- };
-
- /**
- * @type {Object} Drop information calculated in |handleDragOver|.
- */
- var dropDestination = null;
-
- /**
- * @type {number} Timer id used to help minimize flicker.
- */
- var removeDropIndicatorTimer;
-
- /**
- * The element that had a style applied it to indicate the drop location.
- * This is used to easily remove the style when necessary.
- * @type {Element}
- */
- var lastIndicatorElement;
-
- /**
- * The style that was applied to indicate the drop location.
- * @type {string}
- */
- var lastIndicatorClassName;
-
- var dropIndicator = {
- /**
- * Applies the drop indicator style on the target element and stores that
- * information to easily remove the style in the future.
- */
- addDropIndicatorStyle: function(indicatorElement, position) {
- var indicatorStyleName = position == DropPosition.ABOVE ? 'drag-above' :
- position == DropPosition.BELOW ? 'drag-below' :
- 'drag-on';
-
- lastIndicatorElement = indicatorElement;
- lastIndicatorClassName = indicatorStyleName;
-
- indicatorElement.classList.add(indicatorStyleName);
- },
-
- /**
- * Clears the drop indicator style from the last element was the drop target
- * so the drop indicator is no longer for that element.
- */
- removeDropIndicatorStyle: function() {
- if (!lastIndicatorElement || !lastIndicatorClassName)
- return;
- lastIndicatorElement.classList.remove(lastIndicatorClassName);
- lastIndicatorElement = null;
- lastIndicatorClassName = null;
- },
-
- /**
- * Displays the drop indicator on the current drop target to give the
- * user feedback on where the drop will occur.
- */
- update: function(dropDest) {
- window.clearTimeout(removeDropIndicatorTimer);
-
- var indicatorElement = dropDest.element;
- var position = dropDest.position;
- if (dropDest.element instanceof BookmarkList) {
- // For an empty bookmark list use 'drop-above' style.
- position = DropPosition.ABOVE;
- } else if (dropDest.element instanceof TreeItem) {
- indicatorElement = indicatorElement.querySelector('.tree-row');
- }
- dropIndicator.removeDropIndicatorStyle();
- dropIndicator.addDropIndicatorStyle(indicatorElement, position);
- },
-
- /**
- * Stop displaying the drop indicator.
- */
- finish: function() {
- // The use of a timeout is in order to reduce flickering as we move
- // between valid drop targets.
- window.clearTimeout(removeDropIndicatorTimer);
- removeDropIndicatorTimer = window.setTimeout(function() {
- dropIndicator.removeDropIndicatorStyle();
- }, 100);
- }
- };
-
- /**
- * Delay for expanding folder when pointer hovers on folder in tree view in
- * milliseconds.
- * @type {number}
- * @const
- */
- // TODO(yosin): EXPAND_FOLDER_DELAY should follow system settings. 400ms is
- // taken from Windows default settings.
- var EXPAND_FOLDER_DELAY = 400;
-
- /**
- * The timestamp when the mouse was over a folder during a drag operation.
- * Used to open the hovered folder after a certain time.
- * @type {number}
- */
- var lastHoverOnFolderTimeStamp = 0;
-
- /**
- * Expand a folder if the user has hovered for longer than the specified
- * time during a drag action.
- */
- function updateAutoExpander(eventTimeStamp, overElement) {
- // Expands a folder in tree view when pointer hovers on it longer than
- // EXPAND_FOLDER_DELAY.
- var hoverOnFolderTimeStamp = lastHoverOnFolderTimeStamp;
- lastHoverOnFolderTimeStamp = 0;
- if (hoverOnFolderTimeStamp) {
- if (eventTimeStamp - hoverOnFolderTimeStamp >= EXPAND_FOLDER_DELAY)
- overElement.expanded = true;
- else
- lastHoverOnFolderTimeStamp = hoverOnFolderTimeStamp;
- } else if (overElement instanceof TreeItem &&
- bmm.isFolder(overElement.bookmarkNode) &&
- overElement.hasChildren &&
- !overElement.expanded) {
- lastHoverOnFolderTimeStamp = eventTimeStamp;
- }
- }
-
- /**
- * Stores the information abou the bookmark and folders being dragged.
- * @type {Object}
- */
- var dragData = null;
- var dragInfo = {
- handleChromeDragEnter: function(newDragData) {
- dragData = newDragData;
- },
- clearDragData: function() {
- dragData = null;
- },
- isDragValid: function() {
- return !!dragData;
- },
- isSameProfile: function() {
- return dragData && dragData.sameProfile;
- },
- isDraggingFolders: function() {
- return dragData && dragData.elements.some(function(node) {
- return !node.url;
- });
- },
- isDraggingBookmark: function(bookmarkId) {
- return dragData && dragData.elements.some(function(node) {
- return node.id == bookmarkId;
- });
- },
- isDraggingChildBookmark: function(folderId) {
- return dragData && dragData.elements.some(function(node) {
- return node.parentId == folderId;
- });
- },
- isDraggingFolderToDescendant: function(bookmarkNode) {
- return dragData && dragData.elements.some(function(node) {
- var dragFolder = bmm.treeLookup[node.id];
- var dragFolderNode = dragFolder && dragFolder.bookmarkNode;
- return dragFolderNode && bmm.contains(dragFolderNode, bookmarkNode);
- });
- }
- };
-
- /**
- * External function to select folders or bookmarks after a drop action.
- * @type {function}
- */
- var selectItemsAfterUserAction = null;
-
- function getBookmarkElement(el) {
- while (el && !el.bookmarkNode) {
- el = el.parentNode;
- }
- return el;
- }
-
- // If we are over the list and the list is showing search result, we cannot
- // drop.
- function isOverSearch(overElement) {
- return list.isSearch() && list.contains(overElement);
- }
-
- /**
- * Determines the valid drop positions for the given target element.
- * @param {!HTMLElement} overElement The element that we are currently
- * dragging over.
- * @return {DropPosition} An bit field enumeration of valid drop locations.
- */
- function calculateValidDropTargets(overElement) {
- if (!dragInfo.isDragValid() || isOverSearch(overElement))
- return DropPosition.NONE;
-
- if (dragInfo.isSameProfile() &&
- (dragInfo.isDraggingBookmark(overElement.bookmarkNode.id) ||
- dragInfo.isDraggingFolderToDescendant(overElement.bookmarkNode))) {
- return DropPosition.NONE;
- }
-
- var canDropInfo = calculateDropAboveBelow(overElement);
- if (canDropOn(overElement))
- canDropInfo |= DropPosition.ON;
-
- return canDropInfo;
- }
-
- function calculateDropAboveBelow(overElement) {
- if (overElement instanceof BookmarkList)
- return DropPosition.NONE;
-
- // We cannot drop between Bookmarks bar and Other bookmarks.
- if (overElement.bookmarkNode.parentId == bmm.ROOT_ID)
- return DropPosition.NONE;
-
- var isOverTreeItem = overElement instanceof TreeItem;
- var isOverExpandedTree = isOverTreeItem && overElement.expanded;
- var isDraggingFolders = dragInfo.isDraggingFolders();
-
- // We can only drop between items in the tree if we have any folders.
- if (isOverTreeItem && !isDraggingFolders)
- return DropPosition.NONE;
-
- // When dragging from a different profile we do not need to consider
- // conflicts between the dragged items and the drop target.
- if (!dragInfo.isSameProfile()) {
- // Don't allow dropping below an expanded tree item since it is confusing
- // to the user anyway.
- return isOverExpandedTree ? DropPosition.ABOVE :
- (DropPosition.ABOVE | DropPosition.BELOW);
- }
-
- var resultPositions = DropPosition.NONE;
-
- // Cannot drop above if the item above is already in the drag source.
- var previousElem = overElement.previousElementSibling;
- if (!previousElem || !dragInfo.isDraggingBookmark(previousElem.bookmarkId))
- resultPositions |= DropPosition.ABOVE;
-
- // Don't allow dropping below an expanded tree item since it is confusing
- // to the user anyway.
- if (isOverExpandedTree)
- return resultPositions;
-
- // Cannot drop below if the item below is already in the drag source.
- var nextElement = overElement.nextElementSibling;
- if (!nextElement || !dragInfo.isDraggingBookmark(nextElement.bookmarkId))
- resultPositions |= DropPosition.BELOW;
-
- return resultPositions;
- }
-
- /**
- * Determine whether we can drop the dragged items on the drop target.
- * @param {!HTMLElement} overElement The element that we are currently
- * dragging over.
- * @return {boolean} Whether we can drop the dragged items on the drop
- * target.
- */
- function canDropOn(overElement) {
- // We can only drop on a folder.
- if (!bmm.isFolder(overElement.bookmarkNode))
- return false;
-
- if (!dragInfo.isSameProfile())
- return true;
-
- if (overElement instanceof BookmarkList) {
- // We are trying to drop an item past the last item. This is
- // only allowed if dragged item is different from the last item
- // in the list.
- var listItems = list.items;
- var len = listItems.length;
- if (!len || !dragInfo.isDraggingBookmark(listItems[len - 1].bookmarkId))
- return true;
- }
-
- return !dragInfo.isDraggingChildBookmark(overElement.bookmarkNode.id);
- }
-
- /**
- * Callback for the dragstart event.
- * @param {Event} e The dragstart event.
- */
- function handleDragStart(e) {
- // Determine the selected bookmarks.
- var target = e.target;
- var draggedNodes = [];
- if (target instanceof ListItem) {
- // Use selected items.
- draggedNodes = target.parentNode.selectedItems;
- } else if (target instanceof TreeItem) {
- draggedNodes.push(target.bookmarkNode);
- }
-
- // We manage starting the drag by using the extension API.
- e.preventDefault();
-
- if (draggedNodes.length) {
- // If we are dragging a single link, we can do the *Link* effect.
- // Otherwise, we only allow copy and move.
- e.dataTransfer.effectAllowed = draggedNodes.length == 1 &&
- !bmm.isFolder(draggedNodes[0]) ? 'copyMoveLink' : 'copyMove';
-
- chrome.bookmarkManagerPrivate.startDrag(draggedNodes.map(function(node) {
- return node.id;
- }));
- }
- }
-
- function handleDragEnter(e) {
- e.preventDefault();
- }
-
- /**
- * Calback for the dragover event.
- * @param {Event} e The dragover event.
- */
- function handleDragOver(e) {
- // Allow DND on text inputs.
- if (e.target.tagName != 'INPUT') {
- // The default operation is to allow dropping links etc to do navigation.
- // We never want to do that for the bookmark manager.
- e.preventDefault();
-
- // Set to none. This will get set to something if we can do the drop.
- e.dataTransfer.dropEffect = 'none';
- }
-
- if (!dragInfo.isDragValid())
- return;
-
- var overElement = getBookmarkElement(e.target) ||
- (e.target == list ? list : null);
- if (!overElement)
- return;
-
- updateAutoExpander(e.timeStamp, overElement);
-
- var canDropInfo = calculateValidDropTargets(overElement);
- if (canDropInfo == DropPosition.NONE)
- return;
-
- // Now we know that we can drop. Determine if we will drop above, on or
- // below based on mouse position etc.
-
- dropDestination = calcDropPosition(e.clientY, overElement, canDropInfo);
- if (!dropDestination) {
- e.dataTransfer.dropEffect = 'none';
- return;
- }
-
- e.dataTransfer.dropEffect = dragInfo.isSameProfile() ? 'move' : 'copy';
- dropIndicator.update(dropDestination);
- }
-
- /**
- * This function determines where the drop will occur relative to the element.
- * @return {?Object} If no valid drop position is found, null, otherwise
- * an object containing the following parameters:
- * element - The target element that will receive the drop.
- * position - A |DropPosition| relative to the |element|.
- */
- function calcDropPosition(elementClientY, overElement, canDropInfo) {
- if (overElement instanceof BookmarkList) {
- // Dropping on the BookmarkList either means dropping below the last
- // bookmark element or on the list itself if it is empty.
- var length = overElement.items.length;
- if (length)
- return {
- element: overElement.getListItemByIndex(length - 1),
- position: DropPosition.BELOW
- };
- return {element: overElement, position: DropPosition.ON};
- }
-
- var above = canDropInfo & DropPosition.ABOVE;
- var below = canDropInfo & DropPosition.BELOW;
- var on = canDropInfo & DropPosition.ON;
- var rect = overElement.getBoundingClientRect();
- var yRatio = (elementClientY - rect.top) / rect.height;
-
- if (above && (yRatio <= .25 || yRatio <= .5 && (!below || !on)))
- return {element: overElement, position: DropPosition.ABOVE};
- if (below && (yRatio > .75 || yRatio > .5 && (!above || !on)))
- return {element: overElement, position: DropPosition.BELOW};
- if (on)
- return {element: overElement, position: DropPosition.ON};
- return null;
- }
-
- function calculateDropInfo(eventTarget, dropDestination) {
- if (!dropDestination || !dragInfo.isDragValid())
- return null;
-
- var dropPos = dropDestination.position;
- var relatedNode = dropDestination.element.bookmarkNode;
- var dropInfoResult = {
- selectTarget: null,
- selectedTreeId: -1,
- parentId: dropPos == DropPosition.ON ? relatedNode.id :
- relatedNode.parentId,
- index: -1,
- relatedIndex: -1
- };
-
- // Try to find the index in the dataModel so we don't have to always keep
- // the index for the list items up to date.
- var overElement = getBookmarkElement(eventTarget);
- if (overElement instanceof ListItem) {
- dropInfoResult.relatedIndex =
- overElement.parentNode.dataModel.indexOf(relatedNode);
- dropInfoResult.selectTarget = list;
- } else if (overElement instanceof BookmarkList) {
- dropInfoResult.relatedIndex = overElement.dataModel.length - 1;
- dropInfoResult.selectTarget = list;
- } else {
- // Tree
- dropInfoResult.relatedIndex = relatedNode.index;
- dropInfoResult.selectTarget = tree;
- dropInfoResult.selectedTreeId =
- tree.selectedItem ? tree.selectedItem.bookmarkId : null;
- }
-
- if (dropPos == DropPosition.ABOVE)
- dropInfoResult.index = dropInfoResult.relatedIndex;
- else if (dropPos == DropPosition.BELOW)
- dropInfoResult.index = dropInfoResult.relatedIndex + 1;
-
- return dropInfoResult;
- }
-
- function handleDragLeave(e) {
- dropIndicator.finish();
- }
-
- function handleDrop(e) {
- var dropInfo = calculateDropInfo(e.target, dropDestination);
- if (dropInfo) {
- selectItemsAfterUserAction(dropInfo.selectTarget,
- dropInfo.selectedTreeId);
- if (dropInfo.index != -1)
- chrome.bookmarkManagerPrivate.drop(dropInfo.parentId, dropInfo.index);
- else
- chrome.bookmarkManagerPrivate.drop(dropInfo.parentId);
-
- e.preventDefault();
- }
- dropDestination = null;
- dropIndicator.finish();
- }
-
- function clearDragData() {
- dragInfo.clearDragData();
- dropDestination = null;
- }
-
- function init(selectItemsAfterUserActionFunction) {
- function deferredClearData() {
- setTimeout(clearDragData);
- }
-
- selectItemsAfterUserAction = selectItemsAfterUserActionFunction;
-
- document.addEventListener('dragstart', handleDragStart);
- document.addEventListener('dragenter', handleDragEnter);
- document.addEventListener('dragover', handleDragOver);
- document.addEventListener('dragleave', handleDragLeave);
- document.addEventListener('drop', handleDrop);
- document.addEventListener('dragend', deferredClearData);
- document.addEventListener('mouseup', deferredClearData);
-
- chrome.bookmarkManagerPrivate.onDragEnter.addListener(
- dragInfo.handleChromeDragEnter);
- chrome.bookmarkManagerPrivate.onDragLeave.addListener(deferredClearData);
- chrome.bookmarkManagerPrivate.onDrop.addListener(deferredClearData);
- }
- return {init: init};
-});
diff --git a/chromium/chrome/browser/resources/enhanced_bookmark_manager/js/main.js b/chromium/chrome/browser/resources/enhanced_bookmark_manager/js/main.js
deleted file mode 100644
index 5c23f40337e..00000000000
--- a/chromium/chrome/browser/resources/enhanced_bookmark_manager/js/main.js
+++ /dev/null
@@ -1,1308 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-(function() {
-/** @const */ var BookmarkList = bmm.BookmarkList;
-/** @const */ var BookmarkTree = bmm.BookmarkTree;
-/** @const */ var Command = cr.ui.Command;
-/** @const */ var CommandBinding = cr.ui.CommandBinding;
-/** @const */ var LinkKind = cr.LinkKind;
-/** @const */ var ListItem = cr.ui.ListItem;
-/** @const */ var Menu = cr.ui.Menu;
-/** @const */ var MenuButton = cr.ui.MenuButton;
-/** @const */ var Promise = cr.Promise;
-/** @const */ var Splitter = cr.ui.Splitter;
-/** @const */ var TreeItem = cr.ui.TreeItem;
-
-/**
- * An array containing the BookmarkTreeNodes that were deleted in the last
- * deletion action. This is used for implementing undo.
- * @type {Array.<BookmarkTreeNode>}
- */
-var lastDeletedNodes;
-
-/**
- *
- * Holds the last DOMTimeStamp when mouse pointer hovers on folder in tree
- * view. Zero means pointer doesn't hover on folder.
- * @type {number}
- */
-var lastHoverOnFolderTimeStamp = 0;
-
-/**
- * Holds a function that will undo that last action, if global undo is enabled.
- * @type {Function}
- */
-var performGlobalUndo;
-
-/**
- * Holds a link controller singleton. Use getLinkController() rarther than
- * accessing this variabie.
- * @type {LinkController}
- */
-var linkController;
-
-/**
- * New Windows are not allowed in Windows 8 metro mode.
- */
-var canOpenNewWindows = true;
-
-/**
- * Incognito mode availability can take the following values: ,
- * - 'enabled' for when both normal and incognito modes are available;
- * - 'disabled' for when incognito mode is disabled;
- * - 'forced' for when incognito mode is forced (normal mode is unavailable).
- */
-var incognitoModeAvailability = 'enabled';
-
-/**
- * Whether bookmarks can be modified.
- * @type {boolean}
- */
-var canEdit = true;
-
-/**
- * @type {TreeItem}
- * @const
- */
-var searchTreeItem = new TreeItem({
- bookmarkId: 'q='
-});
-
-/**
- * Command shortcut mapping.
- * @const
- */
-var commandShortcutMap = cr.isMac ? {
- 'edit': 'Enter',
- // On Mac we also allow Meta+Backspace.
- 'delete': 'U+007F U+0008 Meta-U+0008',
- 'open-in-background-tab': 'Meta-Enter',
- 'open-in-new-tab': 'Shift-Meta-Enter',
- 'open-in-same-window': 'Meta-Down',
- 'open-in-new-window': 'Shift-Enter',
- 'rename-folder': 'Enter',
- // Global undo is Command-Z. It is not in any menu.
- 'undo': 'Meta-U+005A',
-} : {
- 'edit': 'F2',
- 'delete': 'U+007F',
- 'open-in-background-tab': 'Ctrl-Enter',
- 'open-in-new-tab': 'Shift-Ctrl-Enter',
- 'open-in-same-window': 'Enter',
- 'open-in-new-window': 'Shift-Enter',
- 'rename-folder': 'F2',
- // Global undo is Ctrl-Z. It is not in any menu.
- 'undo': 'Ctrl-U+005A',
-};
-
-/**
- * Mapping for folder id to suffix of UMA. These names will be appeared
- * after "BookmarkManager_NavigateTo_" in UMA dashboard.
- * @const
- */
-var folderMetricsNameMap = {
- '1': 'BookmarkBar',
- '2': 'Other',
- '3': 'Mobile',
- 'q=': 'Search',
- 'subfolder': 'SubFolder',
-};
-
-/**
- * Adds an event listener to a node that will remove itself after firing once.
- * @param {!Element} node The DOM node to add the listener to.
- * @param {string} name The name of the event listener to add to.
- * @param {function(Event)} handler Function called when the event fires.
- */
-function addOneShotEventListener(node, name, handler) {
- var f = function(e) {
- handler(e);
- node.removeEventListener(name, f);
- };
- node.addEventListener(name, f);
-}
-
-// Get the localized strings from the backend via bookmakrManagerPrivate API.
-function loadLocalizedStrings(data) {
- // The strings may contain & which we need to strip.
- for (var key in data) {
- data[key] = data[key].replace(/&/, '');
- }
-
- loadTimeData.data = data;
- i18nTemplate.process(document, loadTimeData);
-
- searchTreeItem.label = loadTimeData.getString('search');
- searchTreeItem.icon = isRTL() ? 'images/bookmark_manager_search_rtl.png' :
- 'images/bookmark_manager_search.png';
-}
-
-/**
- * Updates the location hash to reflect the current state of the application.
- */
-function updateHash() {
- window.location.hash = tree.selectedItem.bookmarkId;
-}
-
-/**
- * Navigates to a bookmark ID.
- * @param {string} id The ID to navigate to.
- * @param {function()} callback Function called when list view loaded or
- * displayed specified folder.
- */
-function navigateTo(id, callback) {
- if (list.parentId == id) {
- callback();
- return;
- }
-
- var metricsId = folderMetricsNameMap[id.replace(/^q=.*/, 'q=')] ||
- folderMetricsNameMap['subfolder'];
- chrome.metricsPrivate.recordUserAction(
- 'BookmarkManager_NavigateTo_' + metricsId);
-
- addOneShotEventListener(list, 'load', callback);
- updateParentId(id);
-}
-
-/**
- * Updates the parent ID of the bookmark list and selects the correct tree item.
- * @param {string} id The id.
- */
-function updateParentId(id) {
- // Setting list.parentId fires 'load' event.
- list.parentId = id;
-
- // When tree.selectedItem changed, tree view calls navigatTo() then it
- // calls updateHash() when list view displayed specified folder.
- tree.selectedItem = bmm.treeLookup[id] || tree.selectedItem;
-}
-
-// Process the location hash. This is called by onhashchange and when the page
-// is first loaded.
-function processHash() {
- var id = window.location.hash.slice(1);
- if (!id) {
- // If we do not have a hash, select first item in the tree.
- id = tree.items[0].bookmarkId;
- }
-
- var valid = false;
- if (/^e=/.test(id)) {
- id = id.slice(2);
-
- // If hash contains e=, edit the item specified.
- chrome.bookmarks.get(id, function(bookmarkNodes) {
- // Verify the node to edit is a valid node.
- if (!bookmarkNodes || bookmarkNodes.length != 1)
- return;
- var bookmarkNode = bookmarkNodes[0];
-
- // After the list reloads, edit the desired bookmark.
- var editBookmark = function(e) {
- var index = list.dataModel.findIndexById(bookmarkNode.id);
- if (index != -1) {
- var sm = list.selectionModel;
- sm.anchorIndex = sm.leadIndex = sm.selectedIndex = index;
- scrollIntoViewAndMakeEditable(index);
- }
- };
-
- navigateTo(bookmarkNode.parentId, editBookmark);
- });
-
- // We handle the two cases of navigating to the bookmark to be edited
- // above. Don't run the standard navigation code below.
- return;
- } else if (/^q=/.test(id)) {
- // In case we got a search hash, update the text input and the
- // bmm.treeLookup to use the new id.
- setSearch(id.slice(2));
- valid = true;
- }
-
- // Navigate to bookmark 'id' (which may be a query of the form q=query).
- if (valid) {
- updateParentId(id);
- } else {
- // We need to verify that this is a correct ID.
- chrome.bookmarks.get(id, function(items) {
- if (items && items.length == 1)
- updateParentId(id);
- });
- }
-}
-
-// Activate is handled by the open-in-same-window-command.
-function handleDoubleClickForList(e) {
- if (e.button == 0)
- $('open-in-same-window-command').execute();
-}
-
-// The list dispatches an event when the user clicks on the URL or the Show in
-// folder part.
-function handleUrlClickedForList(e) {
- getLinkController().openUrlFromEvent(e.url, e.originalEvent);
- chrome.bookmarkManagerPrivate.recordLaunch();
-}
-
-function handleSearch(e) {
- setSearch(this.value);
-}
-
-/**
- * Navigates to the search results for the search text.
- * @param {string} searchText The text to search for.
- */
-function setSearch(searchText) {
- if (searchText) {
- // Only update search item if we have a search term. We never want the
- // search item to be for an empty search.
- delete bmm.treeLookup[searchTreeItem.bookmarkId];
- var id = searchTreeItem.bookmarkId = 'q=' + searchText;
- bmm.treeLookup[searchTreeItem.bookmarkId] = searchTreeItem;
- }
-
- var input = $('term');
- // Do not update the input if the user is actively using the text input.
- if (document.activeElement != input)
- input.value = searchText;
-
- if (searchText) {
- tree.add(searchTreeItem);
- tree.selectedItem = searchTreeItem;
- } else {
- // Go "home".
- tree.selectedItem = tree.items[0];
- id = tree.selectedItem.bookmarkId;
- }
-
- // Navigate now and update hash immediately.
- navigateTo(id, updateHash);
-}
-
-// Handle the logo button UI.
-// When the user clicks the button we should navigate "home" and focus the list.
-function handleClickOnLogoButton(e) {
- setSearch('');
- $('list').focus();
-}
-
-/**
- * This returns the user visible path to the folder where the bookmark is
- * located.
- * @param {number} parentId The ID of the parent folder.
- * @return {string} The path to the the bookmark,
- */
-function getFolder(parentId) {
- var parentNode = tree.getBookmarkNodeById(parentId);
- if (parentNode) {
- var s = parentNode.title;
- if (parentNode.parentId != bmm.ROOT_ID) {
- return getFolder(parentNode.parentId) + '/' + s;
- }
- return s;
- }
-}
-
-function handleLoadForTree(e) {
- processHash();
-}
-
-function getAllUrls(nodes) {
- var urls = [];
-
- // Adds the node and all its direct children.
- function addNodes(node) {
- if (node.id == 'new')
- return;
-
- if (node.children) {
- node.children.forEach(function(child) {
- if (!bmm.isFolder(child))
- urls.push(child.url);
- });
- } else {
- urls.push(node.url);
- }
- }
-
- // Get a future promise for the nodes.
- var promises = nodes.map(function(node) {
- if (bmm.isFolder(node))
- return bmm.loadSubtree(node.id);
- // Not a folder so we already have all the data we need.
- return new Promise(node);
- });
-
- var urlsPromise = new Promise();
-
- var p = Promise.all.apply(null, promises);
- p.addListener(function(nodes) {
- nodes.forEach(function(node) {
- addNodes(node);
- });
- urlsPromise.value = urls;
- });
-
- return urlsPromise;
-}
-
-/**
- * Returns the nodes (non recursive) to use for the open commands.
- * @param {HTMLElement} target .
- * @return {Array.<BookmarkTreeNode>} .
- */
-function getNodesForOpen(target) {
- if (target == tree) {
- var folderItem = tree.selectedItem;
- return folderItem == searchTreeItem ?
- list.dataModel.slice() : tree.selectedFolders;
- }
- var items = list.selectedItems;
- return items.length ? items : list.dataModel.slice();
-}
-
-/**
- * Returns a promise that will contain all URLs of all the selected bookmarks
- * and the nested bookmarks for use with the open commands.
- * @param {HTMLElement} target The target list or tree.
- * @return {Promise} .
- */
-function getUrlsForOpenCommands(target) {
- return getAllUrls(getNodesForOpen(target));
-}
-
-function notNewNode(node) {
- return node.id != 'new';
-}
-
-/**
- * Helper function that updates the canExecute and labels for the open-like
- * commands.
- * @param {!cr.ui.CanExecuteEvent} e The event fired by the command system.
- * @param {!cr.ui.Command} command The command we are currently processing.
- * @param {string} singularId The string id of singular form of the menu label.
- * @param {string} pluralId The string id of menu label if the singular form is
- not used.
- * @param {boolean} commandDisabled Whether the menu item should be disabled
- no matter what bookmarks are selected.
- */
-function updateOpenCommand(e, command, singularId, pluralId, commandDisabled) {
- if (singularId) {
- // The command label reflects the selection which might not reflect
- // how many bookmarks will be opened. For example if you right click an
- // empty area in a folder with 1 bookmark the text should still say "all".
- var selectedNodes = getSelectedBookmarkNodes(e.target).filter(notNewNode);
- var singular = selectedNodes.length == 1 && !bmm.isFolder(selectedNodes[0]);
- command.label = loadTimeData.getString(singular ? singularId : pluralId);
- }
-
- if (commandDisabled) {
- command.disabled = true;
- e.canExecute = false;
- return;
- }
-
- getUrlsForOpenCommands(e.target).addListener(function(urls) {
- var disabled = !urls.length;
- command.disabled = disabled;
- e.canExecute = !disabled;
- });
-}
-
-/**
- * Calls the backend to figure out if we can paste the clipboard into the active
- * folder.
- * @param {Function=} opt_f Function to call after the state has been updated.
- */
-function updatePasteCommand(opt_f) {
- function update(canPaste) {
- var organizeMenuCommand = $('paste-from-organize-menu-command');
- var contextMenuCommand = $('paste-from-context-menu-command');
- organizeMenuCommand.disabled = !canPaste;
- contextMenuCommand.disabled = !canPaste;
- if (opt_f)
- opt_f();
- }
- // We cannot paste into search view.
- if (list.isSearch())
- update(false);
- else
- chrome.bookmarkManagerPrivate.canPaste(list.parentId, update);
-}
-
-function handleCanExecuteForDocument(e) {
- var command = e.command;
- switch (command.id) {
- case 'import-menu-command':
- e.canExecute = canEdit;
- break;
- case 'export-menu-command':
- // We can always execute the export-menu command.
- e.canExecute = true;
- break;
- case 'sort-command':
- e.canExecute = !list.isSearch() && list.dataModel.length > 1;
- break;
- case 'undo-command':
- // The global undo command has no visible UI, so always enable it, and
- // just make it a no-op if undo is not possible.
- e.canExecute = true;
- break;
- default:
- canExecuteForList(e);
- break;
- }
-}
-
-/**
- * Helper function for handling canExecute for the list and the tree.
- * @param {!Event} e Can execute event object.
- * @param {boolean} isSearch Whether the user is trying to do a command on
- * search.
- */
-function canExecuteShared(e, isSearch) {
- var command = e.command;
- var commandId = command.id;
- switch (commandId) {
- case 'paste-from-organize-menu-command':
- case 'paste-from-context-menu-command':
- updatePasteCommand();
- break;
-
- case 'add-new-bookmark-command':
- case 'new-folder-command':
- e.canExecute = !isSearch && canEdit;
- break;
-
- case 'open-in-new-tab-command':
- updateOpenCommand(e, command, 'open_in_new_tab', 'open_all', false);
- break;
- case 'open-in-background-tab-command':
- updateOpenCommand(e, command, '', '', false);
- break;
- case 'open-in-new-window-command':
- updateOpenCommand(e, command,
- 'open_in_new_window', 'open_all_new_window',
- // Disabled when incognito is forced.
- incognitoModeAvailability == 'forced' || !canOpenNewWindows);
- break;
- case 'open-incognito-window-command':
- updateOpenCommand(e, command,
- 'open_incognito', 'open_all_incognito',
- // Not available when incognito is disabled.
- incognitoModeAvailability == 'disabled');
- break;
-
- case 'undo-delete-command':
- e.canExecute = !!lastDeletedNodes;
- break;
- }
-}
-
-/**
- * Helper function for handling canExecute for the list and document.
- * @param {!Event} e Can execute event object.
- */
-function canExecuteForList(e) {
- var command = e.command;
- var commandId = command.id;
-
- function hasSelected() {
- return !!list.selectedItem;
- }
-
- function hasSingleSelected() {
- return list.selectedItems.length == 1;
- }
-
- function canCopyItem(item) {
- return item.id != 'new';
- }
-
- function canCopyItems() {
- var selectedItems = list.selectedItems;
- return selectedItems && selectedItems.some(canCopyItem);
- }
-
- function isSearch() {
- return list.isSearch();
- }
-
- switch (commandId) {
- case 'rename-folder-command':
- // Show rename if a single folder is selected.
- var items = list.selectedItems;
- if (items.length != 1) {
- e.canExecute = false;
- command.hidden = true;
- } else {
- var isFolder = bmm.isFolder(items[0]);
- e.canExecute = isFolder && canEdit;
- command.hidden = !isFolder;
- }
- break;
-
- case 'edit-command':
- // Show the edit command if not a folder.
- var items = list.selectedItems;
- if (items.length != 1) {
- e.canExecute = false;
- command.hidden = false;
- } else {
- var isFolder = bmm.isFolder(items[0]);
- e.canExecute = !isFolder && canEdit;
- command.hidden = isFolder;
- }
- break;
-
- case 'show-in-folder-command':
- e.canExecute = isSearch() && hasSingleSelected();
- break;
-
- case 'delete-command':
- case 'cut-command':
- e.canExecute = canCopyItems() && canEdit;
- break;
-
- case 'copy-command':
- e.canExecute = canCopyItems();
- break;
-
- case 'open-in-same-window-command':
- e.canExecute = hasSelected();
- break;
-
- default:
- canExecuteShared(e, isSearch());
- }
-}
-
-// Update canExecute for the commands when the list is the active element.
-function handleCanExecuteForList(e) {
- if (e.target != list) return;
- canExecuteForList(e);
-}
-
-// Update canExecute for the commands when the tree is the active element.
-function handleCanExecuteForTree(e) {
- if (e.target != tree) return;
-
- var command = e.command;
- var commandId = command.id;
-
- function hasSelected() {
- return !!e.target.selectedItem;
- }
-
- function isSearch() {
- var item = e.target.selectedItem;
- return item == searchTreeItem;
- }
-
- function isTopLevelItem() {
- return e.target.selectedItem.parentNode == tree;
- }
-
- switch (commandId) {
- case 'rename-folder-command':
- command.hidden = false;
- e.canExecute = hasSelected() && !isTopLevelItem() && canEdit;
- break;
-
- case 'edit-command':
- command.hidden = true;
- e.canExecute = false;
- break;
-
- case 'delete-command':
- case 'cut-command':
- e.canExecute = hasSelected() && !isTopLevelItem() && canEdit;
- break;
-
- case 'copy-command':
- e.canExecute = hasSelected() && !isTopLevelItem();
- break;
-
- default:
- canExecuteShared(e, isSearch());
- }
-}
-
-/**
- * Update the canExecute state of the commands when the selection changes.
- * @param {Event} e The change event object.
- */
-function updateCommandsBasedOnSelection(e) {
- if (e.target == document.activeElement) {
- // Paste only needs to be updated when the tree selection changes.
- var commandNames = ['copy', 'cut', 'delete', 'rename-folder', 'edit',
- 'add-new-bookmark', 'new-folder', 'open-in-new-tab',
- 'open-in-background-tab', 'open-in-new-window', 'open-incognito-window',
- 'open-in-same-window', 'show-in-folder'];
-
- if (e.target == tree) {
- commandNames.push('paste-from-context-menu', 'paste-from-organize-menu',
- 'sort');
- }
-
- commandNames.forEach(function(baseId) {
- $(baseId + '-command').canExecuteChange();
- });
- }
-}
-
-function updateEditingCommands() {
- var editingCommands = ['cut', 'delete', 'rename-folder', 'edit',
- 'add-new-bookmark', 'new-folder', 'sort',
- 'paste-from-context-menu', 'paste-from-organize-menu'];
-
- chrome.bookmarkManagerPrivate.canEdit(function(result) {
- if (result != canEdit) {
- canEdit = result;
- editingCommands.forEach(function(baseId) {
- $(baseId + '-command').canExecuteChange();
- });
- }
- });
-}
-
-function handleChangeForTree(e) {
- updateCommandsBasedOnSelection(e);
- navigateTo(tree.selectedItem.bookmarkId, updateHash);
-}
-
-function handleOrganizeButtonClick(e) {
- updateEditingCommands();
- $('add-new-bookmark-command').canExecuteChange();
- $('new-folder-command').canExecuteChange();
- $('sort-command').canExecuteChange();
-}
-
-function handleRename(e) {
- var item = e.target;
- var bookmarkNode = item.bookmarkNode;
- chrome.bookmarks.update(bookmarkNode.id, {title: item.label});
- performGlobalUndo = null; // This can't be undone, so disable global undo.
-}
-
-function handleEdit(e) {
- var item = e.target;
- var bookmarkNode = item.bookmarkNode;
- var context = {
- title: bookmarkNode.title
- };
- if (!bmm.isFolder(bookmarkNode))
- context.url = bookmarkNode.url;
-
- if (bookmarkNode.id == 'new') {
- selectItemsAfterUserAction(list);
-
- // New page
- context.parentId = bookmarkNode.parentId;
- chrome.bookmarks.create(context, function(node) {
- // A new node was created and will get added to the list due to the
- // handler.
- var dataModel = list.dataModel;
- var index = dataModel.indexOf(bookmarkNode);
- dataModel.splice(index, 1);
-
- // Select new item.
- var newIndex = dataModel.findIndexById(node.id);
- if (newIndex != -1) {
- var sm = list.selectionModel;
- list.scrollIndexIntoView(newIndex);
- sm.leadIndex = sm.anchorIndex = sm.selectedIndex = newIndex;
- }
- });
- } else {
- // Edit
- chrome.bookmarks.update(bookmarkNode.id, context);
- }
- performGlobalUndo = null; // This can't be undone, so disable global undo.
-}
-
-function handleCancelEdit(e) {
- var item = e.target;
- var bookmarkNode = item.bookmarkNode;
- if (bookmarkNode.id == 'new') {
- var dataModel = list.dataModel;
- var index = dataModel.findIndexById('new');
- dataModel.splice(index, 1);
- }
-}
-
-/**
- * Navigates to the folder that the selected item is in and selects it. This is
- * used for the show-in-folder command.
- */
-function showInFolder() {
- var bookmarkNode = list.selectedItem;
- if (!bookmarkNode)
- return;
- var parentId = bookmarkNode.parentId;
-
- // After the list is loaded we should select the revealed item.
- function selectItem() {
- var index = list.dataModel.findIndexById(bookmarkNode.id);
- if (index == -1)
- return;
- var sm = list.selectionModel;
- sm.anchorIndex = sm.leadIndex = sm.selectedIndex = index;
- list.scrollIndexIntoView(index);
- }
-
- var treeItem = bmm.treeLookup[parentId];
- treeItem.reveal();
-
- navigateTo(parentId, selectItem);
-}
-
-/**
- * @return {!cr.LinkController} The link controller used to open links based on
- * user clicks and keyboard actions.
- */
-function getLinkController() {
- return linkController ||
- (linkController = new cr.LinkController(loadTimeData));
-}
-
-/**
- * Returns the selected bookmark nodes of the provided tree or list.
- * If |opt_target| is not provided or null the active element is used.
- * Only call this if the list or the tree is focused.
- * @param {BookmarkList|BookmarkTree} opt_target The target list or tree.
- * @return {!Array} Array of bookmark nodes.
- */
-function getSelectedBookmarkNodes(opt_target) {
- return (opt_target || document.activeElement) == tree ?
- tree.selectedFolders : list.selectedItems;
-}
-
-/**
- * @return {!Array.<string>} An array of the selected bookmark IDs.
- */
-function getSelectedBookmarkIds() {
- var selectedNodes = getSelectedBookmarkNodes();
- selectedNodes.sort(function(a, b) { return a.index - b.index });
- return selectedNodes.map(function(node) {
- return node.id;
- });
-}
-
-/**
- * Opens the selected bookmarks.
- * @param {LinkKind} kind The kind of link we want to open.
- * @param {HTMLElement} opt_eventTarget The target of the user initiated event.
- */
-function openBookmarks(kind, opt_eventTarget) {
- // If we have selected any folders, we need to find all the bookmarks one
- // level down. We use multiple async calls to getSubtree instead of getting
- // the whole tree since we would like to minimize the amount of data sent.
-
- var urlsP = getUrlsForOpenCommands(opt_eventTarget);
- urlsP.addListener(function(urls) {
- getLinkController().openUrls(urls, kind);
- chrome.bookmarkManagerPrivate.recordLaunch();
- });
-}
-
-/**
- * Opens an item in the list.
- */
-function openItem() {
- var bookmarkNodes = getSelectedBookmarkNodes();
- // If we double clicked or pressed enter on a single folder, navigate to it.
- if (bookmarkNodes.length == 1 && bmm.isFolder(bookmarkNodes[0])) {
- navigateTo(bookmarkNodes[0].id, updateHash);
- } else {
- openBookmarks(LinkKind.FOREGROUND_TAB);
- }
-}
-
-/**
- * Deletes the selected bookmarks. The bookmarks are saved in memory in case
- * the user needs to undo the deletion.
- */
-function deleteBookmarks() {
- var selectedIds = getSelectedBookmarkIds();
- lastDeletedNodes = [];
-
- function performDelete() {
- chrome.bookmarkManagerPrivate.removeTrees(selectedIds);
- $('undo-delete-command').canExecuteChange();
- performGlobalUndo = undoDelete;
- }
-
- // First, store information about the bookmarks being deleted.
- selectedIds.forEach(function(id) {
- chrome.bookmarks.getSubTree(id, function(results) {
- lastDeletedNodes.push(results);
-
- // When all nodes have been saved, perform the deletion.
- if (lastDeletedNodes.length === selectedIds.length)
- performDelete();
- });
- });
-}
-
-/**
- * Restores a tree of bookmarks under a specified folder.
- * @param {BookmarkTreeNode} node The node to restore.
- * @param {=string} parentId The ID of the folder to restore under. If not
- * specified, the original parentId of the node will be used.
- */
-function restoreTree(node, parentId) {
- var bookmarkInfo = {
- parentId: parentId || node.parentId,
- title: node.title,
- index: node.index,
- url: node.url
- };
-
- chrome.bookmarks.create(bookmarkInfo, function(result) {
- if (!result) {
- console.error('Failed to restore bookmark.');
- return;
- }
-
- if (node.children) {
- // Restore the children using the new ID for this node.
- node.children.forEach(function(child) {
- restoreTree(child, result.id);
- });
- }
- });
-}
-
-/**
- * Restores the last set of bookmarks that was deleted.
- */
-function undoDelete() {
- lastDeletedNodes.forEach(function(arr) {
- arr.forEach(restoreTree);
- });
- lastDeletedNodes = null;
- $('undo-delete-command').canExecuteChange();
-
- // Only a single level of undo is supported, so disable global undo now.
- performGlobalUndo = null;
-}
-
-/**
- * Computes folder for "Add Page" and "Add Folder".
- * @return {string} The id of folder node where we'll create new page/folder.
- */
-function computeParentFolderForNewItem() {
- if (document.activeElement == tree)
- return list.parentId;
- var selectedItem = list.selectedItem;
- return selectedItem && bmm.isFolder(selectedItem) ?
- selectedItem.id : list.parentId;
-}
-
-/**
- * Callback for rename folder and edit command. This starts editing for
- * selected item.
- */
-function editSelectedItem() {
- if (document.activeElement == tree) {
- tree.selectedItem.editing = true;
- } else {
- var li = list.getListItem(list.selectedItem);
- if (li)
- li.editing = true;
- }
-}
-
-/**
- * Callback for the new folder command. This creates a new folder and starts
- * a rename of it.
- */
-function newFolder() {
- performGlobalUndo = null; // This can't be undone, so disable global undo.
-
- var parentId = computeParentFolderForNewItem();
-
- // Callback is called after tree and list data model updated.
- function createFolder(callback) {
- chrome.bookmarks.create({
- title: loadTimeData.getString('new_folder_name'),
- parentId: parentId
- }, callback);
- }
-
- if (document.activeElement == tree) {
- createFolder(function(newNode) {
- navigateTo(newNode.id, function() {
- bmm.treeLookup[newNode.id].editing = true;
- });
- });
- return;
- }
-
- function editNewFolderInList() {
- createFolder(function() {
- var index = list.dataModel.length - 1;
- var sm = list.selectionModel;
- sm.anchorIndex = sm.leadIndex = sm.selectedIndex = index;
- scrollIntoViewAndMakeEditable(index);
- });
- }
-
- navigateTo(parentId, editNewFolderInList);
-}
-
-/**
- * Scrolls the list item into view and makes it editable.
- * @param {number} index The index of the item to make editable.
- */
-function scrollIntoViewAndMakeEditable(index) {
- list.scrollIndexIntoView(index);
- // onscroll is now dispatched asynchronously so we have to postpone
- // the rest.
- setTimeout(function() {
- var item = list.getListItemByIndex(index);
- if (item)
- item.editing = true;
- });
-}
-
-/**
- * Adds a page to the current folder. This is called by the
- * add-new-bookmark-command handler.
- */
-function addPage() {
- var parentId = computeParentFolderForNewItem();
-
- function editNewBookmark() {
- var fakeNode = {
- title: '',
- url: '',
- parentId: parentId,
- id: 'new'
- };
- var dataModel = list.dataModel;
- var length = dataModel.length;
- dataModel.splice(length, 0, fakeNode);
- var sm = list.selectionModel;
- sm.anchorIndex = sm.leadIndex = sm.selectedIndex = length;
- scrollIntoViewAndMakeEditable(length);
- };
-
- navigateTo(parentId, editNewBookmark);
-}
-
-/**
- * This function is used to select items after a user action such as paste, drop
- * add page etc.
- * @param {BookmarkList|BookmarkTree} target The target of the user action.
- * @param {=string} opt_selectedTreeId If provided, then select that tree id.
- */
-function selectItemsAfterUserAction(target, opt_selectedTreeId) {
- // We get one onCreated event per item so we delay the handling until we get
- // no more events coming.
-
- var ids = [];
- var timer;
-
- function handle(id, bookmarkNode) {
- clearTimeout(timer);
- if (opt_selectedTreeId || list.parentId == bookmarkNode.parentId)
- ids.push(id);
- timer = setTimeout(handleTimeout, 50);
- }
-
- function handleTimeout() {
- chrome.bookmarks.onCreated.removeListener(handle);
- chrome.bookmarks.onMoved.removeListener(handle);
-
- if (opt_selectedTreeId && ids.indexOf(opt_selectedTreeId) != -1) {
- var index = ids.indexOf(opt_selectedTreeId);
- if (index != -1 && opt_selectedTreeId in bmm.treeLookup) {
- tree.selectedItem = bmm.treeLookup[opt_selectedTreeId];
- }
- } else if (target == list) {
- var dataModel = list.dataModel;
- var firstIndex = dataModel.findIndexById(ids[0]);
- var lastIndex = dataModel.findIndexById(ids[ids.length - 1]);
- if (firstIndex != -1 && lastIndex != -1) {
- var selectionModel = list.selectionModel;
- selectionModel.selectedIndex = -1;
- selectionModel.selectRange(firstIndex, lastIndex);
- selectionModel.anchorIndex = selectionModel.leadIndex = lastIndex;
- list.focus();
- }
- }
-
- list.endBatchUpdates();
- }
-
- list.startBatchUpdates();
-
- chrome.bookmarks.onCreated.addListener(handle);
- chrome.bookmarks.onMoved.addListener(handle);
- timer = setTimeout(handleTimeout, 300);
-}
-
-/**
- * Record user action.
- * @param {string} name An user action name.
- */
-function recordUserAction(name) {
- chrome.metricsPrivate.recordUserAction('BookmarkManager_Command_' + name);
-}
-
-/**
- * The currently selected bookmark, based on where the user is clicking.
- * @return {string} The ID of the currently selected bookmark (could be from
- * tree view or list view).
- */
-function getSelectedId() {
- if (document.activeElement == tree)
- return tree.selectedItem.bookmarkId;
- var selectedItem = list.selectedItem;
- return selectedItem && bmm.isFolder(selectedItem) ?
- selectedItem.id : tree.selectedItem.bookmarkId;
-}
-
-/**
- * Pastes the copied/cutted bookmark into the right location depending whether
- * if it was called from Organize Menu or from Context Menu.
- * @param {string} id The id of the element being pasted from.
- */
-function pasteBookmark(id) {
- recordUserAction('Paste');
- selectItemsAfterUserAction(list);
- chrome.bookmarkManagerPrivate.paste(id, getSelectedBookmarkIds());
-}
-
-/**
- * Handler for the command event. This is used for context menu of list/tree
- * and organized menu.
- * @param {!Event} e The event object.
- */
-function handleCommand(e) {
- var command = e.command;
- var commandId = command.id;
- switch (commandId) {
- case 'import-menu-command':
- recordUserAction('Import');
- chrome.bookmarks.import();
- break;
- case 'export-menu-command':
- recordUserAction('Export');
- chrome.bookmarks.export();
- break;
- case 'undo-command':
- if (performGlobalUndo) {
- recordUserAction('UndoGlobal');
- performGlobalUndo();
- } else {
- recordUserAction('UndoNone');
- }
- break;
- case 'show-in-folder-command':
- recordUserAction('ShowInFolder');
- showInFolder();
- break;
- case 'open-in-new-tab-command':
- case 'open-in-background-tab-command':
- recordUserAction('OpenInNewTab');
- openBookmarks(LinkKind.BACKGROUND_TAB, e.target);
- break;
- case 'open-in-new-window-command':
- recordUserAction('OpenInNewWindow');
- openBookmarks(LinkKind.WINDOW, e.target);
- break;
- case 'open-incognito-window-command':
- recordUserAction('OpenIncognito');
- openBookmarks(LinkKind.INCOGNITO, e.target);
- break;
- case 'delete-command':
- recordUserAction('Delete');
- deleteBookmarks();
- break;
- case 'copy-command':
- recordUserAction('Copy');
- chrome.bookmarkManagerPrivate.copy(getSelectedBookmarkIds(),
- updatePasteCommand);
- break;
- case 'cut-command':
- recordUserAction('Cut');
- chrome.bookmarkManagerPrivate.cut(getSelectedBookmarkIds(),
- updatePasteCommand);
- break;
- case 'paste-from-organize-menu-command':
- pasteBookmark(list.parentId);
- break;
- case 'paste-from-context-menu-command':
- pasteBookmark(getSelectedId());
- break;
- case 'sort-command':
- recordUserAction('Sort');
- chrome.bookmarkManagerPrivate.sortChildren(list.parentId);
- break;
- case 'rename-folder-command':
- editSelectedItem();
- break;
- case 'edit-command':
- recordUserAction('Edit');
- editSelectedItem();
- break;
- case 'new-folder-command':
- recordUserAction('NewFolder');
- newFolder();
- break;
- case 'add-new-bookmark-command':
- recordUserAction('AddPage');
- addPage();
- break;
- case 'open-in-same-window-command':
- recordUserAction('OpenInSame');
- openItem();
- break;
- case 'undo-delete-command':
- recordUserAction('UndoDelete');
- undoDelete();
- break;
- }
-}
-
-// Execute the copy, cut and paste commands when those events are dispatched by
-// the browser. This allows us to rely on the browser to handle the keyboard
-// shortcuts for these commands.
-function installEventHandlerForCommand(eventName, commandId) {
- function handle(e) {
- if (document.activeElement != list && document.activeElement != tree)
- return;
- var command = $(commandId);
- if (!command.disabled) {
- command.execute();
- if (e)
- e.preventDefault(); // Prevent the system beep.
- }
- }
- if (eventName == 'paste') {
- // Paste is a bit special since we need to do an async call to see if we
- // can paste because the paste command might not be up to date.
- document.addEventListener(eventName, function(e) {
- updatePasteCommand(handle);
- });
- } else {
- document.addEventListener(eventName, handle);
- }
-}
-
-function initializeSplitter() {
- var splitter = document.querySelector('.main > .splitter');
- Splitter.decorate(splitter);
-
- // The splitter persists the size of the left component in the local store.
- if ('treeWidth' in localStorage)
- splitter.previousElementSibling.style.width = localStorage['treeWidth'];
-
- splitter.addEventListener('resize', function(e) {
- localStorage['treeWidth'] = splitter.previousElementSibling.style.width;
- });
-}
-
-function initializeBookmarkManager() {
- // Sometimes the extension API is not initialized.
- if (!chrome.bookmarks)
- console.error('Bookmarks extension API is not available');
-
- chrome.bookmarkManagerPrivate.getStrings(loadLocalizedStrings);
-
- bmm.treeLookup[searchTreeItem.bookmarkId] = searchTreeItem;
-
- cr.ui.decorate('menu', Menu);
- cr.ui.decorate('button[menu]', MenuButton);
- cr.ui.decorate('command', Command);
- BookmarkList.decorate(list);
- BookmarkTree.decorate(tree);
-
- list.addEventListener('canceledit', handleCancelEdit);
- list.addEventListener('canExecute', handleCanExecuteForList);
- list.addEventListener('change', updateCommandsBasedOnSelection);
- list.addEventListener('contextmenu', updateEditingCommands);
- list.addEventListener('dblclick', handleDoubleClickForList);
- list.addEventListener('edit', handleEdit);
- list.addEventListener('rename', handleRename);
- list.addEventListener('urlClicked', handleUrlClickedForList);
-
- tree.addEventListener('canExecute', handleCanExecuteForTree);
- tree.addEventListener('change', handleChangeForTree);
- tree.addEventListener('contextmenu', updateEditingCommands);
- tree.addEventListener('rename', handleRename);
- tree.addEventListener('load', handleLoadForTree);
-
- cr.ui.contextMenuHandler.addContextMenuProperty(tree);
- list.contextMenu = $('context-menu');
- tree.contextMenu = $('context-menu');
-
- // We listen to hashchange so that we can update the currently shown folder
- // when // the user goes back and forward in the history.
- window.addEventListener('hashchange', processHash);
-
- document.querySelector('.header form').onsubmit = function(e) {
- setSearch($('term').value);
- e.preventDefault();
- };
-
- $('term').addEventListener('search', handleSearch);
-
- document.querySelector('.summary > button').addEventListener(
- 'click', handleOrganizeButtonClick);
-
- document.querySelector('button.logo').addEventListener(
- 'click', handleClickOnLogoButton);
-
- document.addEventListener('canExecute', handleCanExecuteForDocument);
- document.addEventListener('command', handleCommand);
-
- // Listen to copy, cut and paste events and execute the associated commands.
- installEventHandlerForCommand('copy', 'copy-command');
- installEventHandlerForCommand('cut', 'cut-command');
- installEventHandlerForCommand('paste', 'paste-from-organize-menu-command');
-
- // Install shortcuts
- for (var name in commandShortcutMap) {
- $(name + '-command').shortcut = commandShortcutMap[name];
- }
-
- // Disable almost all commands at startup.
- var commands = document.querySelectorAll('command');
- for (var i = 0, command; command = commands[i]; ++i) {
- if (command.id != 'import-menu-command' &&
- command.id != 'export-menu-command') {
- command.disabled = true;
- }
- }
-
- chrome.bookmarkManagerPrivate.canEdit(function(result) {
- canEdit = result;
- });
-
- chrome.systemPrivate.getIncognitoModeAvailability(function(result) {
- // TODO(rustema): propagate policy value to the bookmark manager when it
- // changes.
- incognitoModeAvailability = result;
- });
-
- chrome.bookmarkManagerPrivate.canOpenNewWindows(function(result) {
- canOpenNewWindows = result;
- });
-
- cr.ui.FocusOutlineManager.forDocument(document);
- initializeSplitter();
- bmm.addBookmarkModelListeners();
- dnd.init(selectItemsAfterUserAction);
- tree.reload();
-}
-
-initializeBookmarkManager();
-})();
diff --git a/chromium/chrome/browser/resources/enhanced_bookmark_manager/main.html b/chromium/chrome/browser/resources/enhanced_bookmark_manager/main.html
deleted file mode 100644
index 40ad1af5705..00000000000
--- a/chromium/chrome/browser/resources/enhanced_bookmark_manager/main.html
+++ /dev/null
@@ -1,158 +0,0 @@
-<!DOCTYPE html>
-<html i18n-values="dir:textdirection">
-<!--
-
-Copyright 2013 The Chromium Authors. All rights reserved.
-Use of this source code is governed by a BSD-style license that can be
-found in the LICENSE file.
-
--->
-<head>
-<meta name="google" value="notranslate">
-<meta charset="utf-8">
-<title i18n-content="title"></title>
-
-<link rel="stylesheet" href="chrome://resources/css/list.css">
-<link rel="stylesheet" href="chrome://resources/css/tree.css">
-<link rel="stylesheet" href="chrome://resources/css/menu.css">
-<link rel="stylesheet" href="chrome://resources/css/menu_button.css">
-<link rel="stylesheet" href="chrome://resources/css/widgets.css">
-<link rel="stylesheet" href="css/bmm.css">
-
-<script src="chrome://resources/css/tree.css.js"></script>
-<script src="css/bmm.css.js"></script>
-<script src="chrome://resources/js/event_tracker.js"></script>
-
-<script src="chrome://resources/js/cr.js"></script>
-<script src="chrome://resources/js/cr/event_target.js"></script>
-<script src="chrome://resources/js/cr/link_controller.js"></script>
-<script src="chrome://resources/js/cr/promise.js"></script>
-<script src="chrome://resources/js/cr/ui.js"></script>
-<script src="chrome://resources/js/cr/ui/touch_handler.js"></script>
-<script src="chrome://resources/js/cr/ui/array_data_model.js"></script>
-<script src="chrome://resources/js/cr/ui/command.js"></script>
-<script src="chrome://resources/js/cr/ui/focus_outline_manager.js"></script>
-<script src="chrome://resources/js/cr/ui/menu_item.js"></script>
-<script src="chrome://resources/js/cr/ui/menu.js"></script>
-<script src="chrome://resources/js/cr/ui/position_util.js"></script>
-<script src="chrome://resources/js/cr/ui/menu_button.js"></script>
-<script src="chrome://resources/js/cr/ui/context_menu_button.js"></script>
-<script src="chrome://resources/js/cr/ui/context_menu_handler.js"></script>
-<script src="chrome://resources/js/cr/ui/list_selection_model.js"></script>
-<script src="chrome://resources/js/cr/ui/list_selection_controller.js"></script>
-<script src="chrome://resources/js/cr/ui/list_item.js"></script>
-<script src="chrome://resources/js/cr/ui/list.js"></script>
-<script src="chrome://resources/js/cr/ui/tree.js"></script>
-<script src="chrome://resources/js/cr/ui/splitter.js"></script>
-
-<script src="chrome://resources/js/i18n_template_no_process.js"></script>
-<script src="chrome://resources/js/load_time_data.js"></script>
-<script src="chrome://resources/js/util.js"></script>
-
-<script src="js/bmm.js"></script>
-<script src="js/bmm/bookmark_list.js"></script>
-<script src="js/bmm/bookmark_tree.js"></script>
-<script src="js/dnd.js"></script>
-</head>
-<body i18n-values=".style.fontFamily:fontfamily;.style.fontSize:fontsize">
-
-<div class="header">
- <button class="logo link-button" tabindex=3></button>
- <form class="form">
- <input type="search" id="term" tabindex=1 autofocus incremental
- i18n-values="placeholder:search_button">
- </form>
-</div>
-
-<div class="summary">
- <h3 i18n-content="title"></h3>
- <button menu="#organize-menu" tabindex="4" i18n-content="organize_menu">
- </button>
-</div>
-
-<div class=main>
- <div id=tree-container>
- <tree id=tree tabindex=2 role="tree"></tree>
- </div>
- <div class=splitter></div>
- <list id=list tabindex=2></list>
-</div>
-
-<!-- Organize menu -->
-<command i18n-values=".label:rename_folder" id="rename-folder-command">
-</command>
-<command i18n-values=".label:edit" id="edit-command"></command>
-<command i18n-values=".label:show_in_folder" id="show-in-folder-command">
-</command>
-<command i18n-values=".label:cut" id="cut-command"></command>
-<command i18n-values=".label:copy" id="copy-command"></command>
-<command i18n-values=".label:paste" id="paste-from-organize-menu-command">
-</command>
-<command i18n-values=".label:paste" id="paste-from-context-menu-command">
-</command>
-<command i18n-values=".label:delete" id="delete-command"></command>
-<command i18n-values=".label:undo_delete" id="undo-delete-command"></command>
-<command i18n-values=".label:sort" id="sort-command"></command>
-<command i18n-values=".label:add_new_bookmark" id="add-new-bookmark-command">
-</command>
-<command i18n-values=".label:new_folder" id="new-folder-command"></command>
-
-<!-- Tools menu -->
-<command i18n-values=".label:import_menu" id="import-menu-command"></command>
-<command i18n-values=".label:export_menu" id="export-menu-command"></command>
-
-<!-- open * are handled in canExecute handler -->
-<command id="open-in-new-tab-command"></command>
-<command id="open-in-background-tab-command"></command>
-<command id="open-in-new-window-command"></command>
-<command id="open-incognito-window-command"></command>
-<command id="open-in-same-window-command"></command>
-
-<command id="undo-command"></command>
-
-<!-- TODO(arv): I think the commands might be better created in code? -->
-
-<menu id="organize-menu">
- <button command="#add-new-bookmark-command"></button>
- <button command="#new-folder-command"></button>
- <hr>
- <button command="#rename-folder-command"></button>
- <button command="#edit-command"></button>
- <button command="#show-in-folder-command"></button>
- <hr>
- <button command="#cut-command"></button>
- <button command="#copy-command"></button>
- <button command="#paste-from-organize-menu-command"></button>
- <hr>
- <button command="#delete-command"></button>
- <button command="#undo-delete-command"></button>
- <hr>
- <button command="#sort-command"></button>
- <hr>
- <button command="#import-menu-command"></button>
- <button command="#export-menu-command"></button>
-</menu>
-
-<menu id="context-menu">
- <button command="#open-in-new-tab-command"></button>
- <button command="#open-in-new-window-command"></button>
- <button command="#open-incognito-window-command"></button>
- <hr>
- <button command="#rename-folder-command"></button>
- <button command="#edit-command"></button>
- <button command="#show-in-folder-command"></button>
- <hr>
- <button command="#cut-command"></button>
- <button command="#copy-command"></button>
- <button command="#paste-from-context-menu-command"></button>
- <hr>
- <button command="#delete-command"></button>
- <button command="#undo-delete-command"></button>
- <hr>
- <button command="#add-new-bookmark-command"></button>
- <button command="#new-folder-command"></button>
-</menu>
-
-<script src="js/main.js"></script>
-</body>
-</html>
diff --git a/chromium/chrome/browser/resources/enhanced_bookmark_manager/manifest.json b/chromium/chrome/browser/resources/enhanced_bookmark_manager/manifest.json
deleted file mode 100644
index ea3be85ea51..00000000000
--- a/chromium/chrome/browser/resources/enhanced_bookmark_manager/manifest.json
+++ /dev/null
@@ -1,25 +0,0 @@
-{
- "key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDbKcYW5FseOsgJb3ZRtiVnkPMKHb7Tx3C225a2MWyLfdsSqyFTh8A7QuC5UyByn9nZzs0bv/EpZ0JTvpVxEMrtT0w3LaAbdlkCjvRwGbFN8pJLDsxKT0itcibgia87rISxN1Pmpkwp6cvMhwfYNrrSP7v/7XGSUCLzqgDv0nB1oQIDAQAB",
- "name": "Enhanced Bookmark Manager",
- "version": "0.1",
- "manifest_version": 2,
- "description": "Enhanced Bookmark Manager",
- "icons": {
- // The favicon is loaded directly from resources.pak.
- },
- "incognito" : "split",
- "permissions": [
- "bookmarks",
- "bookmarkManagerPrivate",
- "metricsPrivate",
- "systemPrivate",
- "tabs",
- "chrome://favicon/",
- "chrome://resources/"
- ],
- "chrome_url_overrides": {
- "enhanced-bookmarks": "main.html"
- },
- "content_security_policy":
- "object-src 'none'; script-src chrome://resources 'self'"
-}