1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2010 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochcr.define('bmm', function() {
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const Promise = cr.Promise;
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  /**
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch   * Whether a node contains another node.
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch   * @param {!BookmarkTreeNode} parent
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch   * @param {!BookmarkTreeNode} descendant
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch   * @return {boolean} Whether the parent contains the descendant.
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch   */
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  function contains(parent, descendant) {
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (descendant.parentId == parent.id)
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return true;
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // the bmm.treeLookup contains all folders
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    var parentTreeItem = bmm.treeLookup[descendant.parentId];
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!parentTreeItem || !parentTreeItem.bookmarkNode)
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return false;
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return this.contains(parent, parentTreeItem.bookmarkNode);
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  /**
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch   * @param {!BookmarkTreeNode} node The node to test.
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch   * @return {boolean} Whether a bookmark node is a folder.
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch   */
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  function isFolder(node) {
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return !('url' in node);
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  var loadingPromises = {};
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  /**
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch   * Loads a subtree of the bookmark tree and returns a {@code cr.Promise} that
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch   * will be fulfilled when done. This reuses multiple loads so that we do not
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch   * load the same subtree more than once at the same time.
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch   * @return {!cr.Promise} The future promise for the load.
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch   */
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  function loadSubtree(id) {
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    var p = new Promise;
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!(id in loadingPromises)) {
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      loadingPromises[id] = new Promise;
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      chrome.experimental.bookmarkManager.getSubtree(id, false,
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                     function(nodes) {
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        loadingPromises[id].value = nodes && nodes[0];
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        delete loadingPromises[id];
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      });
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    loadingPromises[id].addListener(function(n) {
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      p.value = n;
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    });
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return p;
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  /**
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch   * Loads the entire bookmark tree and returns a {@code cr.Promise} that will
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch   * be fulfilled when done. This reuses multiple loads so that we do not load
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch   * the same tree more than once at the same time.
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch   * @return {!cr.Promise} The future promise for the load.
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch   */
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  function loadTree() {
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return loadSubtree('');
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return {
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    contains: contains,
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    isFolder: isFolder,
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    loadSubtree: loadSubtree,
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    loadTree: loadTree
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch});
73