summaryrefslogtreecommitdiffstats
path: root/chrome/browser/resources/bookmark_manager/js/bmm.js
blob: 73cefa63ad53ade68a41926c9fc7fab8e269a4ec (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
// Copyright (c) 2010 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() {
  const TreeIterator = bmm.TreeIterator;
  const Promise = cr.Promise;

  /**
   * Whether a node contains another node.
   * @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 loadingPromise;

  /**
   * Loads the entire bookmark tree and returns a {@code cr.Promise} that will
   * be fulfilled when done. This reuses multiple loads so that we never load
   * more than one tree at the same time.
   * @return {!cr.Promise} The future promise for the load.
   */
  function loadTree() {
    var p = new Promise;
    if (!loadingPromise) {
      loadingPromise = new Promise;
      chrome.bookmarks.getTree(function(nodes) {
        loadingPromise.value = nodes[0];
        loadingPromise = null;
      });
    }
    loadingPromise.addListener(function(n) {
      p.value = n;
    });
    return p;
  }

  /**
   * Helper function for {@code loadSubtree}. This does an in order search of
   * the tree.
   * @param {!BookmarkTreeNode} node The node to start searching at.
   * @param {string} id The ID of the node to find.
   * @return {BookmarkTreeNode} The found node or null if not found.
   */
  function findNode(node, id) {
    var it = new TreeIterator(node);
    var n;
    while (it.moveNext()) {
      n = it.current;
      if (n.id == id)
        return n;
    }
    return null;
  }

  /**
   * 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 never
   * load more than one tree at the same time. (This actually loads the entire
   * tree but it will only return the relevant subtree in the value of the
   * future promise.)
   * @return {!cr.Promise} The future promise for the load.
   */
  function loadSubtree(id) {
    var p = new Promise;
    var lp = loadTree();
    lp.addListener(function(tree) {
      var node = findNode(tree, id);
      p.value = node || Error('Failed to load subtree ' + id);
    });
    return p;
  }

  return {
    contains: contains,
    isFolder: isFolder,
    loadSubtree: loadSubtree,
    loadTree: loadTree
  };
});