« [Places] nsINavHistoryResultNode からブックマークの各種情報を取得する | JavaScript 関数と XPCOM メソッドの例外ハンドリング » |
[Places] フォルダ内のブックマークを列挙する
Places データベースへの問い合わせ結果から得たブックマークのノードは nsINavHistoryResultNode インタフェースを実装するオブジェクトであるが、ブックマークフォルダは nsINavHistoryContainerResultNode インタフェースも合わせて実装しており、 childCount プロパティで子ノードの数を調べたり、 getChild メソッドで指定したインデックスの子ノードを取得することができる。
例えば、[Places] ビューと nsIPlacesView インタフェース の続きとして、右クリックしたブックマークフォルダ内の子ノードにアクセスするには、以下のようにすればよい。ただし、ビュー上でフォルダが開いていることを前提とする。
// assume that node is instanceof Ci.nsINavHistoryContainerResultNode and is open. for (var i = 0; i < node.childCount; i++) { var childNode = node.getChild(i); }
一方、ビュー上でフォルダが閉じた状態になっている場合、 childCount プロパティなどを使って子ノードへアクセスしようとすると NS_ERROR_NOT_AVAILABLE 例外がスローされる。そこで、ブックマークフォルダのノードの containerOpen プロパティへ true をセットすることで一時的にフォルダを開いてから子ノードへアクセスし、処理が終わった後に false をセットしてフォルダを閉じるようにする。以下は、引数で指定したブックマークフォルダ内のすべてのブックマークを再帰的に取得し、配列として返す関数である。
function flatChildNodes(aNode) { var ret = []; var closeOriginally = !aNode.containerOpen; if (closeOriginally) // if the folder is closed, open it. aNode.containerOpen = true; for (var i = 0; i < aNode.childCount; i++) { var childNode = aNode.getChild(i); if (PlacesUtils.nodeIsBookmark(childNode)) ret.push(childNode); else if (PlacesUtils.nodeIsFolder(childNode) && !PlacesUtils.nodeIsLivemarkContainer(childNode)) // call this function recursive ret = ret.concat(arguments.callee(childNode)); } if (closeOriginally) // don't forget to restore the folder's original closed state aNode.containerOpen = false; return ret; }
上記の例では、ビュー上に表示されているブックマークフォルダ、つまりデータベースへの問い合わせ結果が取得済みのブックマークフォルダを対象としていた。ビューへの表示が無い場面でフォルダ内のノードへアクセスするには、データベースへ問い合わせを行う必要がある。通常 Places データベースへの問い合わせを行うには、 nsINavHistoryService#getNewQuery でクエリオブジェクトを生成し executeQuery で実行するという手続きが必要であるが、 PlacesUtils.getFolderContents を使えばより単純なコードでフォルダ内のノードへアクセス可能である。
var result = PlacesUtils.getFolderContents(node.itemId); // nsINavHistoryResult var parentNode = result.root; for (var i = 0; i < parentNode.childCount; i++) { var childNode = parentNode.getChild(i); }
以下は、ブックマークフォルダの itemId プロパティを引数に、そのフォルダ内の全ブックマークを再帰的に取得して配列として返す関数である。
function flatChildNodes(aItemId) { var ret = []; var parentNode = PlacesUtils.getFolderContents(aItemId).root; for (var i = 0; i < parentNode.childCount; i++) { var childNode = parentNode.getChild(i); if (PlacesUtils.nodeIsBookmark(childNode)) ret.push(childNode); else if (PlacesUtils.nodeIsFolder(childNode) && !PlacesUtils.nodeIsLivemarkContainer(childNode)) // call this function recursive ret = ret.concat(arguments.callee(childNode.itemId)); } return ret; }