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