Querying Places
出典: MDC
このページは翻訳中です。
翻訳作業に参加する場合は、履歴にある翻訳者と連絡·調整してください。
この記事は Firefox 3 の新機能について述べています
Firefox の履歴とブックマークのデータは "Places" クエリー API を通してアクセスされます。これらの API は履歴やブックマーク、またはそれらを組み合わせた複雑な検索を実行する能力を提供します(Firefox Alpha 6 をターゲットにしています)。検索結果はマッチしたデータのフラットなリスト、もしくはツリー構造を含んだオブジェクトとなります。クエリー API の定義及び結果のデータ構造は toolkit/components/places/public/nsINavHistoryService.idl にあります。このページではコア API を使ったいくつかの共通の操作や例を提供します。
目次 |
[編集] Executing a query
Places のクエリーはいくつかの基本的なパーツを持っています:
- The query object:
nsINavHistoryQuery, 検索時のパラメータを保持します。 - The query options:
nsINavHistoryQueryOptions, 検索結果の設定を許可します。 - The history service:
nsINavHistoryService, クエリーを実行します
最初のステップではクエリーとオプションを作り、必要なパラメータを埋めていきます。nsINavHistoryService.getNewQuery と nsINavHistoryService.getNewQueryOptions を使って空のオブジェクトを取り出します。標準ではそれらのオブジェクトはフラットなリストにあなたのブラウザの全履歴が入ったクエリーの結果となるでしょう:
var historyService = Components.classes["@mozilla.org/browser/nav-history-service;1"]
.getService(Components.interfaces.nsINavHistoryService);
// クエリーのパラメータが無ければ、全ての履歴を得るでしょう
// XXX 標準のソートは...?
var options = historyService.getNewQueryOptions();
// クエリーのパラメータが無ければ、何もかもが返ってくるでしょう
var query = historyService.getNewQuery();
// クエリーを実行
var result = historyService.executeQuery(query, options);
[編集] Result types
nsINavHistoryQueryOptions は resultType プロパティを持ち、それは検索結果においてグルーピングや返ってくる詳細のレベルを設定する事を許可します。このプロパティの違う値は下からリスト化されます。これらの値は nsINavHistoryQueryOptions のプロパティとなり、このようにアクセスされます:Components.interfaces.nsINavHistoryQueryOptions.RESULTS_AS_VISIT.
- RESULTS_AS_URI: これはデフォルトで、クエリーにマッチしたそれぞれの URI ごとに
RESULT_TYPE_URIタイプの一つのノードとして返されます。それぞれのノードの訪問日は些最後にその URL に訪問した日付となるでしょう。 - RESULTS_AS_VISIT: このオプションは与えたクエリーにマッチしたそれぞれページに訪問した時間ごとに一つのエントリーとして結果を返します。この結果は重複した URL のエントリーを含み、それぞれ違う時間となるでしょう。このノードは
RESULT_TYPE_VISITタイプで、それぞれ訪問したときのセッションIDを提供します。このセッションIDはリンクをクリックしてたどった全てのページで同じ値になります。新しいセッションはユーザが新しい URL を入力するかブックマークをたどることで開始します(XXX リンクの詳細についてはセッションの性質によります)。 - RESULTS_AS_FULL_VISIT: これは
RESULT_TYPE_VISITの拡張されたバージョンです。結果はRESULT_TYPE_FULL_VISITタイプで、訪問前の場所やどのようにトランザクションが発生したのか(入力か、リダイレクトか、リンクか、など)といった訪問先の詳細な情報を持ちます。
[編集] Basic Query Search Parameters
[編集] Basic Query Configuration Options
[編集] Complex Queries
一つ以上の nsINavHistoryQuery オブジェクトを executeQueries へ渡すことができます。一つのクエリーオブジェクトに対して、全てのパラメータは AND として扱われます。異なるクエリーオブジェクトがある状態では、 OR として扱われます。これは条件に基づいた完全に論理的な操作を入れ子の節 (nested clauses) よりもよりシンプルな実装とインターフェイスを可能にしています。
今まで訪れたページでtitleかURLに "firefox" という文字列を含むもの、もしくは今日 mozilla.org 内で訪れたページを検索する例を挙げます。
// 最初のクエリーオブジェクトは title か URL に "firefox" が入っているものを検索します var query1 = historyService.getNewQuery(); query1.searchTerms = "firefox"; // 二つ目のクエリーオブジェクトは 24 時間以内でかつ mozilla.org 内で訪れたものを検索します var query2 = historyService.getNewQuery(); query2.beginTimeReference = query2.TIME_RELATIVE_NOW; query2.beginTime = -24 * 60 * 60 * 1000000; // 24 hours ago in microseconds query2.endTimeReference = query2.TIME_RELATIVE_NOW; query2.endTime = 0; // now query2.domain = "mozilla.org"; var result = historyService.executeQueries([query1, query2], 2, options);
[編集] Bookmark queries
ここでは Accessing Bookmarks を使って簡単にブックマークの検索を行う初歩的な方法を示します。
The contents of bookmark folders can be retrieved by setting the "folders" member in the query object. This item is an array of folder IDs from the bookmark service. Typically, you will only have one folder ID in this list, which will given you the contents of that folder. You can set multiple folders and the result will be the intersection of all the folders.
For sorting, you will generally want to use SORT_BY_NONE (the default) since this will return items in their "natural" order as specified by the user in the bookmarks manager. Other sortings will work, however.
For bookmark queries you will generally want no query parameters to retrieve all items from the requested folder(s). When you specify exactly one folder, GROUP_BY_FOLDER, and no query parameters, the system will be more efficient querying and keeping the results up-to-date since this maps to exactly one bookmark folder.
var bookmarkService = Components.classes["@mozilla.org/browser/nav-bookmarks-service;1"]
.getService(Components.interfaces.nsINavBookmarksService);
// |query| and |options| are objects created in the previous section
query.setFolders([bookmarkService.toolbarRoot], 1);
options.setGroupingMode([options.GROUP_BY_FOLDER], 1);
var result = historyService.executeQuery(query, options);
[編集] Serializing queries
Query and options objects can be serialized into a string starting with "place:" using queriesToQueryString. The resulting string can be stored or bookmarked. When a "place:" URI is bookmarked, it will expand to the results of the query when it is opened by the user. The original objects can be deserialized from the string using queryStringToQueries.
Be careful, queryStringToQueries may not return any query objects if the string was empty. Your code should handle this case. There will always be an options structure returned. If no options were specified, it will have the default values. If there were no query parameters specified but the input string was not empty (there were options) you may get one query object returned, containing the default query values.
Example of serializing and deserializing two queries and an options object:
var queryString = historyService.queriesToQueryStrings([query1, query2], 2, options);
var queriesRef = { };
var queryCountRef = { };
var optionsRef = { };
historyService.queryStringToQueries(queryString, queriesRef, queryCountRef, optionsRef);
// now use queriesRef.value, optionsRef.value
[編集] Using the results
The most common way to use results is to implement a view. There is a built-in view that will put results in tree controls, and you can also implement your own. See Places:Views for more on this. This section discusses how to access the result directly, for example, if you are creating your own view or are processing the results instead of displaying them.
Note: Be careful when accessing nodes and do not keep references to them around. Notifications sent to the result from the history and bookmarks system, as well as commands executed by the programmer such as sorting may cause the structure to change and nodes may be inserted, removed, or replaced.
The nsINavHistoryResult object returned by executeQuery/executeQueries contains the list of matches to the given history or bookmarks query. These results are contained in a tree structure made up of nodes. A node's type can be retrieved using its type attribute. This type tells you what interface you can QueryInterface the node to in order to get at more detailed information:
- nsINavHistoryResultNode: Base class for all nodes. Contains URI, title, and other general info.
- nsINavHistoryVisitResultNode: Derived from
nsINavHistoryResultNode, contains session information. - nsINavHistoryFullVisitResultNode: Derived from
nsINavHistoryVisitResultNode, contains information about how the user navigated to this page. Note: currently unimplemented, see bug 320831. - nsINavHistoryContainerResultNode: General container node giving access to its children. Derived from
nsINavHistoryResultNode. - nsINavHistoryQueryResultNode: A type of container representing a query of the history system. It allows you to get the query options and parameters.
- nsINavHistoryFolderResultNode: Derived from
nsINavHistoryQueryResultNode, this represents a special type of query mapping to the exact contents of one bookmarks folder. It gives easy access to its folder ID, and also updates itself more efficiently than a general query.
Example of detecting the type of a node
var Ci = Components.interfaces;
switch(node.type)
case node.RESULT_TYPE_URI:
dump("URI result " + node.uri + "\n");
break;
case node.RESULT_TYPE_VISIT:
var visit = node.QueryInterface(Ci.nsINavHistoryVisitResultNode);
dump("Visit result " + node.uri + " session = " + visit.sessionId + "\n");
break;
case node.RESULT_TYPE_FULL_VISIT:
var fullVisit = node.QueryInterface(Ci.nsINavHistoryFullVisitResultNode);
dump("Full visit result " + node.uri + " session = " + fullVisit.sessionId + " transitionType = " +
fullVisit.transitionType + "\n");
break;
case node.RESULT_TYPE_HOST:
var container = node.QueryInterface(Ci.nsINavHistoryContainerResultNode);
dump("Host " + container.title + "\n");
break;
case node.RESULT_TYPE_REMOTE_CONTAINER:
var container = node.QueryInterface(Ci.nsINavHistoryContainerResultNode);
dump("Remote container " + container.title + " type = " + container.remoteContainerType + "\n");
break;
case node.RESULT_TYPE_QUERY:
var query = node.QueryInterface(Ci.nsINavHistoryQueryResultNode);
dump("Query, place URI = " + query.uri + "\n");
break;
case node.RESULT_TYPE_FOLDER:
// note that the folder is also a query and so has a query and an options structure
var folder = node.QueryInterface(Ci.nsINavHistoryFolderResultNode);
dump("Folder " + folder.title + " id = " + folder.folderId + "\n");
break;
case node.RESULT_TYPE_SEPARATOR:
dump("-----------\n");
break;
}
[編集] Containers
Containers hold lists of other containers and result nodes. Each result has a container representing the root of the query. It can be retrieved using the root attribute of the result. For general queries, this root container is a nsINavHistoryQueryResultNode with the query parameters and options that you supplied in the original query. For queries mapping to one bookmark folder, this will be a nsINavHistoryFolderResultNode.
Containers can be open or closed. This corresponds to the open and closed state in a tree view, and can also be mapped to showing and hiding menus. To get at a container's contents, you must first open the container. Most container types populate themselves lazily, so opening a container actually corresponds to executing the given query. While a container is open, it will listen to the history and bookmarks systems' notifications and modify their contents to keep themselves up-to-date. For this reason, it is best to close a container as soon as you are done with it, since it will give better performance. If you close a container and re-open it before any history or bookmark change notifications come, the results will generally still be there and this operation will be fast.
Example of traversing a container:
var cont = result.root;
cont.containerOpen = true;
for (var i = 0; i < cont.childCount; i ++) {
var node = cont.getChild(i);
dump(node.title + "\n");
}
cont.containerOpen = false;
[編集] The result view interface
If you are mapping a result into UI, you can implement the nsINavHistoryResultViewer interface and attach it to the result with the nsINavHistoryResult.viewer attribute. This viewer will be called when the result tree changes, either as a result of user action or as a result of notifications from the bookmarks and history systems. Your implementation would then reflect these changes in the UI.
A prepackaged view interface for a nsITreeBoxObject is provided that manages the complex view requirements of a tree. This object's interface is nsINavHistoryResultTreeViewer (a descendent of nsINavHistoryResultViewer) and can be created using the contract @mozilla.org/browser/nav-history/result-tree-viewer;1.
var treeviewer =
Components.classes["@mozilla.org/browser/nav-history/result-tree-viewer;1"]
.createInstance(Components.interfaces.nsINavHistoryResultTreeViewer);
result.viewer = treeviewer;
mytree.view = treeviewer.QueryInterface(Components.interfaces.nsITreeView);
Both the result and the tree will register themselves with the viewer object using result attribute and the setTree method respectively. Do not set these explicitly.