mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-12 04:45:45 +00:00
Bug 323492 r=bryner,beng Places history result node refactor, dynamic updates, performance improvements.
This commit is contained in:
parent
5c25684de4
commit
a0f8231c69
@ -43,7 +43,7 @@ const Ci = Components.interfaces;
|
||||
const Cc = Components.classes;
|
||||
const Cr = Components.results;
|
||||
|
||||
const SELECTION_CONTAINS_URL = 0x01;
|
||||
const SELECTION_CONTAINS_URI = 0x01;
|
||||
const SELECTION_CONTAINS_CONTAINER = 0x02;
|
||||
const SELECTION_IS_OPEN_CONTAINER = 0x04;
|
||||
const SELECTION_IS_CLOSED_CONTAINER = 0x08;
|
||||
@ -104,16 +104,15 @@ function InsertionPoint(folderId, index, orientation) {
|
||||
* Initialization Configuration for a View
|
||||
* @constructor
|
||||
*/
|
||||
function ViewConfig(dropTypes, dropOnTypes, filterOptions, firstDropIndex) {
|
||||
function ViewConfig(dropTypes, dropOnTypes, excludeItems, expandQueries, firstDropIndex) {
|
||||
this.dropTypes = dropTypes;
|
||||
this.dropOnTypes = dropOnTypes;
|
||||
this.filterOptions = filterOptions;
|
||||
this.excludeItems = excludeItems;
|
||||
this.expandQueries = expandQueries;
|
||||
this.firstDropIndex = firstDropIndex;
|
||||
}
|
||||
ViewConfig.GENERIC_DROP_TYPES = [TYPE_X_MOZ_PLACE_CONTAINER, TYPE_X_MOZ_PLACE,
|
||||
TYPE_X_MOZ_URL];
|
||||
ViewConfig.GENERIC_FILTER_OPTIONS = Ci.nsINavHistoryQuery.INCLUDE_ITEMS +
|
||||
Ci.nsINavHistoryQuery.INCLUDE_QUERIES;
|
||||
|
||||
/**
|
||||
* Manages grouping options for a particular view type.
|
||||
@ -238,17 +237,22 @@ var PlacesController = {
|
||||
* Generates a HistoryResult for the contents of a folder.
|
||||
* @param folderId
|
||||
* The folder to open
|
||||
* @param filterOptions
|
||||
* Options regarding the type of items to be returned. See
|
||||
* documentation in nsINavHistoryQuery for the |itemTypes| property.
|
||||
* @param excludeItems
|
||||
* True to hide all items (individual bookmarks). This is used on
|
||||
* the left places pane so you just get a folder hierarchy.
|
||||
* @param expandQueries
|
||||
* True to make query items expand as new containers. For managing,
|
||||
* you want this to be false, for menus and such, you want this to
|
||||
* be true.
|
||||
* @returns A HistoryResult containing the contents of the folder.
|
||||
*/
|
||||
getFolderContents: function PC_getFolderContents(folderId, filterOptions) {
|
||||
getFolderContents: function PC_getFolderContents(folderId, excludeItems, expandQueries) {
|
||||
var query = this._hist.getNewQuery();
|
||||
query.setFolders([folderId], 1);
|
||||
query.itemTypes = filterOptions;
|
||||
var options = this._hist.getNewQueryOptions();
|
||||
options.setGroupingMode([Ci.nsINavHistoryQueryOptions.GROUP_BY_FOLDER], 1);
|
||||
options.excludeItems = excludeItems;
|
||||
options.expandQueries = expandQueries;
|
||||
return this._hist.executeQuery(query, options);
|
||||
},
|
||||
|
||||
@ -385,8 +389,7 @@ var PlacesController = {
|
||||
* @returns true if the node is a Bookmark folder, false otherwise
|
||||
*/
|
||||
nodeIsFolder: function PC_nodeIsFolder(node) {
|
||||
return (node.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_QUERY &&
|
||||
node.folderId > 0);
|
||||
return (node.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -395,10 +398,11 @@ var PlacesController = {
|
||||
* A NavHistoryResultNode
|
||||
* @returns true if the node is a URL item, false otherwise
|
||||
*/
|
||||
nodeIsURL: function PC_nodeIsURL(node) {
|
||||
nodeIsURI: function PC_nodeIsURI(node) {
|
||||
const NHRN = Ci.nsINavHistoryResultNode;
|
||||
return node.type == NHRN.RESULT_TYPE_URL ||
|
||||
node.type == NHRN.RESULT_TYPE_VISIT;
|
||||
return node.type == NHRN.RESULT_TYPE_URI ||
|
||||
node.type == NHRN.RESULT_TYPE_VISIT ||
|
||||
node.type == NHRN.RESULT_TYPE_FULL_VISIT;
|
||||
},
|
||||
|
||||
/**
|
||||
@ -456,10 +460,10 @@ var PlacesController = {
|
||||
// Paste
|
||||
this._setEnabled("placesCmd_edit:paste", this._canPaste());
|
||||
// Open
|
||||
var hasSelectedURL = this._activeView.selectedURLNode != null;
|
||||
this._setEnabled("placesCmd_open", hasSelectedURL);
|
||||
this._setEnabled("placesCmd_open:window", hasSelectedURL);
|
||||
this._setEnabled("placesCmd_open:tab", hasSelectedURL);
|
||||
var hasSelectedURI = this._activeView.selectedURINode != null;
|
||||
this._setEnabled("placesCmd_open", hasSelectedURI);
|
||||
this._setEnabled("placesCmd_open:window", hasSelectedURI);
|
||||
this._setEnabled("placesCmd_open:tab", hasSelectedURI);
|
||||
|
||||
// We can open multiple links in tabs if there is either:
|
||||
// a) a single folder selected
|
||||
@ -469,7 +473,7 @@ var PlacesController = {
|
||||
this._setEnabled("placesCmd_open:tabs",
|
||||
singleFolderSelected || !hasSingleSelection);
|
||||
|
||||
var viewIsFolder = this.nodeIsFolder(this._activeView.getResult());
|
||||
var viewIsFolder = this.nodeIsFolder(this._activeView.getResult().root);
|
||||
// Persistent Sort
|
||||
this._setEnabled("placesCmd_sortby:name", viewIsFolder);
|
||||
// New Folder
|
||||
@ -499,19 +503,21 @@ var PlacesController = {
|
||||
var metadata = { mixed: true };
|
||||
|
||||
var hasSingleSelection = this._activeView.hasSingleSelection;
|
||||
if (this._activeView.selectedURLNode && hasSingleSelection)
|
||||
if (this._activeView.selectedURINode && hasSingleSelection)
|
||||
metadata["link"] = true;
|
||||
var selectedNode = this._activeView.selectedNode;
|
||||
if (this.nodeIsFolder(selectedNode) && hasSingleSelection)
|
||||
metadata["folder"] = true;
|
||||
if (this.nodeIsContainer(selectedNode) && hasSingleSelection)
|
||||
metadata["container"] = true;
|
||||
if (hasSingleSelection) {
|
||||
var selectedNode = this._activeView.selectedNode;
|
||||
if (this.nodeIsFolder(selectedNode))
|
||||
metadata["folder"] = true;
|
||||
if (this.nodeIsContainer(selectedNode))
|
||||
metadata["container"] = true;
|
||||
}
|
||||
|
||||
var foundNonLeaf = false;
|
||||
var nodes = this._activeView.getSelectionNodes();
|
||||
for (var i = 0; i < nodes.length; ++i) {
|
||||
var node = nodes[i];
|
||||
if (node.type != Ci.nsINavHistoryResultNode.RESULT_TYPE_URL)
|
||||
if (node.type != Ci.nsINavHistoryResultNode.RESULT_TYPE_URI)
|
||||
foundNonLeaf = true;
|
||||
if (!node.readonly && node.folderType == "")
|
||||
metadata["mutable"] = true;
|
||||
@ -617,27 +623,30 @@ var PlacesController = {
|
||||
* Loads the selected URL in a new tab.
|
||||
*/
|
||||
openLinkInNewTab: function PC_openLinkInNewTab() {
|
||||
var node = this._activeView.selectedURLNode;
|
||||
var node = this._activeView.selectedURINode;
|
||||
if (node)
|
||||
this._activeView.browserWindow.openNewTabWith(node.url, null, null);
|
||||
this._activeView.browserWindow.openNewTabWith(
|
||||
node.QueryInterface(Ci.nsINavHistoryURIResultNode).uri, null, null);
|
||||
},
|
||||
|
||||
/**
|
||||
* Loads the selected URL in a new window.
|
||||
*/
|
||||
openLinkInNewWindow: function PC_openLinkInNewWindow() {
|
||||
var node = this._activeView.selectedURLNode;
|
||||
var node = this._activeView.selectedURINode;
|
||||
if (node)
|
||||
this._activeView.browserWindow.openNewWindowWith(node.url, null, null);
|
||||
this._activeView.browserWindow.openNewWindowWith(
|
||||
node.QueryInterface(Ci.nsINavHistoryURIResultNode).uri, null, null);
|
||||
},
|
||||
|
||||
/**
|
||||
* Loads the selected URL in the current window, replacing the Places page.
|
||||
*/
|
||||
openLinkInCurrentWindow: function PC_openLinkInCurrentWindow() {
|
||||
var node = this._activeView.selectedURLNode;
|
||||
var node = this._activeView.selectedURINode;
|
||||
if (node)
|
||||
this._activeView.browserWindow.loadURI(node.url, null, null);
|
||||
this._activeView.browserWindow.loadURI(
|
||||
node.QueryInterface(Ci.nsINavHistoryURIResultNode).uri, null, null);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -652,16 +661,19 @@ var PlacesController = {
|
||||
var cc = kids.childCount;
|
||||
for (var i = 0; i < cc; ++i) {
|
||||
var node = kids.getChild(i);
|
||||
if (this.nodeIsURL(node))
|
||||
this._activeView.browserWindow.openNewTabWith(node.url,
|
||||
null, null);
|
||||
if (this.nodeIsURI(node))
|
||||
this._activeView.browserWindow.openNewTabWith(
|
||||
node.QueryInterface(Ci.nsINavHistoryURIResultNode).uri,
|
||||
null, null);
|
||||
}
|
||||
}
|
||||
else {
|
||||
var nodes = this._activeView.getSelectionNodes();
|
||||
for (var i = 0; i < nodes.length; ++i) {
|
||||
if (this.nodeIsURL(nodes[i]))
|
||||
this._activeView.browserWindow.openNewTabWith(nodes[i].url, null, null);
|
||||
if (this.nodeIsURI(nodes[i]))
|
||||
this._activeView.browserWindow.openNewTabWith(
|
||||
nodes[i].QueryInterface(Ci.nsINavHistoryURIResultNode).uri,
|
||||
null, null);
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -683,8 +695,9 @@ var PlacesController = {
|
||||
if (!this._groupableView)
|
||||
return;
|
||||
var result = this._groupableView.getResult();
|
||||
var queries = result.getQueries({ });
|
||||
var newOptions = result.queryOptions.clone();
|
||||
var root = result.root.QueryInterface(Ci.nsINavHistoryQueryResultNode);
|
||||
var queries = root.getQueries({ });
|
||||
var newOptions = root.queryOptions.clone();
|
||||
|
||||
// Update the grouping mode only after persisting, so that the URI is not
|
||||
// changed.
|
||||
@ -753,36 +766,41 @@ var PlacesController = {
|
||||
remove: function PC_remove(txnName) {
|
||||
var nodes = this._activeView.getSelectionNodes();
|
||||
this._activeView.saveSelection();
|
||||
if (this._activeView.isBookmarks) {
|
||||
// delete bookmarks
|
||||
var txns = [];
|
||||
for (var i = 0; i < nodes.length; ++i) {
|
||||
var node = nodes[i];
|
||||
var index = this.getIndexOfNode(node);
|
||||
if (this.nodeIsFolder(node)) {
|
||||
txns.push(new PlacesRemoveFolderTransaction(node.folderId,
|
||||
node.parent.folderId,
|
||||
index));
|
||||
}
|
||||
else {
|
||||
txns.push(new PlacesRemoveItemTransaction(this._uri(node.url),
|
||||
node.parent.folderId,
|
||||
|
||||
// delete bookmarks
|
||||
var txns = [];
|
||||
for (var i = 0; i < nodes.length; ++i) {
|
||||
var node = nodes[i];
|
||||
var index = this.getIndexOfNode(node);
|
||||
if (this.nodeIsFolder(node)) {
|
||||
txns.push(new PlacesRemoveFolderTransaction(node.folderId,
|
||||
node.parent.folderId,
|
||||
index));
|
||||
}
|
||||
else if (this.nodeIsFolder(node.parent)) {
|
||||
// this item is in a bookmark folder
|
||||
txns.push(new PlacesRemoveItemTransaction(this._uri(node.QueryInterface(Ci.nsINavHistoryURIResultNode).uri),
|
||||
node.parent.folderId,
|
||||
index));
|
||||
}
|
||||
else {
|
||||
// other containers are history queries, just delete from history
|
||||
// history deletes are not undoable.
|
||||
var hist = Cc["@mozilla.org/browser/nav-history-service;1"].
|
||||
getService(Ci.nsIBrowserHistory);
|
||||
for (var i = 0; i < nodes.length; ++i) {
|
||||
var node = nodes[i];
|
||||
if (this.nodeIsHost(node)) {
|
||||
hist.removePagesFromHost(node.title, true);
|
||||
} else if (this.nodeIsURI(node)) {
|
||||
hist.removePage(this._uri(node.QueryInterface(Ci.nsINavHistoryURIResultNode).uri));
|
||||
}
|
||||
}
|
||||
}
|
||||
var txn = new PlacesAggregateTransaction(txnName || "RemoveItems", txns);
|
||||
this._hist.transactionManager.doTransaction(txn);
|
||||
} else {
|
||||
// delete history items: these are unfortunately not undoable.
|
||||
var hist = Cc["@mozilla.org/browser/nav-history-service;1"].
|
||||
getService(Ci.nsIBrowserHistory);
|
||||
for (var i = 0; i < nodes.length; ++i) {
|
||||
var node = nodes[i];
|
||||
if (this.nodeIsHost(node)) {
|
||||
hist.removePagesFromHost(node.title, true);
|
||||
} else {
|
||||
hist.removePage(this._uri(node.url));
|
||||
}
|
||||
|
||||
if (txns.length > 0) {
|
||||
var txn = new PlacesAggregateTransaction(txnName || "RemoveItems", txns);
|
||||
this._hist.transactionManager.doTransaction(txn);
|
||||
}
|
||||
}
|
||||
this._activeView.restoreSelection();
|
||||
@ -817,14 +835,14 @@ var PlacesController = {
|
||||
switch (type) {
|
||||
case TYPE_X_MOZ_PLACE_CONTAINER:
|
||||
case TYPE_X_MOZ_PLACE:
|
||||
return node.folderId + "\n" + node.url + "\n" + node.parent.folderId + "\n" + this.getIndexOfNode(node);
|
||||
return node.folderId + "\n" + node.QueryInterface(Ci.nsINavHistoryURIResultNode).uri + "\n" + node.parent.folderId + "\n" + this.getIndexOfNode(node);
|
||||
case TYPE_X_MOZ_URL:
|
||||
return node.url + "\n" + node.title;
|
||||
return node.QueryInterface(Ci.nsINavHistoryURIResultNode).uri + "\n" + node.title;
|
||||
case TYPE_HTML:
|
||||
return "<A HREF=\"" + node.url + "\">" + node.title + "</A>";
|
||||
return "<A HREF=\"" + node.QueryInterface(Ci.nsINavHistoryURIResultNode).uri + "\">" + node.title + "</A>";
|
||||
}
|
||||
// case TYPE_UNICODE:
|
||||
return node.url;
|
||||
return node.QueryInterface(Ci.nsINavHistoryURIResultNode).uri;
|
||||
},
|
||||
|
||||
/**
|
||||
@ -904,15 +922,14 @@ var PlacesController = {
|
||||
transactions.push(createTxn);
|
||||
|
||||
// Get the folder's children
|
||||
var kids = self.getFolderContents(folderId,
|
||||
ViewConfig.GENERIC_FILTER_OPTIONS);
|
||||
var kids = self.getFolderContents(folderId, false, false);
|
||||
var cc = kids.childCount;
|
||||
for (var i = 0; i < cc; ++i) {
|
||||
var node = kids.getChild(i);
|
||||
if (self.nodeIsFolder(node))
|
||||
createTransactions(node.folderId, folderId, i);
|
||||
else {
|
||||
var uri = self._uri(node.url);
|
||||
else if (this.nodeIsURI(node)) {
|
||||
var uri = self._uri(node.QueryInterface(Ci.nsINavHistoryURIResultNode).uri);
|
||||
transactions.push(self._getItemCopyTransaction(uri, container,
|
||||
index));
|
||||
}
|
||||
@ -1145,7 +1162,7 @@ var PlacesControllerDragHelper = {
|
||||
*/
|
||||
canDrop: function PCDH_canDrop(view, orientation) {
|
||||
var result = view.getResult();
|
||||
if (result.readOnly || !PlacesController.nodeIsFolder(result))
|
||||
if (result.readOnly || !PlacesController.nodeIsFolder(result.root))
|
||||
return false;
|
||||
|
||||
var session = this._getSession();
|
||||
@ -1490,7 +1507,7 @@ PlacesEditItemTransaction.prototype = {
|
||||
selection flags
|
||||
|
||||
flags:
|
||||
SELECTION_CONTAINS_URL
|
||||
SELECTION_CONTAINS_URI
|
||||
SELECTION_CONTAINS_CONTAINER_OPEN
|
||||
SELECTION_CONTAINS_CONTAINER_CLOSED
|
||||
SELECTION_CONTAINS_CHANGEABLE
|
||||
|
@ -37,14 +37,6 @@
|
||||
// options.setExpandPlaces(); ?
|
||||
this._result = this._places.executeQuery(query, options);
|
||||
|
||||
// If this is a container, notify the service.
|
||||
if (PlacesController.nodeIsContainer(this._result)) {
|
||||
var serv = Cc[this._result.folderType]
|
||||
.getService(Ci.nsIBookmarksContainer);
|
||||
if (serv.onContainerOpening(this._result.folderId))
|
||||
this._result = this._places.executeQuery(query, options);
|
||||
}
|
||||
|
||||
this._rebuild();
|
||||
if (this.popupShowingCallback)
|
||||
this.popupShowingCallback();
|
||||
@ -92,15 +84,15 @@
|
||||
<body><![CDATA[
|
||||
this._cleanMenu();
|
||||
const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
var cc = this._result.childCount;
|
||||
var cc = this._result.root.childCount;
|
||||
if (cc > 0) {
|
||||
for (var i = 0; i < cc; ++i) {
|
||||
var child = this._result.getChild(i);
|
||||
var child = this._result.root.getChild(i);
|
||||
var element = null;
|
||||
if (PlacesController.nodeIsURL(child)) {
|
||||
if (PlacesController.nodeIsURI(child)) {
|
||||
element = document.createElementNS(XULNS, "menuitem");
|
||||
element.setAttribute("label", child.title);
|
||||
element.setAttribute("url", child.url);
|
||||
element.setAttribute("url", child.QueryInterface(nsINavHistoryURIResultNode).uri);
|
||||
element.setAttribute("statustext", child.url);
|
||||
element.setAttribute("image", child.icon.spec);
|
||||
element.className = "menuitem-iconic bookmark-item";
|
||||
@ -183,10 +175,10 @@
|
||||
]]></getter>
|
||||
</property>
|
||||
|
||||
<property name="selectedURLNode">
|
||||
<property name="selectedURINode">
|
||||
<getter><![CDATA[
|
||||
var node = this.selectedNode;
|
||||
return node && PlacesController.nodeIsURL(node) ? node : null;
|
||||
return node && PlacesController.nodeIsURI(node) ? node : null;
|
||||
]]></getter>
|
||||
</property>
|
||||
|
||||
@ -200,7 +192,7 @@
|
||||
if(PlacesController.nodeIsFolder(this.selectedNode))
|
||||
// If there is a folder selected, the insertion point is the
|
||||
// end of the folder.
|
||||
folderId = this.selectedNode.folderId;
|
||||
folderId = this.selectedNode.QueryInterface(Ci.nsINavHistoryFolderResultNode).folderId;
|
||||
else
|
||||
// If there is another type of node selected, the insertion point
|
||||
// is after that node.
|
||||
@ -249,7 +241,7 @@
|
||||
onItemChanged: function TB_O_onItemChanged(bookmark, property, value) {
|
||||
//this._self.init();
|
||||
},
|
||||
onItemVisited: function TB_0_onItemVisited(bookmark, time) {
|
||||
onItemVisited: function TB_0_onItemVisited(bookmark, visitId, time) {
|
||||
//this._self.init();
|
||||
},
|
||||
onItemReplaced: function TB_0_onItemReplaced(filder, item, newItem) {
|
||||
|
@ -175,12 +175,11 @@ var PlacesPage = {
|
||||
|
||||
this._places.init(new ViewConfig([TYPE_X_MOZ_PLACE_CONTAINER],
|
||||
ViewConfig.GENERIC_DROP_TYPES,
|
||||
Ci.nsINavHistoryQuery.INCLUDE_QUERIES,
|
||||
ViewConfig.GENERIC_FILTER_OPTIONS, 3));
|
||||
true, false, 3));
|
||||
this._content.init(new ViewConfig(ViewConfig.GENERIC_DROP_TYPES,
|
||||
ViewConfig.GENERIC_DROP_TYPES,
|
||||
ViewConfig.GENERIC_FILTER_OPTIONS, 0));
|
||||
|
||||
false, false, 0));
|
||||
|
||||
PlacesController.groupableView = this._content;
|
||||
|
||||
var GroupingSerializer = {
|
||||
@ -309,21 +308,24 @@ var PlacesPage = {
|
||||
var node = this._places.selectedNode;
|
||||
if (!node || this._places.suppressSelection)
|
||||
return;
|
||||
if (node.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER)
|
||||
node.QueryInterface(Ci.nsINavHistoryFolderResultNode);
|
||||
else if (node.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_QUERY)
|
||||
node.QueryInterface(Ci.nsINavHistoryQueryResultNode);
|
||||
else
|
||||
return; // should not get here
|
||||
var queries = node.getQueries({});
|
||||
var newQueries = [];
|
||||
for (var i = 0; i < queries.length; ++i) {
|
||||
var query = queries[i].clone();
|
||||
query.itemTypes |= this._content.filterOptions;
|
||||
newQueries.push(query);
|
||||
}
|
||||
var newOptions = node.queryOptions.clone();
|
||||
|
||||
var groupings = PlacesController.groupers.generic.value;
|
||||
var isBookmark = PlacesController.nodeIsFolder(node);
|
||||
if (isBookmark)
|
||||
groupings = PlacesController.groupers.bookmark.value;
|
||||
|
||||
newOptions.setGroupingMode(groupings, groupings.length);
|
||||
this._content.load(newQueries, newOptions);
|
||||
|
||||
this._setHeader("showing", node.title);
|
||||
@ -340,11 +342,19 @@ var PlacesPage = {
|
||||
calendar.suppressRangeEvents = true;
|
||||
|
||||
var result = this._content.getResult();
|
||||
var queries = result.getQueries({ });
|
||||
if (result.root.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_QUERY)
|
||||
result.root.QueryInterface(Ci.nsINavHistoryQueryResultNode);
|
||||
else if (result.root.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER)
|
||||
result.root.QueryInterface(Ci.nsINavHistoryFolderResultNode);
|
||||
else
|
||||
return;
|
||||
var queries = result.root.getQueries({ });
|
||||
if (!queries.length)
|
||||
return;
|
||||
|
||||
// Query values are OR'ed together, so just use the first.
|
||||
// Query values are OR'ed together, so just use the first.
|
||||
// FIXME: if there is more than one query, we probably do NOT want to
|
||||
// highlight the date range in the calendar.
|
||||
var query = queries[0];
|
||||
|
||||
const NOW = new Date();
|
||||
@ -868,8 +878,8 @@ var PlacesQueryBuilder = {
|
||||
result.queryOptions.maxResults = max;
|
||||
dump("Max results = " + result.queryOptions.maxResults + "(" + max + ")\n");
|
||||
}
|
||||
// Make sure we're getting url results, not visits
|
||||
result.queryOptions.resultType = result.queryOptions.RESULT_TYPE_URL;
|
||||
// Make sure we're getting uri results, not visits
|
||||
result.queryOptions.resultType = result.queryOptions.RESULT_TYPE_URI;
|
||||
|
||||
PlacesPage._content.load(queries, result.queryOptions);
|
||||
},
|
||||
|
@ -35,16 +35,6 @@
|
||||
var options = this._places.getNewQueryOptions();
|
||||
options.setGroupingMode([Ci.nsINavHistoryQueryOptions.GROUP_BY_FOLDER], 1);
|
||||
this._result = this._places.executeQuery(query, options);
|
||||
|
||||
// Check if the new query needs a show event.
|
||||
if (PlacesController.nodeIsContainer(this._result)) {
|
||||
var serv = Cc[this._result.folderType]
|
||||
.getService(Ci.nsIBookmarksContainer);
|
||||
if (serv.onContainerOpening(this._result.folderId))
|
||||
this._result = this._places.executeQueries(queries, queries.length,
|
||||
options);
|
||||
}
|
||||
|
||||
this._rebuild();
|
||||
]]></body>
|
||||
</method>
|
||||
@ -66,13 +56,14 @@
|
||||
while (this.hasChildNodes())
|
||||
this.removeChild(this.firstChild);
|
||||
const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
var cc = this._result.childCount;
|
||||
var cc = this._result.root.childCount;
|
||||
for (var i = 0; i < cc; ++i) {
|
||||
var child = this._result.getChild(i);
|
||||
var child = this._result.root.getChild(i);
|
||||
var button = document.createElementNS(XULNS, "toolbarbutton");
|
||||
button.setAttribute("label", child.title);
|
||||
if (PlacesController.nodeIsURL(child)) {
|
||||
button.setAttribute("url", child.url);
|
||||
if (PlacesController.nodeIsURI(child)) {
|
||||
child = child.QueryInterface(Ci.nsINavHistoryURIResultNode);
|
||||
button.setAttribute("url", child.uri);
|
||||
button.setAttribute("image", child.icon.spec);
|
||||
} else if (PlacesController.nodeIsFolder(child)) {
|
||||
button.setAttribute("type", "menu");
|
||||
@ -106,7 +97,7 @@
|
||||
// This is set here and not in the XBL constructor for the menu because
|
||||
// it doesn't get initialized properly in the constructor.
|
||||
popup.setAttribute("context", "placesContext");
|
||||
popup.folderId = this._result.folderId;
|
||||
popup.folderId = this._result.root.QueryInterface(Ci.nsINavHistoryFolderResultNode).folderId;
|
||||
var t = this;
|
||||
popup.popupShowingCallback = function() {t.chevronPopupShowing();};
|
||||
this._chevron.appendChild(popup);
|
||||
@ -170,24 +161,8 @@
|
||||
<parameter name="queries"/>
|
||||
<parameter name="options"/>
|
||||
<body><![CDATA[
|
||||
// Check if the old query needs a hidden event.
|
||||
if (PlacesController.nodeIsContainer(this._result)) {
|
||||
var serv = Cc[this._result.folderType]
|
||||
.getService(Ci.nsIBookmarksContainer);
|
||||
serv.onContainerClosed(this._result.folderId);
|
||||
}
|
||||
|
||||
this._result = this._places.executeQueries(queries, queries.length,
|
||||
options);
|
||||
|
||||
// Check if the new query needs a show event.
|
||||
if (PlacesController.nodeIsContainer(this._result)) {
|
||||
var serv = Cc[this._result.folderType]
|
||||
.getService(Ci.nsIBookmarksContainer);
|
||||
if (serv.onContainerOpening(this._result.folderId))
|
||||
this._result = this._places.executeQueries(queries, queries.length,
|
||||
options);
|
||||
}
|
||||
this._rebuild();
|
||||
]]></body>
|
||||
</method>
|
||||
@ -228,10 +203,10 @@
|
||||
]]></getter>
|
||||
</property>
|
||||
|
||||
<property name="selectedURLNode">
|
||||
<property name="selectedURINode">
|
||||
<getter><![CDATA[
|
||||
var node = this.selectedNode;
|
||||
return node && PlacesController.nodeIsURL(node) ? node : null;
|
||||
return node && PlacesController.nodeIsURI(node) ? node : null;
|
||||
]]></getter>
|
||||
</property>
|
||||
|
||||
@ -239,7 +214,7 @@
|
||||
<getter><![CDATA[
|
||||
// By default, the insertion point is at the top level, at the end.
|
||||
var index = -1;
|
||||
var folderId = this._result.folderId;
|
||||
var folderId = this._result.root.QueryInterface(nsINavHistoryFolderResultNode).folderId;
|
||||
|
||||
if (this.hasSelection) {
|
||||
if(PlacesController.nodeIsFolder(this.selectedNode))
|
||||
@ -298,7 +273,7 @@
|
||||
if (!this._numBatches)
|
||||
this._self.init();
|
||||
},
|
||||
onItemVisited: function TB_0_onItemVisited(bookmark, time) {
|
||||
onItemVisited: function TB_0_onItemVisited(bookmark, visitId, time) {
|
||||
//this._self.init();
|
||||
},
|
||||
onItemReplaced: function TB_0_onItemReplaced(filder, item, newItem) {
|
||||
|
@ -30,7 +30,7 @@
|
||||
<body><![CDATA[
|
||||
this.supportedDropTypes = viewConfig.dropTypes;
|
||||
this.supportedDropOnTypes = viewConfig.dropOnTypes;
|
||||
this.filterOptions = viewConfig.filterOptions;
|
||||
this.excludeItems = viewConfig.excludeItems;
|
||||
this.firstDropIndex = viewConfig.firstDropIndex;
|
||||
]]></body>
|
||||
</method>
|
||||
@ -150,11 +150,11 @@
|
||||
<body><![CDATA[
|
||||
var query = this._places.getNewQuery();
|
||||
query.setFolders([folderId], 1);
|
||||
query.itemTypes = this.filterOptions;
|
||||
|
||||
|
||||
var options = this._places.getNewQueryOptions();
|
||||
options.setGroupingMode([Ci.nsINavHistoryQueryOptions.GROUP_BY_FOLDER], 1);
|
||||
// options.setExpandPlaces(); ???
|
||||
options.excludeItems = this.excludeItems;
|
||||
options.expandQueries = false;
|
||||
var result = this._places.executeQuery(query, options);
|
||||
result.QueryInterface(Ci.nsITreeView);
|
||||
this.view = result;
|
||||
@ -166,6 +166,9 @@
|
||||
<parameter name="queries"/>
|
||||
<parameter name="options"/>
|
||||
<body><![CDATA[
|
||||
// override with our local options
|
||||
options.excludeItems = this.excludeItems;
|
||||
options.expandQueries = false;
|
||||
var result = this._places.executeQueries(queries, queries.length,
|
||||
options);
|
||||
result.QueryInterface(Ci.nsITreeView);
|
||||
@ -236,7 +239,7 @@
|
||||
</property>
|
||||
|
||||
<!-- AVI Method -->
|
||||
<property name="selectedURLNode">
|
||||
<property name="selectedURINode">
|
||||
<getter><![CDATA[
|
||||
var view = this.view;
|
||||
var selection = view.selection;
|
||||
@ -245,12 +248,12 @@
|
||||
return null;
|
||||
var min = { }, max = { };
|
||||
selection.getRangeAt(0, min, max);
|
||||
|
||||
// Cannot load containers
|
||||
if (view.isContainer(min.value) || view.isSeparator(min.value))
|
||||
return null;
|
||||
|
||||
return this.getResult().nodeForTreeIndex(min.value);
|
||||
|
||||
// only URI nodes should be returned
|
||||
var node = this.getResult().nodeForTreeIndex(min.value);
|
||||
if (PlacesController.nodeIsURI(node))
|
||||
return node.QueryInterface(Ci.nsINavHistoryURIResultNode);
|
||||
return null;
|
||||
]]></getter>
|
||||
</property>
|
||||
|
||||
@ -316,7 +319,7 @@
|
||||
<field name="supportedDropOnTypes">null</field>
|
||||
|
||||
<!-- AVI Method -->
|
||||
<field name="filterOptions">null</field>
|
||||
<field name="excludeQueries">null</field>
|
||||
|
||||
<!-- AVI Method -->
|
||||
<field name="dropOnFilterOptions">null</field>
|
||||
@ -372,17 +375,17 @@
|
||||
|
||||
<method name="_getInsertionNode">
|
||||
<parameter name="insertionPoint"/>
|
||||
<parameter name="filterOptions"/>
|
||||
<parameter name="excludeItems"/>
|
||||
<body><![CDATA[
|
||||
var result =
|
||||
PlacesController.getFolderContents(insertionPoint.folderId,
|
||||
filterOptions);
|
||||
PlacesController.getFolderContents(insertionPoint.folderId,
|
||||
excludeItems, false);
|
||||
var index = insertionPoint.index;
|
||||
if (insertionPoint.index == 0)
|
||||
index = 0;
|
||||
else if (insertionPoint.index == -1)
|
||||
index = result.childCount - 1;
|
||||
return index > -1 ? result.getChild(index) : null;
|
||||
return index > -1 ? result.root.getChild(index) : null;
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
@ -391,12 +394,12 @@
|
||||
<body><![CDATA[
|
||||
const NHRVO = Ci.nsINavHistoryResultViewObserver;
|
||||
// Insert index of insertion and number of rows to insert
|
||||
var filterOptions = this.filterOptions;
|
||||
var excludeItems = this.excludeItems;
|
||||
// This is a bit of a hack. Assume any container you drop into is
|
||||
// itself showing all item types, not just folders or items.
|
||||
if (insertionPoint.orientation == NHRVO.DROP_ON)
|
||||
filterOptions = ViewConfig.GENERIC_FILTER_OPTIONS;
|
||||
var node = this._getInsertionNode(insertionPoint, filterOptions);
|
||||
excludeItems = false;
|
||||
var node = this._getInsertionNode(insertionPoint, excludeItems);
|
||||
// This is the insertion index of the pivot.
|
||||
return this.getResult().treeIndexForNode(node);
|
||||
]]></body>
|
||||
@ -485,23 +488,7 @@
|
||||
visibleInsertCount);
|
||||
},
|
||||
|
||||
onToggleOpenState: function VO_onToggleOpenState(index) {
|
||||
// Alert containers about the toggle
|
||||
var result = this._self.getResult();
|
||||
var node = result.nodeForTreeIndex(index);
|
||||
if (PlacesController.nodeIsContainer(node)) {
|
||||
var serv = Cc[node.folderType].getService(Ci.nsIBookmarksContainer);
|
||||
// This notification happens before the container is actually
|
||||
// opened or closed, so the open state is the opposite of what
|
||||
// we're notifying.
|
||||
if (this._self.view.isContainerOpen(index)) {
|
||||
serv.onContainerClosed(node.folderId);
|
||||
} else {
|
||||
if (serv.onContainerOpening(node.folderId))
|
||||
this._self.loadFolder(node.folderId);
|
||||
}
|
||||
}
|
||||
},
|
||||
onToggleOpenState: function VO_onToggleOpenState(index) { },
|
||||
onSelectionChanged: function VO_onSelectionChanged() { },
|
||||
onCycleHeader: function VO_onCycleHeader(column) { },
|
||||
onCycleCell: function VO_onCycleCell(row, column) { },
|
||||
|
@ -14,9 +14,10 @@ browser.jar:
|
||||
|
||||
classic.jar:
|
||||
skin/classic/browser/places/places.css (skin-win/places.css)
|
||||
skin/classic/browser/places/icons.png (skin-win/icons.png)
|
||||
skin/classic/browser/places/default_favicon.png (skin-win/default_favicon.png)
|
||||
skin/classic/browser/places/query.png (skin-win/query.png)
|
||||
skin/classic/browser/places/bookmarks_menu.png (skin-win/bookmarks_menu.png)
|
||||
skin/classic/browser/places/bookmarks_toolbar.png (skin-win/bookmarks_toolbar.png)
|
||||
|
||||
en-US.jar:
|
||||
locale/browser/places/places.dtd (locale/places.dtd)
|
||||
|
@ -49,9 +49,9 @@ interface nsIFaviconService : nsISupports
|
||||
* You needn't have specified any data at this point. An entry linking the
|
||||
* favicon with the page will be create with no data. You can populate it
|
||||
* later with SetFaviconData. However, any favicons not associated with a
|
||||
* visited web page or bookmark will be expired when history cleanup is done
|
||||
* (typically at app shutdown, but also possibly if the user clears their
|
||||
* cache or history).
|
||||
* visited web page, a bookmark, or a "place:" URI will be expired when
|
||||
* history cleanup is done * (typically at app shutdown, but also possibly
|
||||
* if the user clears their * cache or history).
|
||||
*
|
||||
* This will send out history notifications if the new favicon has any data.
|
||||
* This means that you should try to set data first if you have it, otherwise
|
||||
@ -99,10 +99,10 @@ interface nsIFaviconService : nsISupports
|
||||
*
|
||||
* You can set the data even if you haven't called SetFaviconUrlForPage
|
||||
* yet. It will be stored but will not be associated with any page.
|
||||
* However, any favicons not associated with a visited web page or bookmark
|
||||
* will be expired when history cleanup is done (typically at app shutdown,
|
||||
* but also possibly if the user clears their cache or history). It is best
|
||||
* to call this function first for notification purposes.
|
||||
* However, any favicons not associated with a visited web page, bookmark,
|
||||
* or "place:" URI will be expired when history cleanup is done (typically
|
||||
* at app shutdown, but also possibly if the user clears their cache or
|
||||
* history). It is best to call this function first for notification purposes.
|
||||
*
|
||||
* The expiration time is stored. This will be used if you call
|
||||
* SetAndLoadFaviconForPage to see whether the data needs reloading.
|
||||
|
@ -39,7 +39,6 @@
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIURI;
|
||||
interface nsINavHistoryResult;
|
||||
|
||||
/**
|
||||
* Observer for bookmark changes.
|
||||
@ -117,7 +116,7 @@ interface nsINavBookmarkObserver : nsISupports
|
||||
* @see onItemChanged properth = "cleartime" for when all visit dates are
|
||||
* deleted for the URI.
|
||||
*/
|
||||
void onItemVisited(in nsIURI bookmark, in PRTime time);
|
||||
void onItemVisited(in nsIURI bookmark, in PRInt64 aVisitID, in PRTime time);
|
||||
|
||||
/**
|
||||
* Notify this observer that a bookmark has been replaced.
|
||||
@ -294,7 +293,12 @@ interface nsINavBookmarksService : nsISupports
|
||||
AString getFolderTitle(in PRInt64 folder);
|
||||
|
||||
/**
|
||||
* Get the place: url for a bookmark folder.
|
||||
* Get the place: url for a bookmark folder. You can use this value to
|
||||
* get/set the icon for a folder or to associate other data with it using
|
||||
* the annotation service. Its important that you use this function instead
|
||||
* of just serializing the query/options for a given folder because you
|
||||
* may have different options or query parameters. This function will give
|
||||
* the canonical value.
|
||||
* @param folder The folder whose URI should be retrieved
|
||||
* @returns The URI for the folder
|
||||
*/
|
||||
@ -316,8 +320,8 @@ interface nsINavBookmarksService : nsISupports
|
||||
/**
|
||||
* Returns the list of folder ids that contain the given URI.
|
||||
*/
|
||||
void getBookmarkCategories(in nsIURI uri, out PRUint32 count,
|
||||
[array, retval, size_is(count)] out PRInt64 categories);
|
||||
void getBookmarkFolders(in nsIURI uri, out PRUint32 count,
|
||||
[array, retval, size_is(count)] out PRInt64 folders);
|
||||
|
||||
/**
|
||||
* Returns the index of the given item in the given folder.
|
||||
|
@ -40,11 +40,13 @@
|
||||
#include "nsIArray.idl"
|
||||
#include "nsIURI.idl"
|
||||
|
||||
interface nsIFile;
|
||||
interface nsINavHistoryContainerResultNode;
|
||||
interface nsINavHistoryQuery;
|
||||
interface nsINavHistoryQueryOptions;
|
||||
interface nsITransactionManager;
|
||||
interface nsITreeColumn;
|
||||
interface nsIFile;
|
||||
interface nsIWritablePropertyBag;
|
||||
|
||||
[scriptable, uuid(acae2b2d-5fcd-4419-b1bc-b7dc92a1836c)]
|
||||
interface nsINavHistoryResultNode : nsISupports
|
||||
@ -53,37 +55,201 @@ interface nsINavHistoryResultNode : nsISupports
|
||||
* Indentifies the parent result node in the result set. This is null for
|
||||
* top level nodes.
|
||||
*/
|
||||
readonly attribute nsINavHistoryResultNode parent;
|
||||
readonly attribute nsINavHistoryContainerResultNode parent;
|
||||
|
||||
/**
|
||||
* Identifies the type of this node.
|
||||
*/
|
||||
const PRUint32 RESULT_TYPE_URL = 0;
|
||||
const PRUint32 RESULT_TYPE_URI = 0;
|
||||
const PRUint32 RESULT_TYPE_VISIT = 1;
|
||||
const PRUint32 RESULT_TYPE_HOST = 2;
|
||||
const PRUint32 RESULT_TYPE_DAY = 3;
|
||||
const PRUint32 RESULT_TYPE_QUERY = 4;
|
||||
const PRUint32 RESULT_TYPE_FULL_VISIT = 2;
|
||||
const PRUint32 RESULT_TYPE_HOST = 3;
|
||||
const PRUint32 RESULT_TYPE_DAY = 4;
|
||||
const PRUint32 RESULT_TYPE_QUERY = 5;
|
||||
const PRUint32 RESULT_TYPE_FOLDER = 6;
|
||||
readonly attribute PRUint32 type;
|
||||
|
||||
/**
|
||||
* URL of the web page in question. Empty for all other types, including
|
||||
* Title of the web page, or of the node's grouping (day, host, folder, etc)
|
||||
*/
|
||||
readonly attribute AUTF8String title;
|
||||
|
||||
/**
|
||||
* Total number of times the URI has ever been accessed. For hosts, this
|
||||
* is the total of the children under it, NOT the total times the host has
|
||||
* been accessed (this would require an additional query, so is not given
|
||||
* by default when most of the time it is never needed).
|
||||
*/
|
||||
readonly attribute PRUint32 accessCount;
|
||||
|
||||
/**
|
||||
* This is the time the user accessed the page.
|
||||
*
|
||||
* If this is a visit, it is the exact time that the page visit occurred.
|
||||
*
|
||||
* If this is a URI, it is the most recent time that the URI was visited.
|
||||
* Even if you ask for all URIs for a given date range long ago, this might
|
||||
* contain today's date if the URI was visited today.
|
||||
*
|
||||
* For hosts, or other node types with children, this is the most recent
|
||||
* access time for any of the children.
|
||||
*
|
||||
* For days, this is midnight on the morning of the day in question in
|
||||
* UTC time.
|
||||
*/
|
||||
readonly attribute PRTime time;
|
||||
|
||||
/**
|
||||
* This URI can be used as an image source URI and will give you the favicon
|
||||
* for the page. It is *not* the URI of the favicon, but rather something
|
||||
* that will resolve to the actual image.
|
||||
*
|
||||
* In most cases, this is an annotation URI that will query the favicon
|
||||
* service. If the entry has no favicon, this is the chrome URI of the
|
||||
* default favicon. If the favicon originally lived in chrome, this will
|
||||
* be the original chrome URI of the icon.
|
||||
*/
|
||||
readonly attribute nsIURI icon;
|
||||
|
||||
/**
|
||||
* This is the number of levels between this node and the top of the
|
||||
* hierarchy. The members of result.children have indentLevel = 0, their
|
||||
* children have indentLevel = 1, etc.
|
||||
*/
|
||||
readonly attribute PRUint32 indentLevel;
|
||||
|
||||
/**
|
||||
* You can use this to associate temporary information with the result node.
|
||||
* This property bag is associated with the result node and is not persisted
|
||||
* in any way.
|
||||
*/
|
||||
readonly attribute nsIWritablePropertyBag propertyBag;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* This is a result node that includes a URI. Used for bookmark and URI
|
||||
* results, as well as a base class for visit information.
|
||||
*/
|
||||
[scriptable, uuid(b62daf70-936a-41f8-a57e-6d2a6598bca6)]
|
||||
interface nsINavHistoryURIResultNode : nsINavHistoryResultNode
|
||||
{
|
||||
/**
|
||||
* URI of the web page in question. Empty for all other types, including
|
||||
* hosts.
|
||||
*/
|
||||
readonly attribute AUTF8String url;
|
||||
readonly attribute AUTF8String uri;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* When you request RESULT_TYPE_VISIT from query options, you will get this
|
||||
* interface for each item, which includes the session ID so that we can
|
||||
* group items from the same session together.
|
||||
*/
|
||||
[scriptable, uuid(8e2c5a86-b33d-4fa6-944b-559af7e95fcd)]
|
||||
interface nsINavHistoryVisitResultNode : nsINavHistoryURIResultNode
|
||||
{
|
||||
/**
|
||||
* This indicates the session ID of the * visit. This is used for session
|
||||
* grouping when a tree view is sorted by date.
|
||||
*/
|
||||
readonly attribute PRInt64 sessionId;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* This structure will be returned when you request RESULT_TYPE_FULL_VISIT in
|
||||
* the query options. This includes uncommonly used information about each
|
||||
* visit.
|
||||
*/
|
||||
[scriptable, uuid(c49fd9d5-56e2-43eb-932c-f933f28cba85)]
|
||||
interface nsINavHistoryFullVisitResultNode : nsINavHistoryVisitResultNode
|
||||
{
|
||||
/**
|
||||
* This indicates the visit ID of the visit.
|
||||
*/
|
||||
readonly attribute PRInt64 visitId;
|
||||
|
||||
/**
|
||||
* ID of the folder corresponding to this node.
|
||||
* Only valid for RESULT_TYPE_QUERY nodes where exactly one folder
|
||||
* has been specified in the query. 0 in all other cases.
|
||||
* This indicates the referring visit ID of the visit. The referrer should
|
||||
* have the same sessionId.
|
||||
*/
|
||||
readonly attribute PRInt64 folderId;
|
||||
readonly attribute PRInt64 referringVisitId;
|
||||
|
||||
/**
|
||||
* Type of the folder corresponding to this node.
|
||||
* Only valid for RESULT_TYPE_QUERY nodes where exactly one folder
|
||||
* has been specified in the query. 0 in all other cases.
|
||||
* Indicates the transition type of the visit.
|
||||
* One of nsINavHistoryService.TRANSITION_*
|
||||
*/
|
||||
readonly attribute AString folderType;
|
||||
readonly attribute PRInt32 transitionType;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Base class for container results. This includes all types of groupings.
|
||||
* Bookmark folders and places queries will be QueryResultNodes which extends
|
||||
* these items.
|
||||
*/
|
||||
[scriptable, uuid(155757ea-482a-462e-9b14-70707d65afe3)]
|
||||
interface nsINavHistoryContainerResultNode : nsINavHistoryResultNode
|
||||
{
|
||||
|
||||
/**
|
||||
* Set this to allow descent into the container. When closed, attempting
|
||||
* to call getChildren or childCount will result in an error. You should
|
||||
* set this to false when you are done reading.
|
||||
*
|
||||
* For HOST and DAY groupings, doing this is free since the children have
|
||||
* been precomputed. For queries and bookmark folders, being open means they
|
||||
* will keep themselves up-to-date by listening for updates and re-querying
|
||||
* as needed.
|
||||
*/
|
||||
attribute boolean containerOpen;
|
||||
|
||||
/**
|
||||
* This indicates whether this node "may" have children, and can be used
|
||||
* when the container is open or closed. When the container is closed, it
|
||||
* will give you an exact answer if the node can easily be populated (for
|
||||
* example, a bookmark folder). If not (for example, a complex history query),
|
||||
* it will return true. When the container is open, it will always be
|
||||
* accurate. It is intended to be used to see if we should draw the "+" next
|
||||
* to a tree item.
|
||||
*/
|
||||
readonly attribute boolean hasChildren;
|
||||
|
||||
/**
|
||||
* This gives you the children of the nodes. It is preferrable to use this
|
||||
* interface over the array one, since it avoids creating an nsIArray object
|
||||
* and the interface is already the correct type.
|
||||
*/
|
||||
readonly attribute PRUint32 childCount;
|
||||
nsINavHistoryResultNode getChild(in PRUint32 index);
|
||||
|
||||
/**
|
||||
* Returns false if this node's list of children can be modified
|
||||
* (adding or removing children, or reordering children), or true if
|
||||
* the UI should not allow the list of children to be modified.
|
||||
* This is false for bookmark folder nodes unless setFolderReadOnly() has
|
||||
* been called to override it, and true for non-folder nodes.
|
||||
*/
|
||||
readonly attribute boolean childrenReadOnly;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Used for places queries and as a base for bookmark folders.
|
||||
*
|
||||
* Note that if you request places to *not* be expanded in the options that
|
||||
* generated this node, this item will report it has no children and never try
|
||||
* to populate itself.
|
||||
*/
|
||||
[scriptable, uuid(dcd6a2b7-3d50-4c78-b1cb-2f0f18ac5864)]
|
||||
interface nsINavHistoryQueryResultNode : nsINavHistoryContainerResultNode
|
||||
{
|
||||
/**
|
||||
* A "place:" URI that encodes the query and options.
|
||||
*/
|
||||
readonly attribute nsIURI queryURI;
|
||||
|
||||
/**
|
||||
* Get the queries which build this node's children.
|
||||
@ -97,72 +263,23 @@ interface nsINavHistoryResultNode : nsISupports
|
||||
* Only valid for RESULT_TYPE_QUERY nodes.
|
||||
*/
|
||||
readonly attribute nsINavHistoryQueryOptions queryOptions;
|
||||
};
|
||||
|
||||
/**
|
||||
* Title of the web page, or of the node's grouping (day, host, folder, etc)
|
||||
*/
|
||||
readonly attribute AString title;
|
||||
|
||||
/**
|
||||
* Represents a bookmark folder (type == RESULT_TYPE_FOLDER). It derives from a
|
||||
* query result because it can provide a query that will result in the
|
||||
* contents.
|
||||
*/
|
||||
[scriptable, uuid(f3160bfe-ebb3-453b-b25e-19d0b9c425b1)]
|
||||
interface nsINavHistoryFolderResultNode : nsINavHistoryQueryResultNode
|
||||
{
|
||||
/**
|
||||
* Total number of times the URL has ever been accessed. For hosts, this
|
||||
* is the total of the children under it, NOT the total times the host has
|
||||
* been accessed (this would require an additional query, so is not given
|
||||
* by default when most of the time it is never needed).
|
||||
* ID of the folder corresponding to this node.
|
||||
* Only valid for RESULT_TYPE_QUERY nodes where exactly one folder
|
||||
* has been specified in the query. 0 in all other cases.
|
||||
*/
|
||||
readonly attribute PRInt32 accessCount;
|
||||
|
||||
/**
|
||||
* This is the time the user accessed the page.
|
||||
*
|
||||
* If this is a visit, it is the exact time that the page visit occurred.
|
||||
*
|
||||
* If this is a URL, it is the most recent time that the URL was visited.
|
||||
* Even if you ask for all URLs for a given date range long ago, this might
|
||||
* contain today's date if the URL was visited today.
|
||||
*
|
||||
* For hosts, or other node types with children, this is the most recent
|
||||
* access time for any of the children.
|
||||
*
|
||||
* For days, this is midnight on the morning of the day in question in
|
||||
* UTC time.
|
||||
*/
|
||||
readonly attribute PRTime time;
|
||||
|
||||
/**
|
||||
* This URI can be used as an image source URL and will give you the favicon
|
||||
* for the page. It is *not* the URL of the favicon, but rather something
|
||||
* that will resolve to the actual image.
|
||||
*
|
||||
* In most cases, this is an annotation URI that will query the favicon
|
||||
* service. If the entry has no favicon, this is the chrome URL of the
|
||||
* default favicon. If the favicon originally lived in chrome, this will
|
||||
* be the original chrome URI of the icon.
|
||||
*/
|
||||
readonly attribute nsIURI icon;
|
||||
|
||||
/**
|
||||
* This is the number of levels between this node and the top of the
|
||||
* hierarchy. The members of result.children have indentLevel = 0, their
|
||||
* children have indentLevel = 1, etc.
|
||||
*/
|
||||
readonly attribute PRInt32 indentLevel;
|
||||
|
||||
/**
|
||||
* This gives you the children of the nodes. It is preferrable to use this
|
||||
* interface over the array one, since it avoids creating an nsIArray object
|
||||
* and the interface is already the correct type.
|
||||
*/
|
||||
readonly attribute PRInt32 childCount;
|
||||
nsINavHistoryResultNode getChild(in PRInt32 index);
|
||||
|
||||
/**
|
||||
* Returns false if this node's list of children can be modified
|
||||
* (adding or removing children, or reordering children), or true if
|
||||
* the UI should not allow the list of children to be modified.
|
||||
* This is false for bookmark folder nodes unless setFolderReadOnly() has
|
||||
* been called to override it, and true for non-folder nodes.
|
||||
*/
|
||||
readonly attribute boolean childrenReadOnly;
|
||||
readonly attribute PRInt64 folderId;
|
||||
};
|
||||
|
||||
|
||||
@ -235,18 +352,19 @@ interface nsINavHistoryResultViewObserver : nsISupports
|
||||
/**
|
||||
* The result of a history/bookmark query.
|
||||
*
|
||||
* This class is also a result "node". Use those interfaces to access the
|
||||
* toplevel children of this result.
|
||||
* Use the "root" element to access the children of this query.
|
||||
*/
|
||||
|
||||
[scriptable, uuid(25b45a94-3323-4c7b-910a-315f2c59bfb4)]
|
||||
interface nsINavHistoryResult : nsINavHistoryResultNode
|
||||
interface nsINavHistoryResult : nsISupports
|
||||
{
|
||||
/**
|
||||
* Sorts all nodes recursively by the given parameter, one of
|
||||
* nsINavHistory.SORT_BY_*
|
||||
* nsINavHistory.SORT_BY_* This will update the corresponding options for
|
||||
* this result, so that re-using the current options/queries will always give
|
||||
* you the current view.
|
||||
*/
|
||||
void recursiveSort(in PRUint32 aSortingMode);
|
||||
void sortAll(in PRUint32 aSortingMode);
|
||||
|
||||
/**
|
||||
* Controls whether duplicate adjacent elements are collapsed into a single
|
||||
@ -254,18 +372,12 @@ interface nsINavHistoryResult : nsINavHistoryResultNode
|
||||
* things when you have selected to get visits. When you sort by date, the
|
||||
* multiple entries will then appear because they will be separated (unless
|
||||
* you clicked reload a bunch of times in a row). If you know you'll only
|
||||
* ever want one entry per site, you should ask for URLs back instead of
|
||||
* ever want one entry per site, you should ask for URIs back instead of
|
||||
* visits so it will be more efficient.
|
||||
* Default = true
|
||||
*/
|
||||
attribute boolean collapseDuplicates;
|
||||
|
||||
/**
|
||||
* Call these functions to expand or collapse all elements in the tree.
|
||||
*/
|
||||
void expandAll();
|
||||
void collapseAll();
|
||||
|
||||
/**
|
||||
* This allows you to get at the real node for a given row index in the tree.
|
||||
*/
|
||||
@ -293,6 +405,15 @@ interface nsINavHistoryResult : nsINavHistoryResultNode
|
||||
* Remove a tree builder observer.
|
||||
*/
|
||||
void removeObserver(in nsINavHistoryResultViewObserver observer);
|
||||
|
||||
/**
|
||||
* This is the root of the results. It will either be a
|
||||
* nsINavHistoryFolderResultNode (if the query is for bookmarks matching a
|
||||
* single folder) or just a nsINavHistoryQueryResultNode (for everything
|
||||
* else). The root node is open by default. Remember that you need to open
|
||||
* all other containers for their contents to be valid.
|
||||
*/
|
||||
readonly attribute nsINavHistoryQueryResultNode root;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -435,7 +556,8 @@ interface nsINavHistoryQuery : nsISupports
|
||||
readonly attribute boolean hasSearchTerms;
|
||||
|
||||
/**
|
||||
* When set, returns only bookmarked items, when unset, returns anything.
|
||||
* When set, returns only bookmarked items, when unset, returns anything. Setting this
|
||||
* is equivalent to listing all bookmark folders in the 'folders' parameter.
|
||||
*/
|
||||
attribute boolean onlyBookmarked;
|
||||
|
||||
@ -483,19 +605,6 @@ interface nsINavHistoryQuery : nsISupports
|
||||
void setFolders([const,array, size_is(folderCount)] in PRInt64 folders,
|
||||
in PRUint32 folderCount);
|
||||
|
||||
/**
|
||||
* Constants for itemTypes
|
||||
*/
|
||||
const PRUint32 INCLUDE_ITEMS = 1;
|
||||
const PRUint32 INCLUDE_QUERIES = 2;
|
||||
|
||||
/**
|
||||
* Filter the items returned. Takes a bitwise combination of INCLUDE_*
|
||||
* constants. Note that folders are only returned when a parent folder
|
||||
* is specified with setFolders().
|
||||
*/
|
||||
attribute PRUint32 itemTypes;
|
||||
|
||||
/**
|
||||
* Creates a new query item with the same parameters of this one.
|
||||
*/
|
||||
@ -554,21 +663,31 @@ interface nsINavHistoryQueryOptions : nsISupports
|
||||
const PRUint32 SORT_BY_TITLE_DESCENDING = 2;
|
||||
const PRUint32 SORT_BY_DATE_ASCENDING = 3;
|
||||
const PRUint32 SORT_BY_DATE_DESCENDING = 4;
|
||||
const PRUint32 SORT_BY_URL_ASCENDING = 5;
|
||||
const PRUint32 SORT_BY_URL_DESCENDING = 6;
|
||||
const PRUint32 SORT_BY_URI_ASCENDING = 5;
|
||||
const PRUint32 SORT_BY_URI_DESCENDING = 6;
|
||||
const PRUint32 SORT_BY_VISITCOUNT_ASCENDING = 7;
|
||||
const PRUint32 SORT_BY_VISITCOUNT_DESCENDING = 8;
|
||||
|
||||
/**
|
||||
* "URL" results, one for each URL visited in the range.
|
||||
* "URI" results, one for each URI visited in the range. Individual result
|
||||
* nodes will be of type "URI".
|
||||
*/
|
||||
const PRUint32 RESULT_TYPE_URL = 0;
|
||||
const PRUint32 RESULTS_AS_URI = 0;
|
||||
|
||||
/**
|
||||
* "Visit" results, with one for each time a page was visited
|
||||
* (this will often give you multiple results for one URL).
|
||||
* "Visit" results, with one for each time a page was visited (this will
|
||||
* often give you multiple results for one URI). Individual result nodes will
|
||||
* have type "Visit"
|
||||
*/
|
||||
const PRUint32 RESULT_TYPE_VISIT = 1;
|
||||
const PRUint32 RESULTS_AS_VISIT = 1;
|
||||
|
||||
/**
|
||||
* This is identical to RESULT_TYPE_VISIT except that individual result nodes
|
||||
* will have type "FullVisit". This is used for the attributes that are not
|
||||
* commonly accessed to save space in the common case (the lists can be very
|
||||
* long).
|
||||
*/
|
||||
const PRUint32 RESULTS_AS_FULL_VISIT = 2;
|
||||
|
||||
/**
|
||||
* The grouping mode to be used for this query.
|
||||
@ -591,22 +710,39 @@ interface nsINavHistoryQueryOptions : nsISupports
|
||||
attribute PRUint32 sortingMode;
|
||||
|
||||
/**
|
||||
* Sets the result type. One of RESULT_TYPE_*.
|
||||
* Sets the result type. One of RESULT_TYPE_* which includes how URIs are
|
||||
* represented.
|
||||
*/
|
||||
attribute PRUint32 resultType;
|
||||
|
||||
/**
|
||||
* This option excludes all URIs from a bookmarks query. This would be used
|
||||
* if you just wanted a list of bookmark folders and queries (such as the left
|
||||
* pane of the places page). Ignored for queries over history.
|
||||
* Defaults to false.
|
||||
*/
|
||||
attribute boolean excludeItems;
|
||||
|
||||
/**
|
||||
* Set to true to exclude queries ("place:" URIs) from the query results.
|
||||
* Simple folder queries (bookmark folder symlinks) will still be included.
|
||||
* Defaults to false.
|
||||
*/
|
||||
attribute boolean excludeQueries;
|
||||
|
||||
/**
|
||||
* When set, allows items with "place:" URIs to appear as containers,
|
||||
* with the container's contents filled in from the stored query.
|
||||
* If not set, these will appear as normal items.
|
||||
* If not set, these will appear as normal items. Doesn't do anything if
|
||||
* excludeQueries is set. Defaults to false.
|
||||
*/
|
||||
attribute boolean expandPlaces;
|
||||
attribute boolean expandQueries;
|
||||
|
||||
/**
|
||||
* Normally the title of a result will be the user's custom title if there is
|
||||
* one, falling back on the default page title. If this is set, we will not
|
||||
* do this operation and always use the original page title extracted from
|
||||
* the HTML of the page.
|
||||
* the HTML of the page. Defaults to false.
|
||||
*/
|
||||
attribute boolean forceOriginalTitle;
|
||||
|
||||
@ -615,7 +751,7 @@ interface nsINavHistoryQueryOptions : nsISupports
|
||||
* user sees in the URL bar are not hidden. Hidden things include the content
|
||||
* of iframes and all images on web pages. Normally, you don't want these
|
||||
* things. If you do, set this flag and you'll get all items, even hidden
|
||||
* ones.
|
||||
* ones. Does nothing for bookmark queries. Defaults to false.
|
||||
*/
|
||||
attribute boolean includeHidden;
|
||||
|
||||
@ -685,8 +821,8 @@ interface nsINavHistoryService : nsISupports
|
||||
|
||||
/**
|
||||
* This is just like markPageAsTyped (in nsIBrowserHistory, also implemented
|
||||
* by the history service), but for bookmarks. It declares that the given URL
|
||||
* is being opened as a result of following a bookmark. If this URL is loaded
|
||||
* by the history service), but for bookmarks. It declares that the given URI
|
||||
* is being opened as a result of following a bookmark. If this URI is loaded
|
||||
* soon after this message has been received, that transition will be marked
|
||||
* as following a bookmark.
|
||||
*/
|
||||
@ -715,7 +851,7 @@ interface nsINavHistoryService : nsISupports
|
||||
* @param aHidden Whether the page is hidden. If the page has only
|
||||
* TRANSITION_EMBED visits, this will be true, otherwise
|
||||
* false.
|
||||
* @param aTyped True if this URL has ever been typed.
|
||||
* @param aTyped True if this URI has ever been typed.
|
||||
*/
|
||||
void setPageDetails(in nsIURI aURI, in AString aTitle, in AString aUserTitle,
|
||||
in PRUint32 aVisitCount, in boolean aHidden,
|
||||
|
BIN
browser/components/places/skin-win/bookmarks_menu.png
Normal file
BIN
browser/components/places/skin-win/bookmarks_menu.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 200 B |
BIN
browser/components/places/skin-win/bookmarks_toolbar.png
Normal file
BIN
browser/components/places/skin-win/bookmarks_toolbar.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 224 B |
Binary file not shown.
Before Width: | Height: | Size: 331 B |
@ -54,18 +54,6 @@ treechildren::-moz-tree-image(title, open) {
|
||||
-moz-image-region: rect(16px, 32px, 32px, 16px);
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-image(title, container, menu-root),
|
||||
treechildren::-moz-tree-image(title, container, open, menu-root) {
|
||||
list-style-image: url("chrome://browser/skin/places/icons.png") !important;
|
||||
-moz-image-region: rect(0px, 16px, 17px, 0px);
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-image(title, container, toolbar-root),
|
||||
treechildren::-moz-tree-image(title, container, open, toolbar-root) {
|
||||
list-style-image: url("chrome://browser/skin/places/icons.png") !important;
|
||||
-moz-image-region: rect(17px, 16px, 32px, 0px);
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-row(session-start) {
|
||||
border-top:1px dotted ThreeDShadow;
|
||||
}
|
||||
|
@ -114,6 +114,9 @@ static NS_DEFINE_CID(kParserCID, NS_PARSER_CID);
|
||||
#define KEY_LASTCHARSET_LOWER "last_charset"
|
||||
#define KEY_ICON_LOWER "icon"
|
||||
|
||||
#define BOOKMARKS_MENU_ICON_URI "chrome://browser/skin/places/bookmarks_menu.png"
|
||||
#define BOOKMARKS_TOOLBAR_ICON_URI "chrome://browser/skin/places/bookmarks_toolbar.png"
|
||||
|
||||
static const char kWhitespace[] = " \r\n\t\b";
|
||||
|
||||
class BookmarkImportFrame
|
||||
@ -277,7 +280,8 @@ protected:
|
||||
nsresult NewFrame();
|
||||
nsresult PopFrame();
|
||||
|
||||
nsresult SetFaviconForURI(nsIURI* aURI, nsCString aData);
|
||||
nsresult SetFaviconForURI(nsIURI* aURI, const nsCString& aData);
|
||||
nsresult SetFaviconForFolder(PRInt64 aFolder, const nsACString& aFavicon);
|
||||
};
|
||||
|
||||
|
||||
@ -653,15 +657,19 @@ BookmarkContentSink::NewFrame()
|
||||
// menu root
|
||||
rv = mBookmarksService->GetBookmarksRoot(&ourID);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (mAllowRootChanges)
|
||||
if (mAllowRootChanges) {
|
||||
updateFolder = PR_TRUE;
|
||||
SetFaviconForFolder(ourID, NS_LITERAL_CSTRING(BOOKMARKS_MENU_ICON_URI));
|
||||
}
|
||||
break;
|
||||
case BookmarkImportFrame::Container_Toolbar:
|
||||
// toolbar root
|
||||
rv = mBookmarksService->GetToolbarRoot(&ourID);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (mAllowRootChanges)
|
||||
if (mAllowRootChanges) {
|
||||
updateFolder = PR_TRUE;
|
||||
SetFaviconForFolder(ourID, NS_LITERAL_CSTRING(BOOKMARKS_TOOLBAR_ICON_URI));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
NS_NOTREACHED("Unknown container type");
|
||||
@ -704,7 +712,7 @@ BookmarkContentSink::PopFrame()
|
||||
// should get expired when the page no longer references it.
|
||||
|
||||
nsresult
|
||||
BookmarkContentSink::SetFaviconForURI(nsIURI* aURI, nsCString aData)
|
||||
BookmarkContentSink::SetFaviconForURI(nsIURI* aURI, const nsCString& aData)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
@ -779,6 +787,33 @@ BookmarkContentSink::SetFaviconForURI(nsIURI* aURI, nsCString aData)
|
||||
}
|
||||
|
||||
|
||||
// BookmarkContentSink::SetFaviconForFolder
|
||||
//
|
||||
// This sets the given favicon URI for the given folder. It is used to
|
||||
// initialize the favicons for the bookmarks menu and toolbar. We don't
|
||||
// actually set any data here because we assume the URI is a chrome: URI.
|
||||
// These do not have to contain any data for them to work.
|
||||
|
||||
nsresult
|
||||
BookmarkContentSink::SetFaviconForFolder(PRInt64 aFolder,
|
||||
const nsACString& aFavicon)
|
||||
{
|
||||
nsFaviconService* faviconService = nsFaviconService::GetFaviconService();
|
||||
NS_ENSURE_TRUE(faviconService, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsCOMPtr<nsIURI> folderURI;
|
||||
nsresult rv = mBookmarksService->GetFolderURI(aFolder,
|
||||
getter_AddRefs(folderURI));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIURI> faviconURI;
|
||||
rv = NS_NewURI(getter_AddRefs(faviconURI), aFavicon);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return faviconService->SetFaviconUrlForPage(folderURI, faviconURI);
|
||||
}
|
||||
|
||||
|
||||
// SyncChannelStatus
|
||||
//
|
||||
// If a function returns an error, we need to set the channel status to be
|
||||
|
@ -156,7 +156,7 @@ nsNavBookmarks::Init()
|
||||
getter_AddRefs(mBundle));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// mDBFildURIBookmarks
|
||||
// mDBFindURIBookmarks
|
||||
rv = dbConn->CreateStatement(NS_LITERAL_CSTRING(
|
||||
"SELECT a.* "
|
||||
"FROM moz_bookmarks a, moz_history h "
|
||||
@ -1068,38 +1068,58 @@ nsNavBookmarks::GetFolderType(PRInt64 aFolder, nsAString &aType)
|
||||
return mDBGetFolderInfo->GetString(kGetFolderInfoIndex_Type, aType);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNavBookmarks::ResultNodeForFolder(PRInt64 aID,
|
||||
nsNavHistoryQueryOptions *aOptions,
|
||||
nsNavHistoryResultNode **aNode)
|
||||
{
|
||||
mozStorageStatementScoper scope(mDBGetFolderInfo);
|
||||
mDBGetFolderInfo->BindInt64Parameter(0, aID);
|
||||
|
||||
PRBool results;
|
||||
nsresult rv = mDBGetFolderInfo->ExecuteStep(&results);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ASSERTION(results, "ResultNodeForFolder expects a valid folder id");
|
||||
|
||||
// type (empty for normal ones, nonempty for container providers)
|
||||
nsCAutoString folderType;
|
||||
rv = mDBGetFolderInfo->GetUTF8String(kGetFolderInfoIndex_Type, folderType);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// title
|
||||
nsCAutoString title;
|
||||
rv = mDBGetFolderInfo->GetUTF8String(kGetFolderInfoIndex_Title, title);
|
||||
|
||||
if (folderType.IsEmpty()) {
|
||||
*aNode = new nsNavHistoryFolderResultNode(title, 0, 0, aOptions, aID);
|
||||
if (! *aNode)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(*aNode);
|
||||
} else {
|
||||
// a container API thing
|
||||
// FIXME(brettw)
|
||||
//NS_NOTREACHED("FIXME: Not implemented");
|
||||
*aNode = nsnull;
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNavBookmarks::GetFolderURI(PRInt64 aFolder, nsIURI **aURI)
|
||||
{
|
||||
// Create a query for the folder; the URI is the querystring
|
||||
// from that query.
|
||||
nsresult rv;
|
||||
nsNavHistory *history = History();
|
||||
nsCOMPtr<nsINavHistoryQuery> query;
|
||||
rv = history->GetNewQuery(getter_AddRefs(query));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = query->SetFolders(&aFolder, 1);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsINavHistoryQueryOptions> queryOptions;
|
||||
rv = history->GetNewQueryOptions(getter_AddRefs(queryOptions));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
PRUint32 groupByFolder = nsINavHistoryQueryOptions::GROUP_BY_FOLDER;
|
||||
rv = queryOptions->SetGroupingMode(&groupByFolder, 1);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCString folderURI;
|
||||
rv = history->QueriesToQueryString((nsINavHistoryQuery **)&query,
|
||||
1,
|
||||
queryOptions,
|
||||
folderURI);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Create a uri from the folder string.
|
||||
rv = NS_NewURI(aURI, folderURI);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
// Create a query for the folder; the URI is the querystring from that
|
||||
// query. We could create a proper query and serialize it, which might
|
||||
// make it less prone to breakage since we'd only have one code path.
|
||||
// However, this gets called a lot (every time we make a folder node)
|
||||
// and constructing fake queries and options each time just to
|
||||
// serialize them would be a waste. Therefore, we just synthesize the
|
||||
// correct string here.
|
||||
nsCAutoString spec("place:folders=");
|
||||
spec.AppendInt(aFolder);
|
||||
spec.AppendLiteral("&group=3"); // GROUP_BY_FOLDER
|
||||
return NS_NewURI(aURI, spec);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -1124,144 +1144,53 @@ nsNavBookmarks::GetFolderReadonly(PRInt64 aFolder, PRBool *aResult)
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNavBookmarks::ResultNodeForFolder(PRInt64 aID,
|
||||
nsINavHistoryQuery *aQuery,
|
||||
nsINavHistoryQueryOptions *aOptions,
|
||||
nsNavHistoryResultNode **aNode)
|
||||
{
|
||||
// Create Query and QueryOptions objects to generate this folder's children
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsINavHistoryQuery> query;
|
||||
rv = aQuery->Clone(getter_AddRefs(query));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
query->SetFolders(&aID, 1);
|
||||
|
||||
nsCOMPtr<nsINavHistoryQueryOptions> options;
|
||||
rv = aOptions->Clone(getter_AddRefs(options));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsRefPtr<nsNavHistoryQueryNode> node = new nsNavHistoryQueryNode();
|
||||
NS_ENSURE_TRUE(node, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
node->mType = nsINavHistoryResultNode::RESULT_TYPE_QUERY;
|
||||
node->mQueries = NS_STATIC_CAST(nsINavHistoryQuery**,
|
||||
nsMemory::Alloc(sizeof(nsINavHistoryQuery*)));
|
||||
NS_ENSURE_TRUE(node->mQueries, NS_ERROR_OUT_OF_MEMORY);
|
||||
node->mQueries[0] = nsnull;
|
||||
query.swap(node->mQueries[0]);
|
||||
node->mQueryCount = 1;
|
||||
node->mOptions = do_QueryInterface(options);
|
||||
|
||||
rv = FillFolderNode(aID, node);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
NS_ADDREF(*aNode = node);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNavBookmarks::FillFolderNode(PRInt64 aID,
|
||||
nsNavHistoryQueryNode *aNode)
|
||||
{
|
||||
mozStorageStatementScoper scope(mDBGetFolderInfo);
|
||||
mDBGetFolderInfo->BindInt64Parameter(0, aID);
|
||||
|
||||
PRBool results;
|
||||
nsresult rv = mDBGetFolderInfo->ExecuteStep(&results);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ASSERTION(results, "ResultNodeForFolder expects a valid folder id");
|
||||
|
||||
// Fill in the folder type
|
||||
// aNode->mFolderType should get set to the empty string
|
||||
// if the folder type is null.
|
||||
rv = mDBGetFolderInfo->GetString(kGetFolderInfoIndex_Type, aNode->mFolderType);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
// Fill in the folder title
|
||||
return mDBGetFolderInfo->GetString(kGetFolderInfoIndex_Title, aNode->mTitle);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNavBookmarks::QueryFolderChildren(nsINavHistoryQuery *aQuery,
|
||||
nsINavHistoryQueryOptions *aOptions,
|
||||
nsNavBookmarks::QueryFolderChildren(PRInt64 aFolderId,
|
||||
nsNavHistoryQueryOptions *aOptions,
|
||||
nsCOMArray<nsNavHistoryResultNode> *aChildren)
|
||||
{
|
||||
mozStorageTransaction transaction(DBConn(), PR_FALSE);
|
||||
|
||||
PRUint32 itemTypes;
|
||||
aQuery->GetItemTypes(&itemTypes);
|
||||
|
||||
PRBool includeQueries = (itemTypes & nsINavHistoryQuery::INCLUDE_QUERIES) != 0;
|
||||
PRBool includeItems = (itemTypes & nsINavHistoryQuery::INCLUDE_ITEMS) != 0;
|
||||
|
||||
nsresult rv;
|
||||
nsCOMArray<nsNavHistoryResultNode> folderChildren;
|
||||
{
|
||||
mozStorageStatementScoper scope(mDBGetChildren);
|
||||
mozStorageStatementScoper scope(mDBGetChildren);
|
||||
|
||||
PRInt64 *folders;
|
||||
PRUint32 folderCount;
|
||||
aQuery->GetFolders(&folderCount, &folders);
|
||||
NS_ASSERTION(folderCount == 1, "querying > 1 folder not yet implemented");
|
||||
rv = mDBGetChildren->BindInt64Parameter(0, aFolderId);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = mDBGetChildren->BindInt64Parameter(0, folders[0]);
|
||||
nsMemory::Free(folders);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = mDBGetChildren->BindInt32Parameter(1, 0);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = mDBGetChildren->BindInt32Parameter(1, 0);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = mDBGetChildren->BindInt32Parameter(2, PR_INT32_MAX);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = mDBGetChildren->BindInt32Parameter(2, PR_INT32_MAX);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRBool results;
|
||||
while (NS_SUCCEEDED(mDBGetChildren->ExecuteStep(&results)) && results) {
|
||||
PRBool isFolder = !mDBGetChildren->IsNull(kGetChildrenIndex_FolderChild);
|
||||
nsCOMPtr<nsNavHistoryResultNode> node;
|
||||
if (isFolder) {
|
||||
PRInt64 folder = mDBGetChildren->AsInt64(kGetChildrenIndex_FolderChild);
|
||||
rv = ResultNodeForFolder(folder, aQuery,
|
||||
aOptions, getter_AddRefs(node));
|
||||
} else {
|
||||
// need the concrete options for RowToResult
|
||||
nsCOMPtr<nsNavHistoryQueryOptions> options =
|
||||
do_QueryInterface(aOptions, &rv);
|
||||
rv = History()->RowToResult(mDBGetChildren, options,
|
||||
getter_AddRefs(node));
|
||||
PRBool isQuery = IsQueryURI(node->URL());
|
||||
if ((isQuery && !includeQueries) || (!isQuery && !includeItems)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
PRBool results;
|
||||
|
||||
nsCOMPtr<nsNavHistoryQueryOptions> options = do_QueryInterface(aOptions, &rv);
|
||||
while (NS_SUCCEEDED(mDBGetChildren->ExecuteStep(&results)) && results) {
|
||||
PRBool isFolder = !mDBGetChildren->IsNull(kGetChildrenIndex_FolderChild);
|
||||
nsCOMPtr<nsNavHistoryResultNode> node;
|
||||
if (isFolder) {
|
||||
PRInt64 folder = mDBGetChildren->AsInt64(kGetChildrenIndex_FolderChild);
|
||||
rv = ResultNodeForFolder(folder, aOptions, getter_AddRefs(node));
|
||||
if (NS_FAILED(rv))
|
||||
continue;
|
||||
} else {
|
||||
rv = History()->RowToResult(mDBGetChildren, options,
|
||||
getter_AddRefs(node));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (isFolder) {
|
||||
NS_ENSURE_TRUE(folderChildren.AppendObject(node),
|
||||
NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
PRUint32 nodeType;
|
||||
node->GetType(&nodeType);
|
||||
if ((nodeType == nsINavHistoryResultNode::RESULT_TYPE_QUERY &&
|
||||
aOptions->ExcludeQueries()) ||
|
||||
(nodeType != nsINavHistoryResultNode::RESULT_TYPE_QUERY &&
|
||||
nodeType != nsINavHistoryResultNode::RESULT_TYPE_FOLDER &&
|
||||
aOptions->ExcludeItems())) {
|
||||
continue;
|
||||
}
|
||||
NS_ENSURE_TRUE(aChildren->AppendObject(node), NS_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
NS_ENSURE_TRUE(aChildren->AppendObject(node), NS_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
// Now build children for any folder children we just created. This is
|
||||
// pretty cheap (only go down 1 level) and allows us to know whether
|
||||
// to draw a twisty.
|
||||
static PRBool queryingChildren = PR_FALSE;
|
||||
|
||||
if (!queryingChildren) {
|
||||
queryingChildren = PR_TRUE; // don't return before resetting to false
|
||||
for (PRInt32 i = 0; i < folderChildren.Count(); ++i) {
|
||||
PRBool built;
|
||||
rv = folderChildren[i]->BuildChildren(&built);
|
||||
if (NS_FAILED(rv)) {
|
||||
break;
|
||||
}
|
||||
NS_ASSERTION(built, "new folder should not have already built children");
|
||||
}
|
||||
queryingChildren = PR_FALSE;
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
return transaction.Commit();
|
||||
}
|
||||
|
||||
@ -1297,11 +1226,11 @@ nsNavBookmarks::IsBookmarked(nsIURI *aURI, PRBool *aBookmarked)
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNavBookmarks::GetBookmarkCategories(nsIURI *aURI, PRUint32 *aCount,
|
||||
PRInt64 **aCategories)
|
||||
nsNavBookmarks::GetBookmarkFolders(nsIURI *aURI, PRUint32 *aCount,
|
||||
PRInt64 **aFolders)
|
||||
{
|
||||
*aCount = 0;
|
||||
*aCategories = nsnull;
|
||||
*aFolders = nsnull;
|
||||
|
||||
mozStorageStatementScoper scope(mDBFindURIBookmarks);
|
||||
mozStorageTransaction transaction(DBConn(), PR_FALSE);
|
||||
@ -1309,34 +1238,25 @@ nsNavBookmarks::GetBookmarkCategories(nsIURI *aURI, PRUint32 *aCount,
|
||||
nsresult rv = BindStatementURI(mDBFindURIBookmarks, 0, aURI);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRUint32 arraySize = 8;
|
||||
PRInt64 *categories = NS_STATIC_CAST(PRInt64*,
|
||||
nsMemory::Alloc(arraySize * sizeof(PRInt64)));
|
||||
NS_ENSURE_TRUE(categories, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
PRUint32 count = 0;
|
||||
nsTArray<PRInt64> folders;
|
||||
PRBool more;
|
||||
|
||||
while (NS_SUCCEEDED((rv = mDBFindURIBookmarks->ExecuteStep(&more))) && more) {
|
||||
if (count >= arraySize) {
|
||||
arraySize <<= 1;
|
||||
PRInt64 *res = NS_STATIC_CAST(PRInt64*, nsMemory::Realloc(categories,
|
||||
arraySize * sizeof(PRInt64)));
|
||||
if (!res) {
|
||||
delete categories;
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
categories = res;
|
||||
}
|
||||
categories[count++] =
|
||||
mDBFindURIBookmarks->AsInt64(kFindBookmarksIndex_Parent);
|
||||
if (! folders.AppendElement(
|
||||
mDBFindURIBookmarks->AsInt64(kFindBookmarksIndex_Parent)))
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
*aCount = count;
|
||||
*aCategories = categories;
|
||||
|
||||
if (folders.Length()) {
|
||||
*aFolders = NS_STATIC_CAST(PRInt64*,
|
||||
nsMemory::Alloc(sizeof(PRInt64) * folders.Length()));
|
||||
if (! aFolders)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
for (PRUint32 i = 0; i < folders.Length(); i ++)
|
||||
(*aFolders)[i] = folders[i];
|
||||
}
|
||||
*aCount = folders.Length();
|
||||
return transaction.Commit();
|
||||
}
|
||||
|
||||
@ -1448,7 +1368,7 @@ nsNavBookmarks::OnVisit(nsIURI *aURI, PRInt64 aVisitID, PRTime aTime,
|
||||
IsBookmarked(aURI, &bookmarked);
|
||||
if (bookmarked) {
|
||||
ENUMERATE_WEAKARRAY(mObservers, nsINavBookmarkObserver,
|
||||
OnItemVisited(aURI, aTime))
|
||||
OnItemVisited(aURI, aVisitID, aTime))
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -65,24 +65,14 @@ public:
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
// Creates a new result node for the given folder.
|
||||
// The query and options are cloned, and the folder's id is set on the
|
||||
// new node's query.
|
||||
nsresult ResultNodeForFolder(PRInt64 aFolder,
|
||||
nsINavHistoryQuery *aQuery,
|
||||
nsINavHistoryQueryOptions *aOptions,
|
||||
nsresult ResultNodeForFolder(PRInt64 aID, nsNavHistoryQueryOptions *aOptions,
|
||||
nsNavHistoryResultNode **aNode);
|
||||
|
||||
// Fills in a ResultNode for the given folder.
|
||||
// The node's type and queries must already be set.
|
||||
nsresult FillFolderNode(PRInt64 aID,
|
||||
nsNavHistoryQueryNode *aNode);
|
||||
|
||||
// Find all the children of a folder, using the given query and options.
|
||||
// For each child, a ResultNode is created and added to |children|.
|
||||
// The results are ordered by folder position.
|
||||
nsresult QueryFolderChildren(nsINavHistoryQuery *aQuery,
|
||||
nsINavHistoryQueryOptions *aOptions,
|
||||
nsresult QueryFolderChildren(PRInt64 aFolderId,
|
||||
nsNavHistoryQueryOptions *aOptions,
|
||||
nsCOMArray<nsNavHistoryResultNode> *children);
|
||||
|
||||
// Returns a statement to get information about a folder id
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -54,6 +54,7 @@
|
||||
#include "nsIAutoCompleteSimpleResult.h"
|
||||
#include "nsIBrowserHistory.h"
|
||||
#include "nsICollation.h"
|
||||
#include "nsIDateTimeFormat.h"
|
||||
#include "nsIGlobalHistory.h"
|
||||
#include "nsIPrefService.h"
|
||||
#include "nsIPrefBranch.h"
|
||||
@ -80,13 +81,17 @@
|
||||
// Size of visit count boost to give to urls which are sites or paths
|
||||
#define AUTOCOMPLETE_NONPAGE_VISIT_COUNT_BOOST 5
|
||||
|
||||
#define QUERYUPDATE_TIME 0
|
||||
#define QUERYUPDATE_SIMPLE 1
|
||||
#define QUERYUPDATE_COMPLEX 2
|
||||
#define QUERYUPDATE_COMPLEX_WITH_BOOKMARKS 3
|
||||
|
||||
class AutoCompleteIntermediateResultSet;
|
||||
class mozIAnnotationService;
|
||||
class nsNavHistory;
|
||||
class nsNavBookmarks;
|
||||
class QueryKeyValuePair;
|
||||
|
||||
|
||||
// nsNavHistory
|
||||
|
||||
class nsNavHistory : public nsSupportsWeakReference,
|
||||
@ -144,8 +149,20 @@ public:
|
||||
return mDBConn;
|
||||
}
|
||||
|
||||
// remember tree state
|
||||
/**
|
||||
* These functions return non-owning references to the locale-specific
|
||||
* objects for places components. Guaranteed to return non-NULL.
|
||||
*/
|
||||
nsIStringBundle* GetBundle()
|
||||
{ return mBundle; }
|
||||
nsILocale* GetLocale()
|
||||
{ return mLocale; }
|
||||
nsICollation* GetCollation()
|
||||
{ return mCollation; }
|
||||
nsIDateTimeFormat* GetDateFormatter()
|
||||
{ return mDateFormatter; }
|
||||
|
||||
// remember tree state
|
||||
void SaveExpandItem(const nsAString& aTitle);
|
||||
void SaveCollapseItem(const nsAString& aTitle);
|
||||
|
||||
@ -181,27 +198,24 @@ public:
|
||||
static nsIAtom* sSessionStartAtom;
|
||||
static nsIAtom* sSessionContinueAtom;
|
||||
|
||||
// this actually executes a query and gives you results, it is used by
|
||||
// nsNavHistoryQueryResultNode
|
||||
nsresult GetQueryResults(const nsCOMArray<nsINavHistoryQuery>& aQueries,
|
||||
nsNavHistoryQueryOptions *aOptions,
|
||||
nsCOMArray<nsNavHistoryResultNode>* aResults);
|
||||
|
||||
// Take a row of kGetInfoIndex_* columns and construct a ResultNode.
|
||||
// The row must contain the full set of columns.
|
||||
nsresult RowToResult(mozIStorageValueArray* aRow,
|
||||
nsNavHistoryQueryOptions* aOptions,
|
||||
nsNavHistoryResultNode** aResult);
|
||||
|
||||
// Take a row of kGetInfoIndex_* columns and fill in an existing ResultNode.
|
||||
// The node's type must already be set, and the row must contain the full
|
||||
// set of columns.
|
||||
nsresult FillURLResult(mozIStorageValueArray* aRow,
|
||||
nsNavHistoryQueryOptions* aOptions,
|
||||
nsNavHistoryResultNode *aNode);
|
||||
|
||||
// Construct a new HistoryResult object. You can give it null query/options.
|
||||
nsNavHistoryResult* NewHistoryResult(nsINavHistoryQuery** aQueries,
|
||||
PRUint32 aQueryCount,
|
||||
nsNavHistoryQueryOptions* aOptions)
|
||||
{
|
||||
return new nsNavHistoryResult(this, mBundle, aQueries, aQueryCount,
|
||||
aOptions);
|
||||
}
|
||||
nsresult VisitIdToResultNode(PRInt64 visitId,
|
||||
nsNavHistoryQueryOptions* aOptions,
|
||||
nsNavHistoryResultNode** aResult);
|
||||
nsresult UriToResultNode(nsIURI* aUri,
|
||||
nsNavHistoryQueryOptions* aOptions,
|
||||
nsNavHistoryResultNode** aResult);
|
||||
|
||||
// used by other places components to send history notifications (for example,
|
||||
// when the favicon has changed)
|
||||
@ -218,6 +232,23 @@ public:
|
||||
// well-known annotations used by the history and bookmarks systems
|
||||
static const char kAnnotationPreviousEncoding[];
|
||||
|
||||
// used by query result nodes to update: see comment on body of CanLiveUpdateQuery
|
||||
static PRUint32 GetUpdateRequirements(nsCOMArray<nsINavHistoryQuery>* aQueries,
|
||||
nsNavHistoryQueryOptions* aOptions,
|
||||
PRBool* aHasSearchTerms);
|
||||
PRBool EvaluateQueryForNode(nsCOMArray<nsINavHistoryQuery>* aQueries,
|
||||
nsNavHistoryQueryOptions* aOptions,
|
||||
nsNavHistoryURIResultNode* aNode);
|
||||
|
||||
static nsresult AsciiHostNameFromHostString(const nsACString& aHostName,
|
||||
nsACString& aAscii);
|
||||
static void DomainNameFromHostName(const nsCString& aHostName,
|
||||
nsACString& aDomainName);
|
||||
static PRTime NormalizeTime(PRUint32 aRelative, PRTime aOffset);
|
||||
nsresult RecursiveGroup(const nsCOMArray<nsNavHistoryResultNode>& aSource,
|
||||
const PRUint32* aGroupingMode, PRUint32 aGroupCount,
|
||||
nsCOMArray<nsNavHistoryResultNode>* aDest);
|
||||
|
||||
private:
|
||||
~nsNavHistory();
|
||||
|
||||
@ -254,6 +285,11 @@ protected:
|
||||
nsCOMPtr<mozIStorageStatement> mDBRecentVisitOfURL; // converts URL into most recent visit ID/session ID
|
||||
nsCOMPtr<mozIStorageStatement> mDBInsertVisit; // used by AddVisit
|
||||
|
||||
// these are used by VisitIdToResultNode for making new result nodes from IDs
|
||||
nsCOMPtr<mozIStorageStatement> mDBVisitToURLResult; // kGetInfoIndex_* results
|
||||
nsCOMPtr<mozIStorageStatement> mDBVisitToVisitResult; // kGetInfoIndex_* results
|
||||
nsCOMPtr<mozIStorageStatement> mDBUrlToUrlResult; // kGetInfoIndex_* results
|
||||
|
||||
nsresult InitDB();
|
||||
|
||||
// this is the cache DB in memory used for storing visited URLs
|
||||
@ -282,7 +318,6 @@ protected:
|
||||
PRBool mNowValid;
|
||||
nsCOMPtr<nsITimer> mExpireNowTimer;
|
||||
static void expireNowTimerCallback(nsITimer* aTimer, void* aClosure);
|
||||
PRTime NormalizeTime(PRUint32 aRelative, PRTime aOffset);
|
||||
|
||||
nsresult QueryToSelectClause(nsINavHistoryQuery* aQuery,
|
||||
PRInt32 aStartParameter,
|
||||
@ -293,27 +328,19 @@ protected:
|
||||
nsINavHistoryQuery* aQuery,
|
||||
PRInt32* aParamCount);
|
||||
|
||||
nsresult FillSimpleBookmarksQuery(nsINavHistoryQuery** aQueries,
|
||||
PRUint32 aQueryCount,
|
||||
nsNavHistoryQueryOptions* aOptions,
|
||||
nsINavHistoryResult** _retval);
|
||||
nsresult ResultsAsList(mozIStorageStatement* statement,
|
||||
nsNavHistoryQueryOptions* aOptions,
|
||||
nsCOMArray<nsNavHistoryResultNode>* aResults);
|
||||
|
||||
void TitleForDomain(const nsString& domain, nsAString& aTitle);
|
||||
void TitleForDomain(const nsCString& domain, nsACString& aTitle);
|
||||
nsresult SetPageTitleInternal(nsIURI* aURI, PRBool aIsUserTitle,
|
||||
const nsAString& aTitle);
|
||||
|
||||
nsresult RecursiveGroup(const nsCOMArray<nsNavHistoryResultNode>& aSource,
|
||||
const PRUint32* aGroupingMode, PRUint32 aGroupCount,
|
||||
nsCOMArray<nsNavHistoryResultNode>* aDest);
|
||||
nsresult GroupByDay(const nsCOMArray<nsNavHistoryResultNode>& aSource,
|
||||
nsCOMArray<nsNavHistoryResultNode>* aDest);
|
||||
nsresult GroupByHost(const nsCOMArray<nsNavHistoryResultNode>& aSource,
|
||||
nsCOMArray<nsNavHistoryResultNode>* aDest);
|
||||
nsresult GroupByDomain(const nsCOMArray<nsNavHistoryResultNode>& aSource,
|
||||
nsCOMArray<nsNavHistoryResultNode>* aDest);
|
||||
nsCOMArray<nsNavHistoryResultNode>* aDest,
|
||||
PRBool aIsDomain);
|
||||
|
||||
nsresult FilterResultSet(const nsCOMArray<nsNavHistoryResultNode>& aSet,
|
||||
nsCOMArray<nsNavHistoryResultNode>* aFiltered,
|
||||
@ -323,8 +350,11 @@ protected:
|
||||
nsMaybeWeakPtrArray<nsINavHistoryObserver> mObservers;
|
||||
PRInt32 mBatchesInProgress;
|
||||
|
||||
// string bundles
|
||||
// localization
|
||||
nsCOMPtr<nsIStringBundle> mBundle;
|
||||
nsCOMPtr<nsILocale> mLocale;
|
||||
nsCOMPtr<nsICollation> mCollation;
|
||||
nsCOMPtr<nsIDateTimeFormat> mDateFormatter;
|
||||
|
||||
// annotation service : MAY BE NULL!
|
||||
//nsCOMPtr<mozIAnnotationService> mAnnotationService;
|
||||
|
@ -119,7 +119,7 @@ static void SetQueryKeyInt64(const nsCString& aValue, nsINavHistoryQuery* aQuery
|
||||
// options setters
|
||||
typedef NS_STDCALL_FUNCPROTO(nsresult, BoolOptionsSetter,
|
||||
nsINavHistoryQueryOptions,
|
||||
SetExpandPlaces, (PRBool));
|
||||
SetExpandQueries, (PRBool));
|
||||
typedef NS_STDCALL_FUNCPROTO(nsresult, Uint32OptionsSetter,
|
||||
nsINavHistoryQueryOptions,
|
||||
SetResultType, (PRUint32));
|
||||
@ -130,7 +130,9 @@ static void SetOptionsKeyUint32(const nsCString& aValue,
|
||||
nsINavHistoryQueryOptions* aOptions,
|
||||
Uint32OptionsSetter setter);
|
||||
|
||||
// components of a query string
|
||||
// Components of a query string.
|
||||
// Note that query strings are also generated in nsNavBookmarks::GetFolderURI
|
||||
// for performance reasons, so if you change these values, change that, too.
|
||||
#define QUERYKEY_BEGIN_TIME "beginTime"
|
||||
#define QUERYKEY_BEGIN_TIME_REFERENCE "beginTimeRef"
|
||||
#define QUERYKEY_END_TIME "endTime"
|
||||
@ -146,7 +148,9 @@ static void SetOptionsKeyUint32(const nsCString& aValue,
|
||||
#define QUERYKEY_GROUP "group"
|
||||
#define QUERYKEY_SORT "sort"
|
||||
#define QUERYKEY_RESULT_TYPE "type"
|
||||
#define QUERYKEY_EXPAND_PLACES "expandplaces"
|
||||
#define QUERYKEY_EXCLUDE_ITEMS "excludeItems"
|
||||
#define QUERYKEY_EXCLUDE_QUERIES "excludeQueries"
|
||||
#define QUERYKEY_EXPAND_QUERIES "expandQueries"
|
||||
#define QUERYKEY_FORCE_ORIGINAL_TITLE "originalTitle"
|
||||
#define QUERYKEY_INCLUDE_HIDDEN "includeHidden"
|
||||
#define QUERYKEY_MAX_RESULTS "maxResults"
|
||||
@ -350,12 +354,30 @@ nsNavHistory::QueriesToQueryString(nsINavHistoryQuery **aQueries,
|
||||
}
|
||||
|
||||
// result type
|
||||
if (options->ResultType() != nsINavHistoryQueryOptions::RESULT_TYPE_URL) {
|
||||
if (options->ResultType() != nsINavHistoryQueryOptions::RESULTS_AS_URI) {
|
||||
AppendAmpersandIfNonempty(aQueryString);
|
||||
aQueryString += NS_LITERAL_CSTRING(QUERYKEY_RESULT_TYPE "=");
|
||||
AppendInt32(aQueryString, options->ResultType());
|
||||
}
|
||||
|
||||
// exclude items
|
||||
if (options->ExcludeItems()) {
|
||||
AppendAmpersandIfNonempty(aQueryString);
|
||||
aQueryString += NS_LITERAL_CSTRING(QUERYKEY_EXCLUDE_ITEMS "=1");
|
||||
}
|
||||
|
||||
// exclude queries
|
||||
if (options->ExcludeQueries()) {
|
||||
AppendAmpersandIfNonempty(aQueryString);
|
||||
aQueryString += NS_LITERAL_CSTRING(QUERYKEY_EXCLUDE_QUERIES "=1");
|
||||
}
|
||||
|
||||
// expand queries
|
||||
if (options->ExpandQueries()) {
|
||||
AppendAmpersandIfNonempty(aQueryString);
|
||||
aQueryString += NS_LITERAL_CSTRING(QUERYKEY_EXPAND_QUERIES "=1");
|
||||
}
|
||||
|
||||
// title mode
|
||||
if (options->ForceOriginalTitle()) {
|
||||
AppendAmpersandIfNonempty(aQueryString);
|
||||
@ -537,10 +559,20 @@ nsNavHistory::TokensToQueries(const nsTArray<QueryKeyValuePair>& aTokens,
|
||||
SetOptionsKeyUint32(kvp.value, aOptions,
|
||||
&nsINavHistoryQueryOptions::SetResultType);
|
||||
|
||||
// expand places
|
||||
} else if (kvp.key.EqualsLiteral(QUERYKEY_EXPAND_PLACES)) {
|
||||
// exclude items
|
||||
} else if (kvp.key.EqualsLiteral(QUERYKEY_EXCLUDE_ITEMS)) {
|
||||
SetOptionsKeyBool(kvp.value, aOptions,
|
||||
&nsINavHistoryQueryOptions::SetExpandPlaces);
|
||||
&nsINavHistoryQueryOptions::SetExcludeItems);
|
||||
|
||||
// exclude queries
|
||||
} else if (kvp.key.EqualsLiteral(QUERYKEY_EXCLUDE_QUERIES)) {
|
||||
SetOptionsKeyBool(kvp.value, aOptions,
|
||||
&nsINavHistoryQueryOptions::SetExcludeQueries);
|
||||
|
||||
// expand queries
|
||||
} else if (kvp.key.EqualsLiteral(QUERYKEY_EXPAND_QUERIES)) {
|
||||
SetOptionsKeyBool(kvp.value, aOptions,
|
||||
&nsINavHistoryQueryOptions::SetExpandQueries);
|
||||
|
||||
// force original title
|
||||
} else if (kvp.key.EqualsLiteral(QUERYKEY_FORCE_ORIGINAL_TITLE)) {
|
||||
@ -592,7 +624,7 @@ ParseQueryBooleanString(const nsCString& aString, PRBool* aValue)
|
||||
|
||||
// nsINavHistoryQuery **********************************************************
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsNavHistoryQuery, nsINavHistoryQuery)
|
||||
NS_IMPL_ISUPPORTS2(nsNavHistoryQuery, nsNavHistoryQuery, nsINavHistoryQuery)
|
||||
|
||||
// nsINavHistoryQuery::nsNavHistoryQuery
|
||||
//
|
||||
@ -604,8 +636,7 @@ nsNavHistoryQuery::nsNavHistoryQuery()
|
||||
: mBeginTime(0), mBeginTimeReference(TIME_RELATIVE_EPOCH),
|
||||
mEndTime(0), mEndTimeReference(TIME_RELATIVE_EPOCH),
|
||||
mOnlyBookmarked(PR_FALSE), mDomainIsHost(PR_FALSE),
|
||||
mUriIsPrefix(PR_FALSE),
|
||||
mItemTypes(PR_UINT32_MAX) // default to include all item types
|
||||
mUriIsPrefix(PR_FALSE)
|
||||
{
|
||||
// differentiate not set (IsVoid) from empty string (local files)
|
||||
mDomain.SetIsVoid(PR_TRUE);
|
||||
@ -802,18 +833,6 @@ NS_IMETHODIMP nsNavHistoryQuery::SetFolders(const PRInt64 *aFolders,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNavHistoryQuery::GetItemTypes(PRUint32 *aTypes)
|
||||
{
|
||||
*aTypes = mItemTypes;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNavHistoryQuery::SetItemTypes(PRUint32 aTypes)
|
||||
{
|
||||
mItemTypes = aTypes;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNavHistoryQuery::Clone(nsINavHistoryQuery** _retval)
|
||||
{
|
||||
*_retval = nsnull;
|
||||
@ -904,23 +923,51 @@ nsNavHistoryQueryOptions::GetResultType(PRUint32* aType)
|
||||
NS_IMETHODIMP
|
||||
nsNavHistoryQueryOptions::SetResultType(PRUint32 aType)
|
||||
{
|
||||
if (aType > RESULT_TYPE_VISIT)
|
||||
if (aType > RESULTS_AS_FULL_VISIT)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
mResultType = aType;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// expandPlaces
|
||||
// excludeItems
|
||||
NS_IMETHODIMP
|
||||
nsNavHistoryQueryOptions::GetExpandPlaces(PRBool* aExpand)
|
||||
nsNavHistoryQueryOptions::GetExcludeItems(PRBool* aExclude)
|
||||
{
|
||||
*aExpand = mExpandPlaces;
|
||||
*aExclude = mExcludeItems;
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHODIMP
|
||||
nsNavHistoryQueryOptions::SetExpandPlaces(PRBool aExpand)
|
||||
nsNavHistoryQueryOptions::SetExcludeItems(PRBool aExclude)
|
||||
{
|
||||
mExpandPlaces = aExpand;
|
||||
mExcludeItems = aExclude;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// excludeQueries
|
||||
NS_IMETHODIMP
|
||||
nsNavHistoryQueryOptions::GetExcludeQueries(PRBool* aExclude)
|
||||
{
|
||||
*aExclude = mExcludeQueries;
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHODIMP
|
||||
nsNavHistoryQueryOptions::SetExcludeQueries(PRBool aExclude)
|
||||
{
|
||||
mExcludeQueries = aExclude;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// expandQueries
|
||||
NS_IMETHODIMP
|
||||
nsNavHistoryQueryOptions::GetExpandQueries(PRBool* aExpand)
|
||||
{
|
||||
*aExpand = mExpandQueries;
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHODIMP
|
||||
nsNavHistoryQueryOptions::SetExpandQueries(PRBool aExpand)
|
||||
{
|
||||
mExpandQueries = aExpand;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -997,7 +1044,9 @@ nsNavHistoryQueryOptions::Clone(nsNavHistoryQueryOptions **aResult)
|
||||
} else {
|
||||
result->mGroupCount = nsnull;
|
||||
}
|
||||
result->mExpandPlaces = mExpandPlaces;
|
||||
result->mExcludeItems = mExcludeItems;
|
||||
result->mExcludeQueries = mExcludeQueries;
|
||||
result->mExpandQueries = mExpandQueries;
|
||||
|
||||
resultHolder.swap(*aResult);
|
||||
return NS_OK;
|
||||
|
@ -50,15 +50,29 @@
|
||||
// This class encapsulates the parameters for basic history queries for
|
||||
// building UI, trees, lists, etc.
|
||||
|
||||
#define NS_NAVHISTORYQUERY_IID \
|
||||
{ 0xb10185e0, 0x86eb, 0x4612, { 0x95, 0x7c, 0x09, 0x34, 0xf2, 0xb1, 0xce, 0xd7 } }
|
||||
|
||||
class nsNavHistoryQuery : public nsINavHistoryQuery
|
||||
{
|
||||
public:
|
||||
nsNavHistoryQuery();
|
||||
// note: we use a copy constructor in Clone(), the default is good enough
|
||||
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_NAVHISTORYQUERY_IID)
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSINAVHISTORYQUERY
|
||||
|
||||
PRTime BeginTime() { return mBeginTime; }
|
||||
PRUint32 BeginTimeReference() { return mBeginTimeReference; }
|
||||
PRTime EndTime() { return mEndTime; }
|
||||
PRUint32 EndTimeReference() { return mEndTimeReference; }
|
||||
const nsString& SearchTerms() { return mSearchTerms; }
|
||||
PRBool OnlyBookmarked() { return mOnlyBookmarked; }
|
||||
PRBool DomainIsHost() { return mDomainIsHost; }
|
||||
const nsCString& Domain() { return mDomain; }
|
||||
PRBool UriIsPrefix() { return mUriIsPrefix; }
|
||||
nsIURI* Uri() { return mUri; } // NOT AddRef-ed!
|
||||
const nsTArray<PRInt64>& Folders() const { return mFolders; }
|
||||
|
||||
private:
|
||||
@ -77,7 +91,6 @@ protected:
|
||||
PRBool mUriIsPrefix;
|
||||
nsCOMPtr<nsIURI> mUri;
|
||||
nsTArray<PRInt64> mFolders;
|
||||
PRUint32 mItemTypes;
|
||||
};
|
||||
|
||||
|
||||
@ -91,7 +104,9 @@ class nsNavHistoryQueryOptions : public nsINavHistoryQueryOptions
|
||||
public:
|
||||
nsNavHistoryQueryOptions() : mSort(0), mResultType(0),
|
||||
mGroupCount(0), mGroupings(nsnull),
|
||||
mExpandPlaces(PR_FALSE),
|
||||
mExcludeItems(PR_FALSE),
|
||||
mExcludeQueries(PR_FALSE),
|
||||
mExpandQueries(PR_FALSE),
|
||||
mForceOriginalTitle(PR_FALSE),
|
||||
mIncludeHidden(PR_FALSE),
|
||||
mMaxResults(0)
|
||||
@ -111,7 +126,9 @@ public:
|
||||
const PRUint32* GroupingMode(PRUint32 *count) const {
|
||||
*count = mGroupCount; return mGroupings;
|
||||
}
|
||||
PRBool ExpandPlaces() const { return mExpandPlaces; }
|
||||
PRBool ExcludeItems() const { return mExcludeItems; }
|
||||
PRBool ExcludeQueries() const { return mExcludeQueries; }
|
||||
PRBool ExpandQueries() const { return mExpandQueries; }
|
||||
PRBool ForceOriginalTitle() const { return mForceOriginalTitle; }
|
||||
PRBool IncludeHidden() const { return mIncludeHidden; }
|
||||
PRUint32 MaxResults() const { return mMaxResults; }
|
||||
@ -123,11 +140,19 @@ private:
|
||||
|
||||
~nsNavHistoryQueryOptions() { delete[] mGroupings; }
|
||||
|
||||
// IF YOU ADD MORE ITEMS:
|
||||
// * Add a new getter for C++ above if it makes sense
|
||||
// * Add to the serialization code
|
||||
// * Add to the deserialization code
|
||||
// * Add to the nsNavHistoryQueryOptions::Clone() function
|
||||
// * Add to the nsNavHistory.cpp:IsSimpleBookmarksQuery function if applicable
|
||||
PRUint32 mSort;
|
||||
PRUint32 mResultType;
|
||||
PRUint32 mGroupCount;
|
||||
PRUint32 *mGroupings;
|
||||
PRBool mExpandPlaces;
|
||||
PRBool mExcludeItems;
|
||||
PRBool mExcludeQueries;
|
||||
PRBool mExpandQueries;
|
||||
PRBool mForceOriginalTitle;
|
||||
PRBool mIncludeHidden;
|
||||
PRUint32 mMaxResults;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -45,17 +45,59 @@
|
||||
#ifndef nsNavHistoryResult_h_
|
||||
#define nsNavHistoryResult_h_
|
||||
|
||||
#include "nsTArray.h"
|
||||
#include "nsInterfaceHashtable.h"
|
||||
#include "nsDataHashtable.h"
|
||||
|
||||
class nsNavHistory;
|
||||
class nsNavHistoryResult;
|
||||
class nsIDateTimeFormat;
|
||||
class nsIWritablePropertyBag;
|
||||
class nsNavHistoryQueryOptions;
|
||||
|
||||
class nsNavHistoryContainerResultNode;
|
||||
class nsNavHistoryFolderResultNode;
|
||||
class nsNavHistoryQueryResultNode;
|
||||
class nsNavHistoryURIResultNode;
|
||||
class nsNavHistoryVisitResultNode;
|
||||
|
||||
/**
|
||||
* hashkey wrapper using PRInt64 KeyType
|
||||
*
|
||||
* @see nsTHashtable::EntryType for specification
|
||||
*
|
||||
* This just truncates the 64-bit int to a 32-bit one for using a hash number.
|
||||
* It is used for bookmark folder IDs, which should be way less than 2^32.
|
||||
*/
|
||||
class nsTrimInt64HashKey : public PLDHashEntryHdr
|
||||
{
|
||||
public:
|
||||
typedef const PRInt64& KeyType;
|
||||
typedef const PRInt64* KeyTypePointer;
|
||||
|
||||
nsTrimInt64HashKey(KeyTypePointer aKey) : mValue(*aKey) { }
|
||||
nsTrimInt64HashKey(const nsTrimInt64HashKey& toCopy) : mValue(toCopy.mValue) { }
|
||||
~nsTrimInt64HashKey() { }
|
||||
|
||||
KeyType GetKey() const { return mValue; }
|
||||
KeyTypePointer GetKeyPointer() const { return &mValue; }
|
||||
PRBool KeyEquals(KeyTypePointer aKey) const { return *aKey == mValue; }
|
||||
|
||||
static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
|
||||
static PLDHashNumber HashKey(KeyTypePointer aKey)
|
||||
{ return NS_STATIC_CAST(PRUint32, (*aKey) & PR_UINT32_MAX); }
|
||||
enum { ALLOW_MEMMOVE = PR_TRUE };
|
||||
|
||||
private:
|
||||
const PRInt64 mValue;
|
||||
};
|
||||
|
||||
// Declare methods for implementing nsINavBookmarkObserver
|
||||
// and nsINavHistoryObserver (some methods, such as BeginUpdateBatch overlap)
|
||||
#define NS_DECL_BOOKMARK_HISTORY_OBSERVER \
|
||||
NS_DECL_NSINAVBOOKMARKOBSERVER \
|
||||
NS_IMETHOD OnVisit(nsIURI* aURI, PRInt64 aVisitID, PRTime aTime, \
|
||||
PRInt64 aSessionID, PRInt64 aReferringID, \
|
||||
NS_IMETHOD OnVisit(nsIURI* aURI, PRInt64 aVisitId, PRTime aTime, \
|
||||
PRInt64 aSessionId, PRInt64 aReferringId, \
|
||||
PRUint32 aTransitionType); \
|
||||
NS_IMETHOD OnTitleChanged(nsIURI* aURI, const nsAString& aPageTitle, \
|
||||
const nsAString& aUserTitle, \
|
||||
@ -74,10 +116,38 @@ class nsNavHistoryQueryOptions;
|
||||
#define NS_NAVHISTORYRESULTNODE_IID \
|
||||
{0x54b61d38, 0x57c1, 0x11da, {0x95, 0xb8, 0x00, 0x13, 0x21, 0xc9, 0xf6, 0x9e}}
|
||||
|
||||
// These are all the simple getters, they can be used for the result node
|
||||
// implementation and all subclasses. More complex are GetIcon and GetParent
|
||||
// (which depends on the definition of container result node).
|
||||
#define NS_IMPLEMENT_SIMPLE_RESULTNODE \
|
||||
NS_IMETHOD GetTitle(nsACString& aTitle) \
|
||||
{ aTitle = mTitle; return NS_OK; } \
|
||||
NS_IMETHOD GetAccessCount(PRUint32* aAccessCount) \
|
||||
{ *aAccessCount = mAccessCount; return NS_OK; } \
|
||||
NS_IMETHOD GetTime(PRTime* aTime) \
|
||||
{ *aTime = mTime; return NS_OK; } \
|
||||
NS_IMETHOD GetIndentLevel(PRUint32* aIndentLevel) \
|
||||
{ *aIndentLevel = mIndentLevel; return NS_OK; }
|
||||
|
||||
// This is used by the base classes instead of
|
||||
// NS_FORWARD_NSINAVHISTORYRESULTNODE(nsNavHistoryResultNode) because they
|
||||
// need to redefine GetType rather than forwarding it. This implements all the
|
||||
// simple getters instead of forwarding because they are so short and we can
|
||||
// save a virtual function call.
|
||||
#define NS_FORWARD_RESULTNODE_TO_BASE_EXCEPT_GETTYPE \
|
||||
NS_IMPLEMENT_SIMPLE_RESULTNODE \
|
||||
NS_IMETHOD GetIcon(nsIURI** aIcon) \
|
||||
{ return nsNavHistoryResultNode::GetIcon(aIcon); } \
|
||||
NS_IMETHOD GetParent(nsINavHistoryContainerResultNode** aParent) \
|
||||
{ return nsNavHistoryResultNode::GetParent(aParent); } \
|
||||
NS_IMETHOD GetPropertyBag(nsIWritablePropertyBag** aBag) \
|
||||
{ return nsNavHistoryResultNode::GetPropertyBag(aBag); }
|
||||
|
||||
class nsNavHistoryResultNode : public nsINavHistoryResultNode
|
||||
{
|
||||
public:
|
||||
nsNavHistoryResultNode();
|
||||
nsNavHistoryResultNode(const nsACString& aTitle, PRUint32 aAccessCount,
|
||||
PRTime aTime, const nsACString& aIconURI);
|
||||
|
||||
#ifdef MOZILLA_1_8_BRANCH
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(NS_NAVHISTORYRESULTNODE_IID)
|
||||
@ -86,116 +156,449 @@ public:
|
||||
#endif
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSINAVHISTORYRESULTNODE
|
||||
NS_IMPLEMENT_SIMPLE_RESULTNODE
|
||||
NS_IMETHOD GetIcon(nsIURI** aIcon);
|
||||
NS_IMETHOD GetParent(nsINavHistoryContainerResultNode** aParent);
|
||||
NS_IMETHOD GetPropertyBag(nsIWritablePropertyBag** aBag);
|
||||
// leave GetType() unimplemented, will be implemented by sub classes
|
||||
|
||||
// History/bookmark notifications. Note that we don't actually inherit
|
||||
// these interfaces since multiple-inheritance breaks nsCOMArray.
|
||||
NS_DECL_BOOKMARK_HISTORY_OBSERVER
|
||||
virtual void OnRemoving();
|
||||
|
||||
// Generate the children for this node.
|
||||
virtual nsresult BuildChildren(PRBool *aBuilt) {
|
||||
*aBuilt = PR_FALSE;
|
||||
return NS_OK;;
|
||||
}
|
||||
public:
|
||||
|
||||
// Rebuild the node's data. This only applies to nodes which have
|
||||
// a URL or a folder ID, and does _not_ rebuild the node's children.
|
||||
virtual nsresult Rebuild();
|
||||
|
||||
// Non-XPCOM member accessors
|
||||
PRInt32 Type() const { return mType; }
|
||||
const nsCString& URL() const { return mUrl; }
|
||||
virtual PRInt64 FolderId() const { return 0; }
|
||||
PRInt32 VisibleIndex() const { return mVisibleIndex; }
|
||||
void SetVisibleIndex(PRInt32 aIndex) { mVisibleIndex = aIndex; }
|
||||
PRInt32 IndentLevel() const { return mIndentLevel; }
|
||||
void SetIndentLevel(PRInt32 aLevel) { mIndentLevel = aLevel; }
|
||||
nsNavHistoryResultNode* Parent() { return mParent; }
|
||||
void SetParent(nsNavHistoryResultNode *aParent) { mParent = aParent; }
|
||||
|
||||
nsNavHistoryResultNode* ChildAt(PRInt32 aIndex) { return mChildren[aIndex]; }
|
||||
|
||||
protected:
|
||||
virtual ~nsNavHistoryResultNode() {}
|
||||
|
||||
// Find the top-level NavHistoryResult for this node
|
||||
nsNavHistoryResult* GetResult();
|
||||
|
||||
// parent of this element, NULL if no parent. Filled in by FilledAllResults
|
||||
// in the result set.
|
||||
nsNavHistoryResultNode* mParent;
|
||||
// These functions test the type. We don't use a virtual function since that
|
||||
// would take a vtable slot for every one of (potentially very many) nodes.
|
||||
// Note that GetType() already has a vtable slot because its on the iface.
|
||||
PRBool IsTypeContainer(PRUint32 type) {
|
||||
return (type == nsINavHistoryResultNode::RESULT_TYPE_HOST ||
|
||||
type == nsINavHistoryResultNode::RESULT_TYPE_DAY ||
|
||||
type == nsINavHistoryResultNode::RESULT_TYPE_QUERY ||
|
||||
type == nsINavHistoryResultNode::RESULT_TYPE_FOLDER);
|
||||
}
|
||||
PRBool IsContainer() {
|
||||
PRUint32 type;
|
||||
GetType(&type);
|
||||
return IsTypeContainer(type);
|
||||
}
|
||||
static PRBool IsTypeQuerySubcontainer(PRUint32 type) {
|
||||
// Tests containers that are inside queries that really belong to the query
|
||||
// itself, and is used when recursively updating a query. This include host
|
||||
// and day containers, but doesn't include other queries and folders.
|
||||
return (type == nsINavHistoryResultNode::RESULT_TYPE_HOST ||
|
||||
type == nsINavHistoryResultNode::RESULT_TYPE_DAY);
|
||||
}
|
||||
PRBool IsQuerySubcontainer() {
|
||||
PRUint32 type;
|
||||
GetType(&type);
|
||||
return IsTypeQuerySubcontainer(type);
|
||||
}
|
||||
static PRBool IsTypeURI(PRUint32 type) {
|
||||
return (type == nsINavHistoryResultNode::RESULT_TYPE_URI ||
|
||||
type == nsINavHistoryResultNode::RESULT_TYPE_VISIT ||
|
||||
type == nsINavHistoryResultNode::RESULT_TYPE_FULL_VISIT);
|
||||
}
|
||||
PRBool IsURI() {
|
||||
PRUint32 type;
|
||||
GetType(&type);
|
||||
return IsTypeURI(type);
|
||||
}
|
||||
static PRBool IsTypeVisit(PRUint32 type) {
|
||||
return (type == nsINavHistoryResultNode::RESULT_TYPE_VISIT ||
|
||||
type == nsINavHistoryResultNode::RESULT_TYPE_FULL_VISIT);
|
||||
}
|
||||
PRBool IsVisit() {
|
||||
PRUint32 type;
|
||||
GetType(&type);
|
||||
return IsTypeVisit(type);
|
||||
}
|
||||
static PRBool IsTypeFolder(PRUint32 type) {
|
||||
return (type == nsINavHistoryResultNode::RESULT_TYPE_FOLDER);
|
||||
}
|
||||
PRBool IsFolder() {
|
||||
PRUint32 type;
|
||||
GetType(&type);
|
||||
return IsTypeFolder(type);
|
||||
}
|
||||
static PRBool IsTypeQuery(PRUint32 type) {
|
||||
return (type == nsINavHistoryResultNode::RESULT_TYPE_QUERY);
|
||||
}
|
||||
PRBool IsQuery() {
|
||||
PRUint32 type;
|
||||
GetType(&type);
|
||||
return IsTypeQuery(type);
|
||||
}
|
||||
|
||||
// these are all the basic row info, filled in by nsNavHistory::RowToResult
|
||||
PRInt64 mID; // keep this for comparing dups, not exposed in interface
|
||||
// might be 0, indicating some kind of parent node
|
||||
PRInt32 mType;
|
||||
nsCString mUrl;
|
||||
nsString mTitle;
|
||||
PRInt32 mAccessCount;
|
||||
PRTime mTime;
|
||||
nsString mHost;
|
||||
nsCString mFaviconURL;
|
||||
PRInt64 mSessionID;
|
||||
nsNavHistoryContainerResultNode* GetAsContainer() {
|
||||
NS_ASSERTION(IsContainer(), "Not a container");
|
||||
return NS_REINTERPRET_CAST(nsNavHistoryContainerResultNode*, this);
|
||||
}
|
||||
nsNavHistoryURIResultNode* GetAsURI() {
|
||||
NS_ASSERTION(IsURI(), "Not a URI");
|
||||
return NS_REINTERPRET_CAST(nsNavHistoryURIResultNode*, this);
|
||||
}
|
||||
nsNavHistoryVisitResultNode* GetAsVisit() {
|
||||
NS_ASSERTION(IsVisit(), "Not a visit");
|
||||
return NS_REINTERPRET_CAST(nsNavHistoryVisitResultNode*, this);
|
||||
}
|
||||
nsNavHistoryFolderResultNode* GetAsFolder() {
|
||||
NS_ASSERTION(IsFolder(), "Not a folder");
|
||||
return NS_REINTERPRET_CAST(nsNavHistoryFolderResultNode*, this);
|
||||
}
|
||||
nsNavHistoryQueryResultNode* GetAsQuery() {
|
||||
NS_ASSERTION(IsQuery(), "Not a query");
|
||||
return NS_REINTERPRET_CAST(nsNavHistoryQueryResultNode*, this);
|
||||
}
|
||||
|
||||
// Filled in by the result type generator in nsNavHistory
|
||||
nsCOMArray<nsNavHistoryResultNode> mChildren;
|
||||
nsNavHistoryContainerResultNode* mParent;
|
||||
nsCString mTitle;
|
||||
PRUint32 mAccessCount;
|
||||
PRInt64 mTime;
|
||||
nsCString mFaviconURI;
|
||||
|
||||
// filled in by FillledAllResults in the result set.
|
||||
// The indent level of this node. The root node will have a value of -1. The
|
||||
// root's children will have a value of 0, and so on.
|
||||
PRInt32 mIndentLevel;
|
||||
|
||||
// index of this element into the mVisibleElements array in the result set
|
||||
// The index into the result's mVisibleElements list of this element. This is
|
||||
// -1 if it is invalid. For items, >= 0 can be used to determine if the node
|
||||
// is visible in the list or not. For folders, call IsVisible, since they
|
||||
// can be the root node which is not itself visible, but its children are.
|
||||
PRInt32 mVisibleIndex;
|
||||
};
|
||||
|
||||
|
||||
// nsNavHistoryURIResultNode
|
||||
|
||||
#define NS_IMPLEMENT_URIRESULT \
|
||||
NS_IMETHOD GetUri(nsACString& aURI) { aURI = mURI; return NS_OK; }
|
||||
|
||||
class nsNavHistoryURIResultNode : public nsNavHistoryResultNode,
|
||||
public nsINavHistoryURIResultNode
|
||||
{
|
||||
public:
|
||||
nsNavHistoryURIResultNode(const nsACString& aTitle, PRUint32 aAccessCount,
|
||||
PRTime aTime, const nsACString& aIconURI, const nsACString& aURI);
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_FORWARD_RESULTNODE_TO_BASE_EXCEPT_GETTYPE
|
||||
NS_IMETHOD GetType(PRUint32* type)
|
||||
{ *type = nsINavHistoryResultNode::RESULT_TYPE_URI; return NS_OK; }
|
||||
NS_IMPLEMENT_URIRESULT
|
||||
|
||||
public:
|
||||
nsCString mURI;
|
||||
};
|
||||
|
||||
|
||||
// nsNavHistoryVisitResultNode
|
||||
|
||||
#define NS_IMPLEMENT_VISITRESULT \
|
||||
NS_IMPLEMENT_URIRESULT \
|
||||
NS_IMETHOD GetSessionId(PRInt64* aSessionId) \
|
||||
{ *aSessionId = mSessionId; return NS_OK; }
|
||||
|
||||
class nsNavHistoryVisitResultNode : public nsNavHistoryURIResultNode,
|
||||
public nsINavHistoryVisitResultNode
|
||||
{
|
||||
public:
|
||||
nsNavHistoryVisitResultNode(const nsACString& aTitle, PRUint32 aAccessCount,
|
||||
PRTime aTime, const nsACString& aIconURI, const nsACString& aURI,
|
||||
PRInt64 aSession);
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_FORWARD_RESULTNODE_TO_BASE_EXCEPT_GETTYPE
|
||||
NS_IMETHOD GetType(PRUint32* type)
|
||||
{ *type = nsINavHistoryResultNode::RESULT_TYPE_VISIT; return NS_OK; }
|
||||
NS_IMPLEMENT_VISITRESULT
|
||||
|
||||
public:
|
||||
|
||||
PRInt64 mSessionId;
|
||||
};
|
||||
|
||||
|
||||
// nsNavHistoryFullVisitResultNode
|
||||
|
||||
#define NS_IMPLEMENT_FULLVISITRESULT \
|
||||
NS_IMPLEMENT_VISITRESULT \
|
||||
NS_IMETHOD GetVisitId(PRInt64 *aVisitId) \
|
||||
{ *aVisitId = mVisitId; return NS_OK; } \
|
||||
NS_IMETHOD GetReferringVisitId(PRInt64 *aReferringVisitId) \
|
||||
{ *aReferringVisitId = mReferringVisitId; return NS_OK; } \
|
||||
NS_IMETHOD GetTransitionType(PRInt32 *aTransitionType) \
|
||||
{ *aTransitionType = mTransitionType; return NS_OK; }
|
||||
|
||||
class nsNavHistoryFullVisitResultNode : public nsNavHistoryVisitResultNode,
|
||||
public nsINavHistoryFullVisitResultNode
|
||||
{
|
||||
public:
|
||||
nsNavHistoryFullVisitResultNode(const nsACString& aTitle, PRUint32 aAccessCount,
|
||||
PRTime aTime, const nsACString& aIconURI, const nsACString& aURI,
|
||||
PRInt64 aSession, PRInt64 aVisitId, PRInt64 aReferringVisitId,
|
||||
PRInt32 aTransitionType);
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_FORWARD_RESULTNODE_TO_BASE_EXCEPT_GETTYPE
|
||||
NS_IMETHOD GetType(PRUint32* type)
|
||||
{ *type = nsINavHistoryResultNode::RESULT_TYPE_FULL_VISIT; return NS_OK; }
|
||||
NS_IMPLEMENT_FULLVISITRESULT
|
||||
|
||||
public:
|
||||
PRInt64 mVisitId;
|
||||
PRInt64 mReferringVisitId;
|
||||
PRInt32 mTransitionType;
|
||||
};
|
||||
|
||||
|
||||
// nsNavHistoryContainerResultNode
|
||||
//
|
||||
// This is the base class for all nodes that can have children. It is
|
||||
// overridden for nodes that are dynamically populated such as queries and
|
||||
// folders. It is used directly for simple containers such as host groups
|
||||
// in history views.
|
||||
|
||||
// derived classes each provide their own implementation of has children and
|
||||
// forward the rest to us using this macro
|
||||
#define NS_FORWARD_CONTAINERNODE_EXCEPT_HASCHILDREN \
|
||||
NS_IMETHOD GetContainerOpen(PRBool *aContainerOpen) \
|
||||
{ return nsNavHistoryContainerResultNode::GetContainerOpen(aContainerOpen); } \
|
||||
NS_IMETHOD SetContainerOpen(PRBool aContainerOpen) \
|
||||
{ return nsNavHistoryContainerResultNode::SetContainerOpen(aContainerOpen); } \
|
||||
NS_IMETHOD GetChildCount(PRUint32 *aChildCount) \
|
||||
{ return nsNavHistoryContainerResultNode::GetChildCount(aChildCount); } \
|
||||
NS_IMETHOD GetChild(PRUint32 index, nsINavHistoryResultNode **_retval) \
|
||||
{ return nsNavHistoryContainerResultNode::GetChild(index, _retval); } \
|
||||
NS_IMETHOD GetChildrenReadOnly(PRBool *aChildrenReadOnly) \
|
||||
{ return nsNavHistoryContainerResultNode::GetChildrenReadOnly(aChildrenReadOnly); }
|
||||
|
||||
class nsNavHistoryContainerResultNode : public nsNavHistoryResultNode,
|
||||
public nsINavHistoryContainerResultNode
|
||||
{
|
||||
public:
|
||||
nsNavHistoryContainerResultNode(const nsACString& aTitle, PRUint32 aAccessCount,
|
||||
PRTime aTime, const nsACString& aIconURI, PRUint32 aContainerType,
|
||||
PRBool aReadOnly);
|
||||
nsNavHistoryContainerResultNode(const nsACString& aTitle,
|
||||
const nsACString& aIconURI, PRUint32 aContainerType);
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_FORWARD_RESULTNODE_TO_BASE_EXCEPT_GETTYPE
|
||||
NS_IMETHOD GetType(PRUint32* type)
|
||||
{ *type = mContainerType; return NS_OK; }
|
||||
NS_DECL_NSINAVHISTORYCONTAINERRESULTNODE
|
||||
|
||||
public:
|
||||
|
||||
virtual void OnRemoving();
|
||||
|
||||
PRBool AreChildrenVisible();
|
||||
|
||||
// overridded by descendents to populate
|
||||
virtual nsresult OpenContainer();
|
||||
virtual nsresult CloseContainer();
|
||||
|
||||
// this points to the result that owns this container. All containers have
|
||||
// their result pointer set so we can quickly get to the result without having
|
||||
// to walk the tree. Yet, this also saves us from storing a million pointers
|
||||
// for every leaf node to the result.
|
||||
nsNavHistoryResult* mResult;
|
||||
|
||||
// for example, RESULT_TYPE_HOST or RESULT_TYPE_DAY. Query and Folder results
|
||||
// override GetType so this is not used, but is still kept in sync.
|
||||
PRUint32 mContainerType;
|
||||
|
||||
// when there are children, this stores the open state in the tree
|
||||
// this is set to the default in the constructor
|
||||
PRBool mExpanded;
|
||||
|
||||
friend class nsNavHistory;
|
||||
friend class nsNavHistoryResult;
|
||||
friend class nsNavBookmarks;
|
||||
// Filled in by the result type generator in nsNavHistory
|
||||
nsCOMArray<nsNavHistoryResultNode> mChildren;
|
||||
|
||||
PRBool mChildrenReadOnly;
|
||||
|
||||
void FillStats();
|
||||
void ReverseUpdateStats(PRInt32 aAccessCountChange);
|
||||
|
||||
// sorting
|
||||
typedef nsCOMArray<nsNavHistoryResultNode>::nsCOMArrayComparatorFunc SortComparator;
|
||||
virtual PRUint32 GetSortType();
|
||||
static SortComparator GetSortingComparator(PRUint32 aSortType);
|
||||
void RecursiveSort(nsICollation* aCollation, SortComparator aComparator);
|
||||
PRUint32 FindInsertionPoint(nsNavHistoryResultNode* aNode, SortComparator aComparator);
|
||||
PRBool DoesChildNeedResorting(PRUint32 aIndex, SortComparator aComparator);
|
||||
|
||||
PR_STATIC_CALLBACK(int) SortComparison_TitleLess(
|
||||
nsNavHistoryResultNode* a, nsNavHistoryResultNode* b, void* closure);
|
||||
PR_STATIC_CALLBACK(int) SortComparison_TitleGreater(
|
||||
nsNavHistoryResultNode* a, nsNavHistoryResultNode* b, void* closure);
|
||||
PR_STATIC_CALLBACK(int) SortComparison_DateLess(
|
||||
nsNavHistoryResultNode* a, nsNavHistoryResultNode* b, void* closure);
|
||||
PR_STATIC_CALLBACK(int) SortComparison_DateGreater(
|
||||
nsNavHistoryResultNode* a, nsNavHistoryResultNode* b, void* closure);
|
||||
PR_STATIC_CALLBACK(int) SortComparison_URILess(
|
||||
nsNavHistoryResultNode* a, nsNavHistoryResultNode* b, void* closure);
|
||||
PR_STATIC_CALLBACK(int) SortComparison_URIGreater(
|
||||
nsNavHistoryResultNode* a, nsNavHistoryResultNode* b, void* closure);
|
||||
PR_STATIC_CALLBACK(int) SortComparison_VisitCountLess(
|
||||
nsNavHistoryResultNode* a, nsNavHistoryResultNode* b, void* closure);
|
||||
PR_STATIC_CALLBACK(int) SortComparison_VisitCountGreater(
|
||||
nsNavHistoryResultNode* a, nsNavHistoryResultNode* b, void* closure);
|
||||
|
||||
// finding children: THESE DO NOT ADDREF
|
||||
nsNavHistoryURIResultNode* FindChildURI(nsIURI* aURI, PRUint32* aNodeIndex)
|
||||
{
|
||||
nsCAutoString spec;
|
||||
if (NS_FAILED(aURI->GetSpec(spec)))
|
||||
return PR_FALSE;
|
||||
return FindChildURI(spec, aNodeIndex);
|
||||
}
|
||||
nsNavHistoryURIResultNode* FindChildURI(const nsACString& aSpec,
|
||||
PRUint32* aNodeIndex);
|
||||
nsNavHistoryFolderResultNode* FindChildFolder(PRInt64 aFolderId,
|
||||
PRUint32* aNodeIndex);
|
||||
nsNavHistoryContainerResultNode* FindChildContainerByName(const nsACString& aTitle,
|
||||
PRUint32* aNodeIndex);
|
||||
// returns the index of the given node, -1 if not found
|
||||
PRInt32 FindChild(nsNavHistoryResultNode* aNode)
|
||||
{ return mChildren.IndexOf(aNode); }
|
||||
|
||||
nsresult InsertChildAt(nsNavHistoryResultNode* aNode, PRInt32 aIndex,
|
||||
PRBool aIsTemporary = PR_FALSE);
|
||||
nsresult InsertSortedChild(nsNavHistoryResultNode* aNode,
|
||||
PRBool aIsTemporary = PR_FALSE);
|
||||
void MergeResults(nsCOMArray<nsNavHistoryResultNode>* aNodes);
|
||||
nsresult ReplaceChildURIAt(PRUint32 aIndex,
|
||||
nsNavHistoryURIResultNode* aNode);
|
||||
nsresult RemoveChildAt(PRInt32 aIndex, PRBool aIsTemporary = PR_FALSE);
|
||||
};
|
||||
|
||||
// nsNavHistoryQeuryNode
|
||||
//
|
||||
// nsNavHistoryQueryNode is a special type of ResultNode that executes a
|
||||
// query when asked to build its children.
|
||||
|
||||
class nsNavHistoryQueryNode : public nsNavHistoryResultNode
|
||||
// nsNavHistoryQueryResultNode
|
||||
//
|
||||
// Overridden container type for complex queries over history and/or
|
||||
// bookmarks. This keeps itself in sync by listening to history and
|
||||
// bookmark notifications.
|
||||
|
||||
class nsNavHistoryQueryResultNode : public nsNavHistoryContainerResultNode,
|
||||
public nsINavHistoryQueryResultNode
|
||||
{
|
||||
public:
|
||||
nsNavHistoryQueryNode()
|
||||
: mQueries(nsnull), mQueryCount(0), mBuiltChildren(PR_FALSE) {}
|
||||
nsNavHistoryQueryResultNode(nsNavHistoryQueryOptions* aGeneratingOptions,
|
||||
const nsACString& aTitle, PRUint32 aAccessCount,
|
||||
PRTime aTime, const nsACString& aIconURI,
|
||||
const nsACString& aQueryURI);
|
||||
nsNavHistoryQueryResultNode(nsNavHistoryQueryOptions* aGeneratingOptions,
|
||||
const nsACString& aTitle, PRUint32 aAccessCount,
|
||||
PRTime aTime, const nsACString& aIconURI,
|
||||
nsINavHistoryQuery** aQueries, PRUint32 aQueryCount,
|
||||
nsNavHistoryQueryOptions* aOptions);
|
||||
|
||||
// nsINavHistoryResultNode methods
|
||||
NS_IMETHOD GetFolderId(PRInt64 *aId)
|
||||
{ *aId = nsNavHistoryQueryNode::FolderId(); return NS_OK; }
|
||||
NS_IMETHOD GetFolderType(nsAString& aFolderType);
|
||||
NS_IMETHOD GetQueries(PRUint32 *aQueryCount,
|
||||
nsINavHistoryQuery ***aQueries);
|
||||
NS_IMETHOD GetQueryOptions(nsINavHistoryQueryOptions **aOptions);
|
||||
NS_IMETHOD GetChildrenReadOnly(PRBool *aResult);
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_FORWARD_RESULTNODE_TO_BASE_EXCEPT_GETTYPE
|
||||
NS_IMETHOD GetType(PRUint32* type)
|
||||
{ *type = nsINavHistoryResultNode::RESULT_TYPE_QUERY; return NS_OK; }
|
||||
NS_FORWARD_CONTAINERNODE_EXCEPT_HASCHILDREN
|
||||
NS_IMETHOD GetHasChildren(PRBool* aHasChildren);
|
||||
NS_DECL_NSINAVHISTORYQUERYRESULTNODE
|
||||
|
||||
PRBool CanExpand();
|
||||
|
||||
virtual nsresult OpenContainer();
|
||||
|
||||
NS_DECL_BOOKMARK_HISTORY_OBSERVER
|
||||
virtual void OnRemoving();
|
||||
|
||||
// nsNavHistoryResultNode methods
|
||||
virtual nsresult BuildChildren(PRBool *aBuilt);
|
||||
virtual PRInt64 FolderId() const;
|
||||
virtual nsresult Rebuild();
|
||||
public:
|
||||
// These are the options that caused this node to be generated. For just
|
||||
// running queries directly, this node will be the root of the result and
|
||||
// mGeneratingOptions will be the same as mOptions. When queries are in
|
||||
// bookmark folders, this it the options structure used to generate the
|
||||
// bookmarks tree. It tells us, for example, if we should expand ourselves.
|
||||
nsCOMPtr<nsNavHistoryQueryOptions> mGeneratingOptions;
|
||||
|
||||
protected:
|
||||
virtual ~nsNavHistoryQueryNode();
|
||||
nsresult ParseQueries();
|
||||
nsresult CreateNode(nsIURI *aURI, nsNavHistoryResultNode **aNode);
|
||||
nsresult UpdateQuery();
|
||||
PRBool HasFilteredChildren() const;
|
||||
// this may be constructedlazily from mQueries and mOptions, call VerifyQueriesSerialized
|
||||
// either this or mQueries/mOptions should be valid
|
||||
nsCString mQueryURI;
|
||||
nsresult VerifyQueriesSerialized();
|
||||
|
||||
nsINavHistoryQuery **mQueries;
|
||||
PRUint32 mQueryCount;
|
||||
// these may be constructed lazily from mQueryURI, call VerifyQueriesParsed
|
||||
// either this or mQueryURI should be valid
|
||||
nsCOMArray<nsINavHistoryQuery> mQueries;
|
||||
nsCOMPtr<nsNavHistoryQueryOptions> mOptions;
|
||||
PRBool mBuiltChildren;
|
||||
nsString mFolderType;
|
||||
PRUint32 mLiveUpdate; // one of QUERYUPDATE_* in nsNavHistory.h
|
||||
PRBool mHasSearchTerms;
|
||||
nsresult VerifyQueriesParsed();
|
||||
|
||||
friend class nsNavBookmarks;
|
||||
// this indicates whether the query contents are valid, they don't go away
|
||||
// after the container is closed until a notification comes in
|
||||
PRBool mContentsValid;
|
||||
|
||||
PRBool mBatchInProgress;
|
||||
|
||||
nsresult FillChildren();
|
||||
void ClearChildren(PRBool unregister);
|
||||
nsresult Refresh();
|
||||
|
||||
virtual PRUint32 GetSortType();
|
||||
void UpdateURIs(PRBool aOnlyOne, PRBool aUpdateSort, const nsCString& aSpec,
|
||||
void (*aCallback)(nsNavHistoryURIResultNode*,void*),
|
||||
void* aClosure);
|
||||
void RecursiveFindURIs(PRBool aOnlyOne,
|
||||
nsNavHistoryContainerResultNode* aContainer,
|
||||
const nsCString& aSpec,
|
||||
nsCOMArray<nsNavHistoryResultNode>* aMatches);
|
||||
};
|
||||
|
||||
|
||||
// nsNavHistoryFolderResultNode
|
||||
//
|
||||
// Overridden container type for bookmark folders. It will keep the contents
|
||||
// of the folder in sync with the bookmark service.
|
||||
|
||||
class nsNavHistoryFolderResultNode : public nsNavHistoryContainerResultNode,
|
||||
public nsINavHistoryFolderResultNode
|
||||
{
|
||||
public:
|
||||
nsNavHistoryFolderResultNode(const nsACString& aTitle, PRUint32 aAccessCount,
|
||||
PRTime aTime, nsNavHistoryQueryOptions* options,
|
||||
PRInt64 aFolderId);
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_FORWARD_RESULTNODE_TO_BASE_EXCEPT_GETTYPE
|
||||
NS_IMETHOD GetType(PRUint32* type)
|
||||
{ *type = nsINavHistoryResultNode::RESULT_TYPE_FOLDER; return NS_OK; }
|
||||
NS_FORWARD_CONTAINERNODE_EXCEPT_HASCHILDREN
|
||||
NS_IMETHOD GetHasChildren(PRBool* aHasChildren);
|
||||
NS_DECL_NSINAVHISTORYQUERYRESULTNODE
|
||||
|
||||
NS_IMETHOD GetFolderId(PRInt64* aFolderId)
|
||||
{ *aFolderId = mFolderId; return NS_OK; }
|
||||
|
||||
virtual nsresult OpenContainer();
|
||||
|
||||
// This object implements a bookmark observer interface without deriving from
|
||||
// the bookmark observers. This is called from the result's actual observer
|
||||
// and it knows all observers are FolderResultNodes
|
||||
NS_DECL_NSINAVBOOKMARKOBSERVER
|
||||
|
||||
virtual void OnRemoving();
|
||||
|
||||
public:
|
||||
|
||||
// this indicates whether the folder contents are valid, they don't go away
|
||||
// after the container is closed until a notification comes in
|
||||
PRBool mContentsValid;
|
||||
|
||||
nsCOMPtr<nsNavHistoryQueryOptions> mOptions;
|
||||
PRInt64 mFolderId;
|
||||
|
||||
nsresult FillChildren();
|
||||
void ClearChildren(PRBool aUnregister);
|
||||
|
||||
virtual PRUint32 GetSortType();
|
||||
PRBool StartIncrementalUpdate();
|
||||
};
|
||||
|
||||
|
||||
@ -208,151 +611,121 @@ protected:
|
||||
// This object implements nsITreeView so you can just set it to a tree
|
||||
// view and it will work. This object also observes the necessary history
|
||||
// and bookmark events to keep itself up-to-date.
|
||||
//
|
||||
|
||||
class nsNavHistoryResult : public nsNavHistoryQueryNode,
|
||||
public nsSupportsWeakReference,
|
||||
class nsNavHistoryResult : public nsSupportsWeakReference,
|
||||
public nsINavHistoryResult,
|
||||
public nsITreeView,
|
||||
public nsINavBookmarkObserver,
|
||||
public nsINavHistoryObserver
|
||||
{
|
||||
public:
|
||||
nsNavHistoryResult(nsNavHistory* aHistoryService,
|
||||
nsIStringBundle* aHistoryBundle,
|
||||
nsINavHistoryQuery** aQueries,
|
||||
PRUint32 aQueryCount,
|
||||
nsNavHistoryQueryOptions *aOptions);
|
||||
static nsresult NewHistoryResult(nsINavHistoryQuery** aQueries,
|
||||
PRUint32 aQueryCount,
|
||||
nsNavHistoryQueryOptions* aOptions,
|
||||
nsNavHistoryContainerResultNode* aRoot,
|
||||
nsNavHistoryResult** result);
|
||||
|
||||
// Two-stage init, MUST BE CALLED BEFORE ANYTHING ELSE
|
||||
nsresult Init();
|
||||
nsresult PropertyBagFor(nsISupports* aObject,
|
||||
nsIWritablePropertyBag** aBag);
|
||||
|
||||
nsCOMArray<nsNavHistoryResultNode>* GetTopLevel() { return &mChildren; }
|
||||
void ApplyTreeState(const nsDataHashtable<nsStringHashKey, int>& aExpanded);
|
||||
void FilledAllResults();
|
||||
|
||||
nsresult BuildChildrenFor(nsNavHistoryResultNode *aNode);
|
||||
|
||||
// These methods are typically called by child nodes from one of the
|
||||
// history or bookmark observer notifications.
|
||||
|
||||
// Notify the result that the entire contents of the tree have changed.
|
||||
void Invalidate();
|
||||
|
||||
// Notify the result that a row has been added at index aIndex relative
|
||||
// to aParent.
|
||||
void RowAdded(nsNavHistoryResultNode* aParent, PRInt32 aIndex);
|
||||
|
||||
// Notify the result that the row with visible index aVisibleIndex has been
|
||||
// removed from the tree.
|
||||
void RowRemoved(PRInt32 aVisibleIndex);
|
||||
|
||||
// Notify the result that the contents of the row at visible index
|
||||
// aVisibleIndex has been modified.
|
||||
void RowChanged(PRInt32 aVisibleIndex);
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSINAVHISTORYRESULT
|
||||
NS_DECL_NSITREEVIEW
|
||||
NS_FORWARD_NSINAVBOOKMARKOBSERVER(nsNavHistoryQueryNode::)
|
||||
NS_IMETHOD OnVisit(nsIURI* aURI, PRInt64 aVisitID, PRTime aTime,
|
||||
PRInt64 aSessionID, PRInt64 aReferringID,
|
||||
PRUint32 aTransitionType)
|
||||
{ return nsNavHistoryQueryNode::OnVisit(aURI, aVisitID, aTime, aSessionID,
|
||||
aReferringID, aTransitionType); }
|
||||
NS_IMETHOD OnDeleteURI(nsIURI *aURI)
|
||||
{ return nsNavHistoryQueryNode::OnDeleteURI(aURI); }
|
||||
NS_IMETHOD OnClearHistory()
|
||||
{ return nsNavHistoryQueryNode::OnClearHistory(); }
|
||||
NS_IMETHOD OnTitleChanged(nsIURI* aURI, const nsAString& aPageTitle,
|
||||
const nsAString& aUserTitle,
|
||||
PRBool aIsUserTitleChanged)
|
||||
{ return nsNavHistoryQueryNode::OnTitleChanged(aURI, aPageTitle, aUserTitle,
|
||||
aIsUserTitleChanged); }
|
||||
NS_IMETHOD OnPageChanged(nsIURI *aURI, PRUint32 aWhat,
|
||||
const nsAString &aValue)
|
||||
{ return nsNavHistoryQueryNode::OnPageChanged(aURI, aWhat, aValue); }
|
||||
NS_DECL_BOOKMARK_HISTORY_OBSERVER
|
||||
|
||||
NS_FORWARD_NSINAVHISTORYRESULTNODE(nsNavHistoryQueryNode::)
|
||||
// called by container nodes to update the tree when things change
|
||||
nsresult RefreshVisibleSection(nsNavHistoryContainerResultNode* aContainer);
|
||||
|
||||
private:
|
||||
void AddEverythingObserver(nsNavHistoryQueryResultNode* aNode);
|
||||
void AddBookmarkObserver(nsNavHistoryFolderResultNode* aNode, PRInt64 aFolder);
|
||||
void RemoveEverythingObserver(nsNavHistoryQueryResultNode* aNode);
|
||||
void RemoveBookmarkObserver(nsNavHistoryFolderResultNode* aNode, PRInt64 aFolder);
|
||||
|
||||
PRBool CanCollapseDuplicates(nsNavHistoryResultNode* aTop,
|
||||
nsNavHistoryResultNode* aNext,
|
||||
PRUint32* aShowThisOne);
|
||||
|
||||
public:
|
||||
// two-stage init, use NewHistoryResult to construct
|
||||
nsNavHistoryResult(nsNavHistoryContainerResultNode* mRoot);
|
||||
~nsNavHistoryResult();
|
||||
nsresult Init(nsINavHistoryQuery** aQueries,
|
||||
PRUint32 aQueryCount,
|
||||
nsNavHistoryQueryOptions *aOptions);
|
||||
|
||||
nsCOMPtr<nsIStringBundle> mBundle;
|
||||
nsCOMPtr<nsITreeBoxObject> mTree; // may be null if no tree has bound itself
|
||||
nsCOMPtr<nsITreeSelection> mSelection; // may be null
|
||||
nsRefPtr<nsNavHistoryContainerResultNode> mRootNode;
|
||||
|
||||
nsRefPtr<nsNavHistory> mHistoryService;
|
||||
nsCOMArray<nsINavHistoryQuery> mQueries;
|
||||
nsCOMPtr<nsNavHistoryQueryOptions> mOptions;
|
||||
|
||||
// One of nsNavHistoryQueryOptions.SORY_BY_* This is initialized to mOptions.sortingMode,
|
||||
// but may be overridden if the user clicks on one of the columns.
|
||||
PRUint32 mSortingMode;
|
||||
|
||||
PRBool mCollapseDuplicates;
|
||||
|
||||
nsMaybeWeakPtrArray<nsINavHistoryResultViewObserver> mObservers;
|
||||
|
||||
// for locale-specific date formatting and string sorting
|
||||
nsCOMPtr<nsILocale> mLocale;
|
||||
nsCOMPtr<nsICollation> mCollation;
|
||||
nsCOMPtr<nsIDateTimeFormat> mDateFormatter;
|
||||
|
||||
// this is the flattened version of the hierarchy containing everything
|
||||
nsVoidArray mAllElements;
|
||||
nsNavHistoryResultNode* AllElementAt(PRInt32 index)
|
||||
{
|
||||
return (nsNavHistoryResultNode*)mAllElements[index];
|
||||
}
|
||||
|
||||
nsVoidArray mVisibleElements;
|
||||
nsNavHistoryResultNode* VisibleElementAt(PRInt32 index)
|
||||
{
|
||||
return (nsNavHistoryResultNode*)mVisibleElements[index];
|
||||
}
|
||||
|
||||
// This value indicates whether we should try to compute session boundaries.
|
||||
// It is cached so we don't have to compute it every time we want to get a
|
||||
// row style.
|
||||
PRBool mShowSessions;
|
||||
void ComputeShowSessions();
|
||||
|
||||
void FillTreeStats(nsNavHistoryResultNode* aResult, PRInt32 aLevel);
|
||||
void InitializeVisibleList();
|
||||
void RebuildList();
|
||||
void RebuildAllListRecurse(const nsCOMArray<nsNavHistoryResultNode>& aSource);
|
||||
void BuildVisibleSection(const nsCOMArray<nsNavHistoryResultNode>& aSources,
|
||||
nsVoidArray* aVisible);
|
||||
void InsertVisibleSection(const nsVoidArray& aAddition, PRInt32 aInsertHere);
|
||||
PRInt32 DeleteVisibleChildrenOf(PRInt32 aIndex);
|
||||
// property bags for all result nodes, see PropertyBagFor
|
||||
nsInterfaceHashtable<nsISupportsHashKey, nsIWritablePropertyBag> mPropertyBags;
|
||||
|
||||
void RecursiveSortArray(nsCOMArray<nsNavHistoryResultNode>& aSources,
|
||||
PRUint32 aSortingMode);
|
||||
void SetTreeSortingIndicator();
|
||||
nsCOMPtr<nsITreeBoxObject> mTree; // will be null if no tree bound
|
||||
nsCOMPtr<nsITreeSelection> mSelection; // may be null
|
||||
|
||||
void RecursiveApplyTreeState(
|
||||
nsCOMArray<nsNavHistoryResultNode>& aList,
|
||||
const nsDataHashtable<nsStringHashKey, int>& aExpanded);
|
||||
void RecursiveExpandCollapse(nsCOMArray<nsNavHistoryResultNode>& aList,
|
||||
PRBool aExpand);
|
||||
// This list is maintained only when a tree is attached (mTree != null) to
|
||||
// the result. It is used to map rows to nodes.
|
||||
typedef nsTArray< nsCOMPtr<nsNavHistoryResultNode> > VisibleList;
|
||||
VisibleList mVisibleElements;
|
||||
nsresult BuildVisibleList();
|
||||
nsresult BuildVisibleSection(nsNavHistoryContainerResultNode* aContainer,
|
||||
VisibleList* aVisible,
|
||||
PRUint32 aVisibleStartIndex);
|
||||
PRUint32 CountVisibleRowsForItem(nsNavHistoryResultNode* aNode);
|
||||
|
||||
enum ColumnType { Column_Unknown = -1, Column_Title, Column_URL, Column_Date, Column_VisitCount };
|
||||
// node observers
|
||||
PRBool mIsHistoryObserver;
|
||||
PRBool mIsBookmarksObserver;
|
||||
nsTArray<nsNavHistoryQueryResultNode*> mEverythingObservers;
|
||||
typedef nsTArray<nsNavHistoryFolderResultNode*> FolderObserverList;
|
||||
nsDataHashtable<nsTrimInt64HashKey, FolderObserverList* > mBookmarkObservers;
|
||||
FolderObserverList* BookmarkObserversForId(PRInt64 aFolderId, PRBool aCreate);
|
||||
|
||||
// external observers
|
||||
nsMaybeWeakPtrArray<nsINavHistoryResultViewObserver> mObservers;
|
||||
|
||||
// columns
|
||||
enum ColumnType { Column_Unknown = -1, Column_Title, Column_URI, Column_Date,
|
||||
Column_VisitCount };
|
||||
ColumnType GetColumnType(nsITreeColumn* col);
|
||||
ColumnType SortTypeToColumnType(PRUint32 aSortType,
|
||||
PRBool* aDescending = nsnull);
|
||||
|
||||
PR_STATIC_CALLBACK(int) SortComparison_TitleLess(
|
||||
nsNavHistoryResultNode* a, nsNavHistoryResultNode* b, void* closure);
|
||||
PR_STATIC_CALLBACK(int) SortComparison_TitleGreater(
|
||||
nsNavHistoryResultNode* a, nsNavHistoryResultNode* b, void* closure);
|
||||
PR_STATIC_CALLBACK(int) SortComparison_DateLess(
|
||||
nsNavHistoryResultNode* a, nsNavHistoryResultNode* b, void* closure);
|
||||
PR_STATIC_CALLBACK(int) SortComparison_DateGreater(
|
||||
nsNavHistoryResultNode* a, nsNavHistoryResultNode* b, void* closure);
|
||||
PR_STATIC_CALLBACK(int) SortComparison_URLLess(
|
||||
nsNavHistoryResultNode* a, nsNavHistoryResultNode* b, void* closure);
|
||||
PR_STATIC_CALLBACK(int) SortComparison_URLGreater(
|
||||
nsNavHistoryResultNode* a, nsNavHistoryResultNode* b, void* closure);
|
||||
PR_STATIC_CALLBACK(int) SortComparison_VisitCountLess(
|
||||
nsNavHistoryResultNode* a, nsNavHistoryResultNode* b, void* closure);
|
||||
PR_STATIC_CALLBACK(int) SortComparison_VisitCountGreater(
|
||||
nsNavHistoryResultNode* a, nsNavHistoryResultNode* b, void* closure);
|
||||
void SetTreeSortingIndicator();
|
||||
void RecursiveExpandCollapse(nsNavHistoryContainerResultNode* aContainer,
|
||||
PRBool aExpand);
|
||||
|
||||
void InvalidateTree();
|
||||
|
||||
nsresult FormatFriendlyTime(PRTime aTime, nsAString& aResult);
|
||||
|
||||
// Notify the result that a row has been added at index aIndex relative
|
||||
// to aParent.
|
||||
void RowAdded(PRInt32 aVisibleIndex, nsNavHistoryResultNode* aNode);
|
||||
|
||||
// Notify the result that the row with visible index aVisibleIndex has been
|
||||
// removed from the tree.
|
||||
void RowsRemoved(PRInt32 aVisibleIndex, PRUint32 aCount = 1);
|
||||
|
||||
// Notify the result that the contents of the row at visible index
|
||||
// aVisibleIndex has been modified.
|
||||
void RowChanged(PRInt32 aVisibleIndex);
|
||||
|
||||
void RowReplaced(PRInt32 aVisibleIndex, nsNavHistoryResultNode* aNode);
|
||||
};
|
||||
|
||||
#endif // nsNavHistoryResult_h_
|
||||
|
Loading…
Reference in New Issue
Block a user