1

我希望能够在树中的任何位置从根文件夹返回所有用户书签文件夹的数组。

这是我来过的最接近的,它不返回任何 RESULT_TYPE_FOLDER:

function find_folders()
{
  var history = Cc["@mozilla.org/browser/nav-history-service;1"]
     .getService(Ci.nsINavHistoryService);

  var query = history.getNewQuery();
  var options = history.getNewQueryOptions();

  // Query users bookmarks, not history
  options.queryType = options.QUERY_TYPE_BOOKMARKS;

  // Execute the search and store results
  var result = history.executeQuery(query, options);

  // Open the root containerNode and open it
  var resultContainerNode = result.root;

  // OPEN resultContainerNode
  resultContainerNode.containerOpen = true;
  var folders = [];

  // Search results are now child items of this container?
  for (var i=0; i < resultContainerNode.childCount; ++i) {
    var childNode = resultContainerNode.getChild(i);

    if(childNode.type === childNode.RESULT_TYPE_FOLDER)
    {
      folders.push(childNode);
    }
  }

  // CLOSE resultContainerNode
  resultContainerNode.containerOpen = false;

  return folders;
};

find_folders();

如果我删除此结果类型检查,我会得到很多 URI,一些 RESULT_TYPE_QUERY,但没有 RESULT_TYPE_FOLDER:

childNode.type: 0
childNode.type: RESULT_TYPE_QUERY
childNode.title: Most Visited
childNode.type: 0
childNode.type: 0
childNode.type: 0
childNode.type: 0
childNode.type: 0
childNode.type: 0
childNode.type: 0
childNode.type: 0
childNode.type: 0
childNode.type: 0
childNode.type: RESULT_TYPE_QUERY
childNode.title: History

此处的文档:https ://developer.mozilla.org/en-US/docs/XPCOM_Interface_Reference/nsINavHistoryQueryOptions#Query_type_constants 建议您可以设置:

excludeItems boolean 此选项从书签查询中排除所有 URI 和分隔符。如果您只需要书签文件夹和查询的列表(例如位置页面的左窗格),则可以使用此选项。忽略历史查询。默认为假。

但是设置这个会导致查询不返回任何结果:

function find_folders()
{
  var history = Cc["@mozilla.org/browser/nav-history-service;1"]
     .getService(Ci.nsINavHistoryService);

  var query = history.getNewQuery();
  var options = history.getNewQueryOptions();

  options.queryType = options.QUERY_TYPE_BOOKMARKS;
  options.excludeItems = true; // Exclude everything that isn't a folder?
  // Execute the search and store results
  var result = history.executeQuery(query, options);

  // Open the root containerNode and open it
  var resultContainerNode = result.root;

  // OPEN resultContainerNode
  resultContainerNode.containerOpen = true;
  var folders = [];

  // Search results are now child items of this container?
  for (var i=0; i < resultContainerNode.childCount; ++i) {
    var childNode = resultContainerNode.getChild(i);
    folders.push(childNode);
  }

  // CLOSE resultContainerNode
  resultContainerNode.containerOpen = false;

  return folders;
};

find_folders(); // Returns nothing :C
4

2 回答 2

2

excludeItems仅当您指定要搜索的文件夹时才有效,例如

query.setFolders([PlacesUtils.toolbarFolderId, PlacesUtils.bookmarksMenuFolderId,
                 PlacesUtils.unfiledBookmarksFolderId], 1);

它也不会返回文件夹的平面列表,因此您必须遍历结果,递归地打开和收集内容。

如果您有一个很好的用例来获取文件夹的平面列表,您可以自由提交增强错误。

最后,您将 Places 节点从结果中取出并将它们分发出去,这基本上使它们成为僵尸对象,如果您创建自己的对象并添加您关心的东西会更好,例如{ title: node.title, uri: node.uri },或其他任何东西(我刚刚在这里发现了一个与此行为相关的错误,我将归档并修复它)。

于 2013-02-05T20:12:35.910 回答
1

好吧,看起来我在 Firefox Places 查询界面中遇到了一些错误和限制。

1 - (错误?)query.setFolders([folder_array], 1)第二个参数(文件夹计数)设置为 1 以外的任何值都不会导致任何结果。将其设置为 1 将仅搜索阵列中的第一个文件夹。

2 - (限制)excludeItems仅在您指定要搜索的文件夹时才有效:C

3 - (限制/错误?)query.setSearchTerm(term)似乎与文件夹名称不匹配,所以我不得不根据搜索词手动检查它们:Q__

粗略的解决方法是创建要搜索的文件夹数组,然后分别搜索每个文件夹,将结果连接起来,如下所示:

bookmarkr_utilities.find_folders = function(search_term)
{
  bookmarkr_utilities.debug_log("find_folders()");
  bookmarkr_utilities.folders = [];


  var folders = [   bookmarkr_utilities.bmsvc_service().toolbarFolder
                  , bookmarkr_utilities.bmsvc_service().bookmarksMenuFolder
                  , bookmarkr_utilities.bmsvc_service().unfiledBookmarksFolder   ];


  for (var i = 0; i < folders.length; i++) 
  {
    bookmarkr_utilities.folders = bookmarkr_utilities.folders.concat(bookmarkr_utilities.find_inside_folder(search_term, folders[i]));
  }

  return bookmarkr_utilities.folders;
};

实际运行搜索的辅助函数:

bookmarkr_utilities.find_inside_folder = function(search_term, search_folder)
{
  var history = Cc["@mozilla.org/browser/nav-history-service;1"]
     .getService(Ci.nsINavHistoryService);

  var result_folders = [];

  var query = history.getNewQuery();

  query.setFolders([search_folder], 1);

  var options = history.getNewQueryOptions();

  options.excludeItems = true; // exclude everything except folders
                               // only works when folders are set

  // Execute the search and store results
  var result = history.executeQuery(query, options);

  // Open the root containerNode and open it
  var resultContainerNode = result.root;
  resultContainerNode.containerOpen = true;

  // Search results are now child items of this container?
  bookmarkr_utilities.debug_log("resultContainerNode.childCount: " + resultContainerNode.childCount);
  for (var i=0; i < resultContainerNode.childCount; ++i) {
    var childNode = resultContainerNode.getChild(i);

    if(childNode.type === childNode.RESULT_TYPE_FOLDER)
    {
      // HACK HACK HACK
      if(search_term)
      {
        if(childNode.title.toLowerCase() == search_term.toLowerCase())
          result_folders.push(childNode);
      }
      // END HACK HACK HACK OH GOD
      else
      {
        result_folders.push(childNode);
      }
    }
  }

  // Close container
  resultContainerNode.containerOpen = false;

  return result_folders;
}
于 2013-02-06T10:36:04.547 回答