зеркало из https://github.com/mozilla/pjs.git
Bug 385245 ? history sidebar very slow (way slower than fx2) (for ondrej@allpeers.com, r=dietrich)
This commit is contained in:
Родитель
bec44c8676
Коммит
d084f217e0
|
@ -639,6 +639,10 @@ pref("browser.places.createdSmartBookmarks", false);
|
|||
// XXX to be removed after beta 2 (bug 391419)
|
||||
pref("browser.places.migratePostDataAnnotations", true);
|
||||
|
||||
// If true, will update the Smart Bookmarks uri for
|
||||
// recent tags (bug 385245). Useful just for FX3 beta users.
|
||||
pref("browser.places.updateRecentTagsUri", true);
|
||||
|
||||
// the (maximum) number of the recent visits to sample
|
||||
// when calculating frecency
|
||||
pref("places.frecency.numVisits", 10);
|
||||
|
|
|
@ -1024,7 +1024,7 @@ function placesMigrationTasks() {
|
|||
// XXX - REMOVE ME FOR BETA 3 (bug 391419)
|
||||
if (gPrefService.getBoolPref("browser.places.migratePostDataAnnotations")) {
|
||||
const annosvc = PlacesUtils.annotations;
|
||||
const bmsvc = PlacesUtils.bookmarks;
|
||||
var bmsvc = PlacesUtils.bookmarks;
|
||||
const oldPostDataAnno = "URIProperties/POSTData";
|
||||
var pages = annosvc.getPagesWithAnnotation(oldPostDataAnno, {});
|
||||
for (let i = 0; i < pages.length; i++) {
|
||||
|
@ -1048,4 +1048,30 @@ function placesMigrationTasks() {
|
|||
}
|
||||
gPrefService.setBoolPref("browser.places.migratePostDataAnnotations", false);
|
||||
}
|
||||
|
||||
if (gPrefService.getBoolPref("browser.places.updateRecentTagsUri")) {
|
||||
var bmsvc = PlacesUtils.bookmarks;
|
||||
var tagsFolder = bmsvc.tagsFolder;
|
||||
var oldUriSpec = "place:folder=" + tagsFolder + "&group=3&queryType=1"+
|
||||
"&applyOptionsToContainers=1&sort=12&maxResults=10";
|
||||
|
||||
var maxResults = 10;
|
||||
var newUriSpec = "place:type=" +
|
||||
Ci.nsINavHistoryQueryOptions.RESULTS_AS_TAG_QUERY +
|
||||
"&sort=" +
|
||||
Ci.nsINavHistoryQueryOptions.SORT_BY_DATEADDED_DESCENDING +
|
||||
"&maxResults=" + maxResults;
|
||||
|
||||
var ios = Cc["@mozilla.org/network/io-service;1"].
|
||||
getService(Ci.nsIIOService);
|
||||
|
||||
var oldUri = ios.newURI(oldUriSpec, null, null);
|
||||
var newUri = ios.newURI(newUriSpec, null, null);
|
||||
|
||||
let bookmarks = bmsvc.getBookmarkIdsForURI( oldUri, {});
|
||||
for (let i = 0; i < bookmarks.length; i++) {
|
||||
bmsvc.changeBookmarkURI( bookmarks[i], newUri);
|
||||
}
|
||||
gPrefService.setBoolPref("browser.places.updateRecentTagsUri", false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -539,7 +539,6 @@ BrowserGlue.prototype = {
|
|||
var bookmarksMenuFolder = bmsvc.bookmarksMenuFolder;
|
||||
var unfiledBookmarksFolder = bmsvc.unfiledBookmarksFolder;
|
||||
var toolbarFolder = bmsvc.toolbarFolder;
|
||||
var tagsFolder = bmsvc.tagsFolder;
|
||||
var defaultIndex = bmsvc.DEFAULT_INDEX;
|
||||
|
||||
// index = 0, make it the first folder
|
||||
|
@ -574,14 +573,11 @@ BrowserGlue.prototype = {
|
|||
var sep = bmsvc.insertSeparator(placesFolder, defaultIndex);
|
||||
|
||||
var recentTagsItem = bmsvc.insertBookmark(placesFolder,
|
||||
this._uri("place:folder=" + tagsFolder +
|
||||
"&group=" + Ci.nsINavHistoryQueryOptions.GROUP_BY_FOLDER +
|
||||
"&queryType=" + Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS +
|
||||
"&applyOptionsToContainers=1" +
|
||||
"&sort=" +
|
||||
Ci.nsINavHistoryQueryOptions.SORT_BY_DATEADDED_DESCENDING +
|
||||
this._uri("place:"+
|
||||
"type=" + Ci.nsINavHistoryQueryOptions.RESULTS_AS_TAG_QUERY +
|
||||
"&sort=" + Ci.nsINavHistoryQueryOptions.SORT_BY_DATEADDED_DESCENDING +
|
||||
"&maxResults=" + maxResults),
|
||||
defaultIndex, recentTagsTitle);
|
||||
defaultIndex, recentTagsTitle);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -413,6 +413,17 @@ PlacesController.prototype = {
|
|||
switch(nodeType) {
|
||||
case Ci.nsINavHistoryResultNode.RESULT_TYPE_QUERY:
|
||||
nodeData["query"] = true;
|
||||
if (node.parent) {
|
||||
switch (asQuery(node.parent).queryOptions.resultType) {
|
||||
case Ci.nsINavHistoryQueryOptions.RESULTS_AS_SITE_QUERY:
|
||||
nodeData["host"] = true;
|
||||
break;
|
||||
case Ci.nsINavHistoryQueryOptions.RESULTS_AS_DATE_SITE_QUERY:
|
||||
case Ci.nsINavHistoryQueryOptions.RESULTS_AS_DATE_QUERY:
|
||||
nodeData["day"] = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Ci.nsINavHistoryResultNode.RESULT_TYPE_DYNAMIC_CONTAINER:
|
||||
nodeData["dynamiccontainer"] = true;
|
||||
|
@ -421,9 +432,6 @@ PlacesController.prototype = {
|
|||
case Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER_SHORTCUT:
|
||||
nodeData["folder"] = true;
|
||||
break;
|
||||
case Ci.nsINavHistoryResultNode.RESULT_TYPE_HOST:
|
||||
nodeData["host"] = true;
|
||||
break;
|
||||
case Ci.nsINavHistoryResultNode.RESULT_TYPE_SEPARATOR:
|
||||
nodeData["separator"] = true;
|
||||
break;
|
||||
|
@ -442,8 +450,6 @@ PlacesController.prototype = {
|
|||
nodeData["livemarkChild"] = true;
|
||||
}
|
||||
break;
|
||||
case Ci.nsINavHistoryResultNode.RESULT_TYPE_DAY:
|
||||
nodeData["day"] = true;
|
||||
}
|
||||
|
||||
// Mutability is whether or not a container can have selected items
|
||||
|
@ -903,14 +909,16 @@ PlacesController.prototype = {
|
|||
// day nodes have time property set to the last day in the interval
|
||||
var endDate = node.time;
|
||||
|
||||
// if this is not the last day container, then beginDate
|
||||
// is the time property of the next day container
|
||||
for (var j = 0; j < root.childCount-1 && !beginDate; ++j) {
|
||||
if (root.getChild(j) != node)
|
||||
continue;
|
||||
var nextNode = root.getChild(j+1);
|
||||
beginDate = nextNode.time
|
||||
}
|
||||
var nodeIdx = 0;
|
||||
var cc = root.childCount;
|
||||
|
||||
// Find index of current day node
|
||||
while (nodeIdx < cc && root.getChild(nodeIdx) != node)
|
||||
++nodeIdx;
|
||||
|
||||
// We have an older day
|
||||
if (nodeIdx+1 < cc)
|
||||
beginDate = root.getChild(nodeIdx+1).time;
|
||||
|
||||
// we want to exclude beginDate from the removal
|
||||
bhist.removePagesByTimeframe(beginDate+1, endDate);
|
||||
|
|
|
@ -114,7 +114,6 @@ function searchHistory(aInput)
|
|||
|
||||
const NHQO = Ci.nsINavHistoryQueryOptions;
|
||||
var sortingMode;
|
||||
var groups = [];
|
||||
var resultType;
|
||||
|
||||
if (aInput) {
|
||||
|
@ -132,22 +131,20 @@ function searchHistory(aInput)
|
|||
resultType = NHQO.RESULTS_AS_URI;
|
||||
sortingMode = NHQO.SORT_BY_DATE_DESCENDING;
|
||||
break;
|
||||
case "dayandsite": // fall through
|
||||
groups.push(NHQO.GROUP_BY_DAY);
|
||||
case "dayandsite":
|
||||
resultType = NHQO.RESULTS_AS_DATE_SITE_QUERY;
|
||||
break;
|
||||
case "site":
|
||||
groups.push(NHQO.GROUP_BY_HOST);
|
||||
resultType = NHQO.RESULTS_AS_VISIT;
|
||||
resultType = NHQO.RESULTS_AS_SITE_QUERY;
|
||||
sortingMode = NHQO.SORT_BY_TITLE_ASCENDING;
|
||||
break;
|
||||
case "day":
|
||||
default:
|
||||
resultType = NHQO.RESULTS_AS_VISIT;
|
||||
groups.push(NHQO.GROUP_BY_DAY);
|
||||
sortingMode = NHQO.SORT_BY_TITLE_ASCENDING;
|
||||
resultType = NHQO.RESULTS_AS_DATE_QUERY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
options.setGroupingMode(groups, groups.length);
|
||||
options.sortingMode = sortingMode;
|
||||
options.resultType = resultType;
|
||||
|
||||
|
|
|
@ -97,15 +97,6 @@
|
|||
var query = PlacesUtils.history.getNewQuery();
|
||||
query.searchTerms = filterString;
|
||||
|
||||
// Remove "group by folder" from the options list, because
|
||||
// nsNavHistory::RecursiveGroup doesn't support it.
|
||||
function isFolderGrouping(grouping, index, ary) {
|
||||
return grouping != Ci.nsINavHistoryQueryOptions.GROUP_BY_FOLDER;
|
||||
}
|
||||
var groupings = options.getGroupingMode({});
|
||||
var folderGroupings = groupings.filter(isFolderGrouping);
|
||||
options.setGroupingMode(folderGroupings, folderGroupings.length);
|
||||
|
||||
if (folderRestrict) {
|
||||
query.setFolders(folderRestrict, folderRestrict.length);
|
||||
options.queryType = options.QUERY_TYPE_BOOKMARKS;
|
||||
|
|
|
@ -85,6 +85,13 @@ PlacesTreeView.prototype = {
|
|||
if (this._tree && this._result)
|
||||
this.sortingChanged(this._result.sortingMode);
|
||||
|
||||
var qoInt = Ci.nsINavHistoryQueryOptions;
|
||||
var options = asQuery(this._result.root).queryOptions;
|
||||
this._showQueryAsFolder = (options &&
|
||||
(options.resultType == qoInt.RESULTS_AS_DATE_QUERY ||
|
||||
options.resultType == qoInt.RESULTS_AS_SITE_QUERY ||
|
||||
options.resultType == qoInt.RESULTS_AS_DATE_SITE_QUERY));
|
||||
|
||||
// if there is no tree, BuildVisibleList will clear everything for us
|
||||
this._buildVisibleList();
|
||||
},
|
||||
|
@ -109,14 +116,6 @@ PlacesTreeView.prototype = {
|
|||
sortType != nsINavHistoryQueryOptions::SORT_BY_DATE_DESCENDING)
|
||||
return; // not date sorting
|
||||
|
||||
// showing sessions only makes sense if we are grouping by date
|
||||
// any other grouping (or recursive grouping) doesn't make sense
|
||||
var groupings = options.getGroupingMode({});
|
||||
for (var i=0; i < groupings.length; i++) {
|
||||
if (groupings[i] != Ci.nsINavHistoryQueryOptions.GROUP_BY_DAY)
|
||||
return; // non-time-based grouping
|
||||
}
|
||||
|
||||
this._showSessions = true;
|
||||
},
|
||||
|
||||
|
@ -200,26 +199,6 @@ PlacesTreeView.prototype = {
|
|||
var curChild = aContainer.getChild(i);
|
||||
var curChildType = curChild.type;
|
||||
|
||||
// collapse all duplicates starting from here
|
||||
if (this._collapseDuplicates) {
|
||||
var showThis = { value: false };
|
||||
while (i < cc - 1 &&
|
||||
this._canCollapseDuplicates(curChild, aContainer.getChild(i+1),
|
||||
showThis)) {
|
||||
if (showThis.value) {
|
||||
// collapse the first and use the second
|
||||
curChild.viewIndex = -1;
|
||||
curChild = aContainer.getChild(i+1);
|
||||
curChildType = curChild.type;
|
||||
}
|
||||
else {
|
||||
// collapse the second and use the first
|
||||
aContainer.getChild(i+1).viewIndex = -1;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
// don't display separators when sorted
|
||||
if (curChildType == Ci.nsINavHistoryResultNode.RESULT_TYPE_SEPARATOR) {
|
||||
if (this._result.sortingMode !=
|
||||
|
@ -418,30 +397,6 @@ PlacesTreeView.prototype = {
|
|||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* This returns true if the two results can be collapsed as duplicates.
|
||||
* aShowThisOne will be either 0 or 1, indicating which of the
|
||||
* duplicates should be shown.
|
||||
*/
|
||||
_canCollapseDuplicates:
|
||||
function PTV__canCollapseDuplicate(aTop, aNext, aShowThisOne) {
|
||||
if (!this._collapseDuplicates)
|
||||
return false;
|
||||
if (!PlacesUtils.nodeIsVisit(aTop) ||
|
||||
!PlacesUtils.nodeIsVisit(aNext))
|
||||
return false; // only collapse two visits
|
||||
|
||||
asVisit(aTop);
|
||||
asVisit(aNext);
|
||||
|
||||
if (aTop.uri != aNext.uri)
|
||||
return false; // don't collapse nonmatching URIs
|
||||
|
||||
// now we know we want to collapse, show the one with the more recent time
|
||||
aShowThisOne.value = aTop.time < aNext.time;
|
||||
return true;
|
||||
},
|
||||
|
||||
_convertPRTimeToString: function PTV__convertPRTimeToString(aTime) {
|
||||
var timeInMilliseconds = aTime / 1000; // PRTime is in microseconds
|
||||
var timeObj = new Date(timeInMilliseconds);
|
||||
|
@ -600,44 +555,6 @@ PlacesTreeView.prototype = {
|
|||
}
|
||||
}
|
||||
|
||||
// Try collapsing with the previous node. Note that we do not have to try
|
||||
// to redraw the surrounding rows (which we normally would because session
|
||||
// boundaries may have changed) because when an item is merged, it will
|
||||
// always be in the same session.
|
||||
var showThis = { value: true };
|
||||
if (newViewIndex > 0 &&
|
||||
this._canCollapseDuplicates
|
||||
(this._visibleElements[newViewIndex - 1], aItem, showThis)) {
|
||||
if (!showThis.value) {
|
||||
// new node is invisible, collapsed with previous one
|
||||
aItem.viewIndex = -1;
|
||||
}
|
||||
else {
|
||||
// new node replaces the previous
|
||||
this.itemReplaced(aParent, this._visibleElements[newViewIndex - 1],
|
||||
aItem, 0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// try collapsing with the next node (which is currently at the same
|
||||
// index we are trying to insert at)
|
||||
if (newViewIndex < this._visibleElements.length &&
|
||||
this._canCollapseDuplicates(aItem, this._visibleElements[newViewIndex],
|
||||
showThis)) {
|
||||
if (!showThis.value) {
|
||||
// new node replaces the next node
|
||||
this.itemReplaced(aParent, this._visibleElements[newViewIndex], aItem,
|
||||
0);
|
||||
}
|
||||
else {
|
||||
// new node is invisible, replaced by next one
|
||||
aItem.viewIndex = -1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// no collapsing, insert new item
|
||||
aItem.viewIndex = newViewIndex;
|
||||
this._visibleElements.splice(newViewIndex, 0, aItem);
|
||||
for (var i = newViewIndex + 1;
|
||||
|
@ -668,40 +585,14 @@ PlacesTreeView.prototype = {
|
|||
// this may have been a container, in which case it has a lot of rows
|
||||
var count = this._countVisibleRowsForItem(aItem);
|
||||
|
||||
// We really want tail recursion here, since we sometimes do another
|
||||
// remove after this when duplicates are being collapsed. This loop
|
||||
// emulates that.
|
||||
while (true) {
|
||||
if (oldViewIndex > this._visibleElements.length)
|
||||
throw("Trying to remove an item with an invalid viewIndex");
|
||||
if (oldViewIndex > this._visibleElements.length)
|
||||
throw("Trying to remove an item with an invalid viewIndex");
|
||||
|
||||
this._visibleElements.splice(oldViewIndex, count);
|
||||
for (var i = oldViewIndex; i < this._visibleElements.length; i++)
|
||||
this._visibleElements[i].viewIndex = i;
|
||||
this._visibleElements.splice(oldViewIndex, count);
|
||||
for (var i = oldViewIndex; i < this._visibleElements.length; i++)
|
||||
this._visibleElements[i].viewIndex = i;
|
||||
|
||||
this._tree.rowCountChanged(oldViewIndex, -count);
|
||||
|
||||
// the removal might have put two things together that should be collapsed
|
||||
if (oldViewIndex > 0 &&
|
||||
oldViewIndex < this._visibleElements.length) {
|
||||
var showThisOne = { value: true };
|
||||
if (this._canCollapseDuplicates
|
||||
(this._visibleElements[oldViewIndex - 1],
|
||||
this._visibleElements[oldViewIndex], showThisOne))
|
||||
{
|
||||
// Fake-tail-recurse to the beginning of this function to
|
||||
// remove the collapsed row. Note that we need to set the
|
||||
// visible index to -1 before looping because we can never
|
||||
// touch the row we're removing (callers may have already
|
||||
// destroyed it).
|
||||
oldViewIndex = oldViewIndex - 1 + (showThisOne.value ? 1 : 0);
|
||||
this._visibleElements[oldViewIndex].viewIndex = -1;
|
||||
count = 1; // next time remove one row
|
||||
continue;
|
||||
}
|
||||
}
|
||||
break; // normal path: just remove once
|
||||
}
|
||||
this._tree.rowCountChanged(oldViewIndex, -count);
|
||||
|
||||
// redraw parent because twisty may have changed
|
||||
if (!aParent.hasChildren)
|
||||
|
@ -917,22 +808,6 @@ PlacesTreeView.prototype = {
|
|||
return val;
|
||||
},
|
||||
|
||||
// nsINavHistoryResultTreeViewer
|
||||
get collapseDuplicates() {
|
||||
return this._collapseDuplicates;
|
||||
},
|
||||
|
||||
set collapseDuplicates(val) {
|
||||
if (this._collapseDuplicates == val)
|
||||
return val; // no change;
|
||||
|
||||
this._collapseDuplicates = val;
|
||||
if (this._tree && this._result)
|
||||
this.invalidateAll();
|
||||
|
||||
return val;
|
||||
},
|
||||
|
||||
nodeForTreeIndex: function PTV_nodeForTreeIndex(aIndex) {
|
||||
if (aIndex > this._visibleElements.length)
|
||||
throw Cr.NS_ERROR_INVALID_ARG;
|
||||
|
@ -1007,10 +882,12 @@ PlacesTreeView.prototype = {
|
|||
|
||||
var nodeType = node.type;
|
||||
if (PlacesUtils.containerTypes.indexOf(nodeType) != -1) {
|
||||
if (nodeType == Ci.nsINavHistoryResultNode.RESULT_TYPE_QUERY)
|
||||
if (nodeType == Ci.nsINavHistoryResultNode.RESULT_TYPE_QUERY) {
|
||||
aProperties.AppendElement(this._getAtomFor("query"));
|
||||
else if (nodeType == Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER ||
|
||||
nodeType == Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER_SHORTCUT) {
|
||||
if (this._showQueryAsFolder)
|
||||
aProperties.AppendElement(this._getAtomFor("folder"));
|
||||
} else if (nodeType == Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER ||
|
||||
nodeType == Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER_SHORTCUT) {
|
||||
if (PlacesUtils.annotations.itemHasAnnotation(node.itemId,
|
||||
LMANNO_FEEDURI))
|
||||
aProperties.AppendElement(this._getAtomFor("livemark"));
|
||||
|
@ -1467,7 +1344,6 @@ function PlacesTreeView(aShowRoot, aFlatList, aOnOpenFlatContainer) {
|
|||
|
||||
this._tree = null;
|
||||
this._result = null;
|
||||
this._collapseDuplicates = true;
|
||||
this._showSessions = false;
|
||||
this._selection = null;
|
||||
this._visibleElements = [];
|
||||
|
|
|
@ -349,7 +349,10 @@ var PlacesUtils = {
|
|||
*/
|
||||
nodeIsHost: function PU_nodeIsHost(aNode) {
|
||||
NS_ASSERT(aNode, "null node");
|
||||
return aNode.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_HOST;
|
||||
return aNode.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_QUERY &&
|
||||
aNode.parent &&
|
||||
asQuery(aNode.parent).queryOptions.resultType ==
|
||||
Ci.nsINavHistoryQueryOptions.RESULTS_AS_SITE_QUERY;
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -359,7 +362,13 @@ var PlacesUtils = {
|
|||
* @returns true if the node is a day container, false otherwise
|
||||
*/
|
||||
nodeIsDay: function PU_nodeIsDay(aNode) {
|
||||
return aNode.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_DAY;
|
||||
NS_ASSERT(aNode, "null node");
|
||||
var resultType;
|
||||
return aNode.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_QUERY &&
|
||||
aNode.parent &&
|
||||
((resultType = asQuery(aNode.parent).queryOptions.resultType) ==
|
||||
Ci.nsINavHistoryQueryOptions.RESULTS_AS_DATE_QUERY ||
|
||||
resultType == Ci.nsINavHistoryQueryOptions.RESULTS_AS_DATE_SITE_QUERY);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -371,8 +380,6 @@ var PlacesUtils = {
|
|||
containerTypes: [Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER,
|
||||
Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER_SHORTCUT,
|
||||
Ci.nsINavHistoryResultNode.RESULT_TYPE_QUERY,
|
||||
Ci.nsINavHistoryResultNode.RESULT_TYPE_HOST,
|
||||
Ci.nsINavHistoryResultNode.RESULT_TYPE_DAY,
|
||||
Ci.nsINavHistoryResultNode.RESULT_TYPE_DYNAMIC_CONTAINER],
|
||||
nodeIsContainer: function PU_nodeIsContainer(aNode) {
|
||||
NS_ASSERT(aNode, "null node");
|
||||
|
@ -1666,11 +1673,8 @@ var PlacesUtils = {
|
|||
// Include visible url nodes only
|
||||
let child = aNode.getChild(i);
|
||||
if (this.nodeIsURI(child)) {
|
||||
// If the node contents is visible, add the uri only if its node is
|
||||
// visible. Otherwise follow viewer's collapseDuplicates property,
|
||||
// default to true
|
||||
// If the node contents is visible, add the uri
|
||||
if ((wasOpen && oldViewer && child.viewIndex != -1) ||
|
||||
(oldViewer && !oldViewer.collapseDuplicates) ||
|
||||
urls.indexOf(child.uri) == -1) {
|
||||
urls.push({ uri: child.uri,
|
||||
isBookmark: this.nodeIsBookmark(child) });
|
||||
|
|
|
@ -50,6 +50,12 @@ treechildren::-moz-tree-image(title, query) {
|
|||
-moz-image-region: auto;
|
||||
}
|
||||
|
||||
/* We want some queries to look like ordinary folders. This must come
|
||||
after the (title, query) selector, or it would get overridden. */
|
||||
treechildren::-moz-tree-image(title, query, folder) {
|
||||
list-style-image: url("moz-icon://stock/gtk-directory?size=menu");
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-row(session-start) {
|
||||
border-top:1px dotted ThreeDShadow;
|
||||
font-weight: bold;
|
||||
|
|
|
@ -135,6 +135,14 @@ treechildren::-moz-tree-image(query) {
|
|||
list-style-image: url("chrome://browser/skin/places/query.png");
|
||||
}
|
||||
|
||||
/* We want some queries to look like ordinary folders. This must come
|
||||
after the (title, query) selector, or it would get overridden. */
|
||||
treechildren::-moz-tree-image(title, query, folder),
|
||||
treechildren::-moz-tree-image(title, query, folder, open) {
|
||||
list-style-image: url("chrome://global/skin/tree/folder.png");
|
||||
-moz-image-region: rect(0, 16px, 16px, 0);
|
||||
}
|
||||
|
||||
/* FIXME this should make the date field invisible, but only does it for
|
||||
unselected items and maybe won't work for different color schemes. */
|
||||
treechildren::-moz-tree-cell-text(date, session-continue) {
|
||||
|
|
|
@ -58,6 +58,17 @@ treechildren::-moz-tree-image(title, query) {
|
|||
-moz-image-region: auto;
|
||||
}
|
||||
|
||||
/* We want some queries to look like ordinary folders. This must come
|
||||
after the (title, query) selector, or it would get overridden. */
|
||||
treechildren::-moz-tree-image(title, query, folder) {
|
||||
list-style-image: url("chrome://global/skin/icons/folder-item.png");
|
||||
-moz-image-region: rect(0px, 32px, 16px, 16px);
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-image(title, query, folder, open) {
|
||||
-moz-image-region: rect(16px, 32px, 32px, 16px);
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-row(session-start) {
|
||||
border-top:1px dotted ThreeDShadow;
|
||||
font-weight: bold;
|
||||
|
|
|
@ -79,17 +79,15 @@ interface nsINavHistoryResultNode : nsISupports
|
|||
const unsigned long RESULT_TYPE_URI = 0; // nsINavHistoryResultNode
|
||||
const unsigned long RESULT_TYPE_VISIT = 1; // nsINavHistoryVisitResultNode
|
||||
const unsigned long RESULT_TYPE_FULL_VISIT = 2; // nsINavHistoryFullVisitResultNode
|
||||
const unsigned long RESULT_TYPE_HOST = 3; // nsINavHistoryContainerResultNode
|
||||
const unsigned long RESULT_TYPE_DYNAMIC_CONTAINER = 4; // nsINavHistoryContainerResultNode
|
||||
const unsigned long RESULT_TYPE_QUERY = 5; // nsINavHistoryQueryResultNode
|
||||
const unsigned long RESULT_TYPE_FOLDER = 6; // nsINavHistoryQueryResultNode
|
||||
const unsigned long RESULT_TYPE_SEPARATOR = 7; // nsINavHistoryResultNode
|
||||
const unsigned long RESULT_TYPE_DAY = 8; // nsINavHistoryContainerResultNode
|
||||
const unsigned long RESULT_TYPE_FOLDER_SHORTCUT = 9; // nsINavHistoryQueryResultNode
|
||||
readonly attribute unsigned long type;
|
||||
|
||||
/**
|
||||
* Title of the web page, or of the node's grouping (day, host, folder, etc)
|
||||
* Title of the web page, or of the node's query (day, host, folder, etc)
|
||||
*/
|
||||
readonly attribute AUTF8String title;
|
||||
|
||||
|
@ -113,8 +111,8 @@ interface nsINavHistoryResultNode : nsISupports
|
|||
* 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.
|
||||
* For days queries this is the respective endTime - a maximum possible
|
||||
* visit time to fit in the day range.
|
||||
*/
|
||||
readonly attribute PRTime time;
|
||||
|
||||
|
@ -340,8 +338,8 @@ interface nsINavHistoryContainerResultNode : nsINavHistoryResultNode
|
|||
* container API. TO BE CALLED FROM nsIDynamicContainer::OnContainerOpening()
|
||||
* ONLY, and only for non-bookmark-folder containers.
|
||||
*
|
||||
* aContainerType should be either RESULT_TYPE_HOST or
|
||||
* RESULT_TYPE_DYNAMIC_CONTAINER. When type is dynamic container you must
|
||||
* aContainerType should be RESULT_TYPE_DYNAMIC_CONTAINER.
|
||||
* When type is dynamic container you must
|
||||
* specify a dynamic container type, otherwise, the dynamic container type must
|
||||
* be null. Use appendQueryNode and appendFolderNode for the other container
|
||||
* types.
|
||||
|
@ -500,8 +498,7 @@ interface nsINavHistoryResultViewer : nsISupports
|
|||
|
||||
/**
|
||||
* Called when something significant is changing that requires everything
|
||||
* to be recomputed. For example, changing sorting or changing collapse
|
||||
* duplicates can affect every row.
|
||||
* to be recomputed. For example, changing sorting can affect every row.
|
||||
*/
|
||||
void invalidateAll();
|
||||
|
||||
|
@ -537,24 +534,9 @@ interface nsINavHistoryResultViewer : nsISupports
|
|||
* object, attach it to a result, never attach it to a tree, and forget about
|
||||
* it, it will leak!
|
||||
*/
|
||||
[scriptable, uuid(e0ce87df-8b77-407b-a52b-7510eab14fb5)]
|
||||
[scriptable, uuid(fa77e4e9-9fc8-45d2-9507-0fe4f0602505)]
|
||||
interface nsINavHistoryResultTreeViewer : nsINavHistoryResultViewer
|
||||
{
|
||||
/**
|
||||
* Controls whether duplicate adjacent elements are collapsed into a single
|
||||
* item in the tree. This prevents you from seeing multiple entries for
|
||||
* 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 URIs back instead of
|
||||
* visits so it will be more efficient.
|
||||
* Default = true
|
||||
*
|
||||
* Changing this value is somewhat heavyweight since it will force a tree
|
||||
* refresh.
|
||||
*/
|
||||
attribute boolean collapseDuplicates;
|
||||
|
||||
/**
|
||||
* This allows you to get at the real node for a given row index. This is
|
||||
* only valid when a tree is attached.
|
||||
|
@ -637,7 +619,7 @@ interface nsINavHistoryResult : nsISupports
|
|||
* DANGER! If you are in the middle of a batch transaction, there may be a
|
||||
* database transaction active. You can still access the DB, but be careful.
|
||||
*/
|
||||
[scriptable, uuid(849e2184-3dee-416f-91cd-6a619ca49d1c)]
|
||||
[scriptable, uuid(eacb76eb-3eeb-419b-a963-9b3a9d65f356)]
|
||||
interface nsINavHistoryObserver : nsISupports
|
||||
{
|
||||
/**
|
||||
|
@ -666,10 +648,14 @@ interface nsINavHistoryObserver : nsISupports
|
|||
* @param aSessionID The ID of one connected sequence of visits.
|
||||
* @param aReferringID The ID of the visit the user came from. 0 if empty.
|
||||
* @param aTransitionType One of nsINavHistory.TRANSITION_*
|
||||
* @param aAdded Incremented by query nodes when the visited uri
|
||||
* belongs to them. If no such query exists, the
|
||||
* history result creates a new query node dynamically.
|
||||
* It is used in places views only and can be ignored.
|
||||
*/
|
||||
void onVisit(in nsIURI aURI, in long long aVisitID, in PRTime aTime,
|
||||
in long long aSessionID, in long long aReferringID,
|
||||
in unsigned long aTransitionType);
|
||||
in unsigned long aTransitionType, out unsigned long aAdded);
|
||||
|
||||
/**
|
||||
* Called whenever either the "real" title or the custom title of the page
|
||||
|
@ -868,41 +854,9 @@ interface nsINavHistoryQuery : nsISupports
|
|||
/**
|
||||
* This object represents the global options for executing a query.
|
||||
*/
|
||||
[scriptable, uuid(ff73bf85-2755-4c1a-a48d-8c91ccca770e)]
|
||||
[scriptable, uuid(a46c132e-35f3-4e1e-bb3d-4e3043657248)]
|
||||
interface nsINavHistoryQueryOptions : nsISupports
|
||||
{
|
||||
/**
|
||||
* Grouping by day. The results will be an array of nsINavHistoryResults with
|
||||
* type = RESULT_TYPE_DAY, one for each day where there are results. These
|
||||
* will have children of corresponding to the search results of that day.
|
||||
*/
|
||||
const unsigned short GROUP_BY_DAY = 0;
|
||||
|
||||
/**
|
||||
* Grouping by exact host. The results will be an array of nsINavHistoryResults
|
||||
* with type = RESULT_TYPE_HOST, one for each unique host (for example,
|
||||
* "bugzilla.mozilla.org" and "www.mozilla.org" will be separate). The
|
||||
* children of these will correspond to the results for each host.
|
||||
*/
|
||||
const unsigned short GROUP_BY_HOST = 1;
|
||||
|
||||
/**
|
||||
* Grouping by toplevel domain. Similar to GROUP_BY_HOST, but there will be
|
||||
* one result for each toplevel domain (mozilla.org will be one entry, and
|
||||
* will contain results including, for example, "bugzilla.mozilla.org" and
|
||||
* "www.mozilla.org").
|
||||
*/
|
||||
const unsigned short GROUP_BY_DOMAIN = 2;
|
||||
|
||||
/**
|
||||
* Group by bookmark folders. Results from the query are grouped in folders
|
||||
* containers. This option requires there to be at least one parent folder specified
|
||||
* via nsINavHistoryQuery::setFolders. Note, since the folder containers are built
|
||||
* from the items that match the results that we are grouping, you will not get any
|
||||
* folders (when grouping by folder) with zero items.
|
||||
*/
|
||||
const unsigned short GROUP_BY_FOLDER = 3;
|
||||
|
||||
/**
|
||||
* You can ask for the results to be pre-sorted. Since the DB has indices
|
||||
* of many items, it can produce sorted results almost for free. These should
|
||||
|
@ -928,8 +882,6 @@ interface nsINavHistoryQueryOptions : nsISupports
|
|||
const unsigned short SORT_BY_DATEADDED_DESCENDING = 12;
|
||||
const unsigned short SORT_BY_LASTMODIFIED_ASCENDING = 13;
|
||||
const unsigned short SORT_BY_LASTMODIFIED_DESCENDING = 14;
|
||||
const unsigned short SORT_BY_COUNT_ASCENDING = 15;
|
||||
const unsigned short SORT_BY_COUNT_DESCENDING = 16;
|
||||
const unsigned short SORT_BY_TAGS_ASCENDING = 17;
|
||||
const unsigned short SORT_BY_TAGS_DESCENDING = 18;
|
||||
const unsigned short SORT_BY_ANNOTATION_ASCENDING = 19;
|
||||
|
@ -958,18 +910,32 @@ interface nsINavHistoryQueryOptions : nsISupports
|
|||
const unsigned short RESULTS_AS_FULL_VISIT = 2;
|
||||
|
||||
/**
|
||||
* The grouping mode to be used for this query.
|
||||
* Grouping mode is an array of GROUP_BY_* values that specifies the
|
||||
* structure of the tree you want. For example, an array consisting of
|
||||
* [GROUP_BY_DAY, GROUP_BY_DOMAIN] will give you a tree whose first level is
|
||||
* a list of days, and whose second level is a list of domains, and whose
|
||||
* third level is a list of pages in those domains.
|
||||
* If you don't want grouping, you can specify an empty array.
|
||||
* This returns query nodes for each predefined date range where we
|
||||
* had visits. The node contains information how to load its content:
|
||||
* - visits for the given date range will be loaded.
|
||||
*/
|
||||
void getGroupingMode(out unsigned long groupCount,
|
||||
[retval,array,size_is(groupCount)] out unsigned short groupingMode);
|
||||
void setGroupingMode([const,array,size_is(groupCount)] in unsigned short groupingMode,
|
||||
in unsigned long groupCount);
|
||||
const unsigned short RESULTS_AS_DATE_QUERY = 3;
|
||||
|
||||
/**
|
||||
* This returns nsINavHistoryQueryResultNode nodes for each site where we
|
||||
* have visits. The node contains information how to load its content:
|
||||
* - last visit for each url in the given host will be loaded.
|
||||
*/
|
||||
const unsigned short RESULTS_AS_SITE_QUERY = 4;
|
||||
|
||||
/**
|
||||
* This returns nsINavHistoryQueryResultNode nodes for each day where we
|
||||
* have visits. The node contains information how to load its content:
|
||||
* - list of hosts visited in the given period will be loaded.
|
||||
*/
|
||||
const unsigned short RESULTS_AS_DATE_SITE_QUERY = 5;
|
||||
|
||||
/**
|
||||
* This returns nsINavHistoryQueryResultNode nodes for each tag.
|
||||
* The node contains information how to load its content:
|
||||
* - list of bookmarks with the given tag will be loaded.
|
||||
*/
|
||||
const unsigned short RESULTS_AS_TAG_QUERY = 6;
|
||||
|
||||
/**
|
||||
* The sorting mode to be used for this query.
|
||||
|
@ -1063,11 +1029,6 @@ interface nsINavHistoryQueryOptions : nsISupports
|
|||
*/
|
||||
attribute unsigned long maxResults;
|
||||
|
||||
/**
|
||||
* only apply our query options to the containers
|
||||
*/
|
||||
attribute boolean applyOptionsToContainers;
|
||||
|
||||
const unsigned short QUERY_TYPE_HISTORY = 0;
|
||||
const unsigned short QUERY_TYPE_BOOKMARKS = 1;
|
||||
const unsigned short QUERY_TYPE_UNIFIED = 2;
|
||||
|
|
|
@ -2608,7 +2608,7 @@ nsNavBookmarks::OnEndUpdateBatch()
|
|||
NS_IMETHODIMP
|
||||
nsNavBookmarks::OnVisit(nsIURI *aURI, PRInt64 aVisitID, PRTime aTime,
|
||||
PRInt64 aSessionID, PRInt64 aReferringID,
|
||||
PRUint32 aTransitionType)
|
||||
PRUint32 aTransitionType, PRUint32* aAdded)
|
||||
{
|
||||
// If the page is bookmarked, we need to notify observers
|
||||
PRBool bookmarked = PR_FALSE;
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -94,6 +94,7 @@
|
|||
#define QUERYUPDATE_SIMPLE 1
|
||||
#define QUERYUPDATE_COMPLEX 2
|
||||
#define QUERYUPDATE_COMPLEX_WITH_BOOKMARKS 3
|
||||
#define QUERYUPDATE_HOST 4
|
||||
|
||||
// this is a work-around for a problem with the optimizer of sqlite
|
||||
// A sub-select on MAX(visit_date) is slower than this query with our indexes
|
||||
|
@ -110,6 +111,7 @@ class nsNavBookmarks;
|
|||
class QueryKeyValuePair;
|
||||
class nsIEffectiveTLDService;
|
||||
class nsIIDNService;
|
||||
class PlacesSQLQueryBuilder;
|
||||
|
||||
// nsNavHistory
|
||||
|
||||
|
@ -126,6 +128,8 @@ class nsNavHistory : public nsSupportsWeakReference,
|
|||
{
|
||||
friend class AutoCompleteIntermediateResultSet;
|
||||
friend class AutoCompleteResultComparator;
|
||||
friend class PlacesSQLQueryBuilder;
|
||||
|
||||
public:
|
||||
nsNavHistory();
|
||||
|
||||
|
@ -237,6 +241,7 @@ public:
|
|||
{ return mCollation; }
|
||||
nsIDateTimeFormat* GetDateFormatter()
|
||||
{ return mDateFormatter; }
|
||||
void GetStringFromName(const PRUnichar* aName, nsACString& aResult);
|
||||
|
||||
// returns true if history has been disabled
|
||||
PRBool IsHistoryDisabled() { return mExpireDaysMax == 0; }
|
||||
|
@ -319,10 +324,6 @@ public:
|
|||
void DomainNameFromURI(nsIURI* aURI,
|
||||
nsACString& aDomainName);
|
||||
static PRTime NormalizeTime(PRUint32 aRelative, PRTime aOffset);
|
||||
nsresult RecursiveGroup(nsNavHistoryQueryResultNode *aResultNode,
|
||||
const nsCOMArray<nsNavHistoryResultNode>& aSource,
|
||||
const PRUint16* aGroupingMode, PRUint32 aGroupCount,
|
||||
nsCOMArray<nsNavHistoryResultNode>* aDest);
|
||||
|
||||
// Don't use these directly, inside nsNavHistory use UpdateBatchScoper,
|
||||
// else use nsINavHistoryService::RunInBatchMode
|
||||
|
@ -455,6 +456,7 @@ protected:
|
|||
* The database was migrated to a new version.
|
||||
*/
|
||||
nsresult InitDB(PRInt16 *aMadeChanges);
|
||||
nsresult InitFunctions();
|
||||
nsresult InitStatements();
|
||||
nsresult ForceMigrateBookmarksDB(mozIStorageConnection *aDBConn);
|
||||
nsresult MigrateV3Up(mozIStorageConnection *aDBConn);
|
||||
|
@ -564,14 +566,14 @@ protected:
|
|||
|
||||
nsresult ConstructQueryString(const nsCOMArray<nsNavHistoryQuery>& aQueries,
|
||||
nsNavHistoryQueryOptions *aOptions,
|
||||
nsCString &queryString);
|
||||
nsCString& queryString,
|
||||
PRBool& aParamsPresent);
|
||||
|
||||
nsresult QueryToSelectClause(nsNavHistoryQuery* aQuery,
|
||||
nsNavHistoryQueryOptions* aOptions,
|
||||
PRInt32 aStartParameter,
|
||||
nsCString* aClause,
|
||||
PRInt32* aParamCount,
|
||||
const nsACString& aCommonConditions);
|
||||
PRInt32* aParamCount);
|
||||
nsresult BindQueryClauseParameters(mozIStorageStatement* statement,
|
||||
PRInt32 aStartParameter,
|
||||
nsNavHistoryQuery* aQuery,
|
||||
|
@ -585,25 +587,10 @@ protected:
|
|||
void GetAgeInDaysString(PRInt32 aInt, const PRUnichar *aName,
|
||||
nsACString& aResult);
|
||||
|
||||
void GetStringFromName(const PRUnichar *aName, nsACString& aResult);
|
||||
|
||||
void TitleForDomain(const nsCString& domain, nsACString& aTitle);
|
||||
|
||||
nsresult SetPageTitleInternal(nsIURI* aURI, const nsAString& aTitle);
|
||||
|
||||
nsresult GroupByDay(nsNavHistoryQueryResultNode *aResultNode,
|
||||
const nsCOMArray<nsNavHistoryResultNode>& aSource,
|
||||
nsCOMArray<nsNavHistoryResultNode>* aDest);
|
||||
|
||||
nsresult GroupByHost(nsNavHistoryQueryResultNode *aResultNode,
|
||||
const nsCOMArray<nsNavHistoryResultNode>& aSource,
|
||||
nsCOMArray<nsNavHistoryResultNode>* aDest,
|
||||
PRBool aIsDomain);
|
||||
|
||||
nsresult GroupByFolder(nsNavHistoryQueryResultNode *aResultNode,
|
||||
const nsCOMArray<nsNavHistoryResultNode>& aSource,
|
||||
nsCOMArray<nsNavHistoryResultNode>* aDest);
|
||||
|
||||
PRBool URIHasTag(const nsACString& aURISpec, const nsAString& aTag);
|
||||
PRBool URIHasAnyTagFromTerms(const nsACString& aURISpec, const nsStringArray& aTerms);
|
||||
void CreateTermsFromTokens(const nsStringArray& aTagTokens, nsStringArray& aTerms);
|
||||
|
|
|
@ -167,7 +167,6 @@ static void SetOptionsKeyUint32(const nsCString& aValue,
|
|||
#define QUERYKEY_FORCE_ORIGINAL_TITLE "originalTitle"
|
||||
#define QUERYKEY_INCLUDE_HIDDEN "includeHidden"
|
||||
#define QUERYKEY_SHOW_SESSIONS "showSessions"
|
||||
#define QUERYKEY_APPLY_OPTIONS_TO_CONTAINERS "applyOptionsToContainers"
|
||||
#define QUERYKEY_MAX_RESULTS "maxResults"
|
||||
#define QUERYKEY_QUERY_TYPE "queryType"
|
||||
|
||||
|
@ -417,15 +416,6 @@ nsNavHistory::QueriesToQueryString(nsINavHistoryQuery **aQueries,
|
|||
nsMemory::Free(folders);
|
||||
}
|
||||
|
||||
// grouping
|
||||
PRUint32 groupCount;
|
||||
const PRUint16* groups = options->GroupingMode(&groupCount);
|
||||
for (PRUint32 i = 0; i < groupCount; i ++) {
|
||||
AppendAmpersandIfNonempty(queryString);
|
||||
queryString += NS_LITERAL_CSTRING(QUERYKEY_GROUP "=");
|
||||
AppendInt16(queryString, groups[i]);
|
||||
}
|
||||
|
||||
// sorting
|
||||
if (options->SortingMode() != nsINavHistoryQueryOptions::SORT_BY_NONE) {
|
||||
AppendAmpersandIfNonempty(queryString);
|
||||
|
@ -501,12 +491,6 @@ nsNavHistory::QueriesToQueryString(nsINavHistoryQuery **aQueries,
|
|||
queryString += NS_LITERAL_CSTRING(QUERYKEY_SHOW_SESSIONS "=1");
|
||||
}
|
||||
|
||||
// apply options to containers
|
||||
if (options->ApplyOptionsToContainers()) {
|
||||
AppendAmpersandIfNonempty(queryString);
|
||||
queryString += NS_LITERAL_CSTRING(QUERYKEY_APPLY_OPTIONS_TO_CONTAINERS "=1");
|
||||
}
|
||||
|
||||
// max results
|
||||
if (options->MaxResults()) {
|
||||
AppendAmpersandIfNonempty(queryString);
|
||||
|
@ -577,7 +561,6 @@ nsNavHistory::TokensToQueries(const nsTArray<QueryKeyValuePair>& aTokens,
|
|||
if (aTokens.Length() == 0)
|
||||
return NS_OK; // nothing to do
|
||||
|
||||
nsTArray<PRUint16> groups;
|
||||
nsTArray<PRInt64> folders;
|
||||
|
||||
nsCOMPtr<nsNavHistoryQuery> query(new nsNavHistoryQuery());
|
||||
|
@ -695,15 +678,6 @@ nsNavHistory::TokensToQueries(const nsTArray<QueryKeyValuePair>& aTokens,
|
|||
if (! aQueries->AppendObject(query))
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
// grouping
|
||||
} else if (kvp.key.EqualsLiteral(QUERYKEY_GROUP)) {
|
||||
PRUint32 grouping = kvp.value.ToInteger((PRInt32*)&rv);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
groups.AppendElement(grouping);
|
||||
} else {
|
||||
NS_WARNING("Bad number for grouping in query");
|
||||
}
|
||||
|
||||
// sorting mode
|
||||
} else if (kvp.key.EqualsLiteral(QUERYKEY_SORT)) {
|
||||
SetOptionsKeyUint16(kvp.value, aOptions,
|
||||
|
@ -754,10 +728,6 @@ nsNavHistory::TokensToQueries(const nsTArray<QueryKeyValuePair>& aTokens,
|
|||
} else if (kvp.key.EqualsLiteral(QUERYKEY_SHOW_SESSIONS)) {
|
||||
SetOptionsKeyBool(kvp.value, aOptions,
|
||||
&nsINavHistoryQueryOptions::SetShowSessions);
|
||||
// apply options to containers
|
||||
} else if (kvp.key.EqualsLiteral(QUERYKEY_APPLY_OPTIONS_TO_CONTAINERS)) {
|
||||
SetOptionsKeyBool(kvp.value, aOptions,
|
||||
&nsINavHistoryQueryOptions::SetApplyOptionsToContainers);
|
||||
// max results
|
||||
} else if (kvp.key.EqualsLiteral(QUERYKEY_MAX_RESULTS)) {
|
||||
SetOptionsKeyUint32(kvp.value, aOptions,
|
||||
|
@ -775,7 +745,6 @@ nsNavHistory::TokensToQueries(const nsTArray<QueryKeyValuePair>& aTokens,
|
|||
|
||||
if (folders.Length() != 0)
|
||||
query->SetFolders(folders.Elements(), folders.Length());
|
||||
aOptions->SetGroupingMode(groups.Elements(), groups.Length());
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1097,54 +1066,6 @@ NS_IMETHODIMP nsNavHistoryQuery::Clone(nsINavHistoryQuery** _retval)
|
|||
// nsNavHistoryQueryOptions
|
||||
NS_IMPL_ISUPPORTS2(nsNavHistoryQueryOptions, nsNavHistoryQueryOptions, nsINavHistoryQueryOptions)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNavHistoryQueryOptions::GetGroupingMode(PRUint32 *aGroupCount,
|
||||
PRUint16** aGroupingMode)
|
||||
{
|
||||
if (mGroupCount == 0) {
|
||||
*aGroupCount = 0;
|
||||
*aGroupingMode = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
*aGroupingMode = static_cast<PRUint16*>
|
||||
(nsMemory::Alloc(sizeof(PRUint16) * mGroupCount));
|
||||
if (! *aGroupingMode)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
for(PRUint32 i = 0; i < mGroupCount; i ++)
|
||||
(*aGroupingMode)[i] = mGroupings[i];
|
||||
*aGroupCount = mGroupCount;
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHODIMP
|
||||
nsNavHistoryQueryOptions::SetGroupingMode(const PRUint16 *aGroupingMode,
|
||||
PRUint32 aGroupCount)
|
||||
{
|
||||
// check input
|
||||
PRUint32 i;
|
||||
for (i = 0; i < aGroupCount; i ++) {
|
||||
if (aGroupingMode[i] > GROUP_BY_FOLDER)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (mGroupings) {
|
||||
delete[] mGroupings;
|
||||
mGroupings = nsnull;
|
||||
mGroupCount = 0;
|
||||
}
|
||||
if (! aGroupCount)
|
||||
return NS_OK;
|
||||
|
||||
mGroupings = new PRUint16[aGroupCount];
|
||||
NS_ENSURE_TRUE(mGroupings, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
for (i = 0; i < aGroupCount; ++i) {
|
||||
mGroupings[i] = aGroupingMode[i];
|
||||
}
|
||||
|
||||
mGroupCount = aGroupCount;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// sortingMode
|
||||
NS_IMETHODIMP
|
||||
nsNavHistoryQueryOptions::GetSortingMode(PRUint16* aMode)
|
||||
|
@ -1184,7 +1105,7 @@ nsNavHistoryQueryOptions::GetResultType(PRUint16* aType)
|
|||
NS_IMETHODIMP
|
||||
nsNavHistoryQueryOptions::SetResultType(PRUint16 aType)
|
||||
{
|
||||
if (aType > RESULTS_AS_FULL_VISIT)
|
||||
if (aType > RESULTS_AS_TAG_QUERY)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
mResultType = aType;
|
||||
return NS_OK;
|
||||
|
@ -1287,20 +1208,6 @@ nsNavHistoryQueryOptions::SetShowSessions(PRBool aShowSessions)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// applyOptionsToContainers
|
||||
NS_IMETHODIMP
|
||||
nsNavHistoryQueryOptions::GetApplyOptionsToContainers(PRBool* aApplyOptionsToContainers)
|
||||
{
|
||||
*aApplyOptionsToContainers = mApplyOptionsToContainers;
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHODIMP
|
||||
nsNavHistoryQueryOptions::SetApplyOptionsToContainers(PRBool aApplyOptionsToContainers)
|
||||
{
|
||||
mApplyOptionsToContainers = aApplyOptionsToContainers;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// maxResults
|
||||
NS_IMETHODIMP
|
||||
nsNavHistoryQueryOptions::GetMaxResults(PRUint32* aMaxResults)
|
||||
|
@ -1349,21 +1256,9 @@ nsNavHistoryQueryOptions::Clone(nsNavHistoryQueryOptions **aResult)
|
|||
nsRefPtr<nsNavHistoryQueryOptions> resultHolder(result);
|
||||
result->mSort = mSort;
|
||||
result->mResultType = mResultType;
|
||||
result->mGroupCount = mGroupCount;
|
||||
if (mGroupCount) {
|
||||
result->mGroupings = new PRUint16[mGroupCount];
|
||||
if (! result->mGroupings) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
for (PRUint32 i = 0; i < mGroupCount; i ++)
|
||||
result->mGroupings[i] = mGroupings[i];
|
||||
} else {
|
||||
result->mGroupCount = nsnull;
|
||||
}
|
||||
result->mExcludeItems = mExcludeItems;
|
||||
result->mExcludeQueries = mExcludeQueries;
|
||||
result->mShowSessions = mShowSessions;
|
||||
result->mApplyOptionsToContainers = mApplyOptionsToContainers;
|
||||
result->mExpandQueries = mExpandQueries;
|
||||
result->mMaxResults = mMaxResults;
|
||||
result->mQueryType = mQueryType;
|
||||
|
|
|
@ -118,14 +118,12 @@ class nsNavHistoryQueryOptions : public nsINavHistoryQueryOptions
|
|||
{
|
||||
public:
|
||||
nsNavHistoryQueryOptions() : mSort(0), mResultType(0),
|
||||
mGroupCount(0), mGroupings(nsnull),
|
||||
mExcludeItems(PR_FALSE),
|
||||
mExcludeQueries(PR_FALSE),
|
||||
mExcludeReadOnlyFolders(PR_FALSE),
|
||||
mExpandQueries(PR_TRUE),
|
||||
mIncludeHidden(PR_FALSE),
|
||||
mShowSessions(PR_FALSE),
|
||||
mApplyOptionsToContainers(PR_FALSE),
|
||||
mMaxResults(0),
|
||||
mQueryType(nsINavHistoryQueryOptions::QUERY_TYPE_HISTORY)
|
||||
{ }
|
||||
|
@ -141,16 +139,12 @@ public:
|
|||
|
||||
PRUint16 SortingMode() const { return mSort; }
|
||||
PRUint16 ResultType() const { return mResultType; }
|
||||
const PRUint16* GroupingMode(PRUint32 *count) const {
|
||||
*count = mGroupCount; return mGroupings;
|
||||
}
|
||||
PRBool ExcludeItems() const { return mExcludeItems; }
|
||||
PRBool ExcludeQueries() const { return mExcludeQueries; }
|
||||
PRBool ExcludeReadOnlyFolders() const { return mExcludeReadOnlyFolders; }
|
||||
PRBool ExpandQueries() const { return mExpandQueries; }
|
||||
PRBool IncludeHidden() const { return mIncludeHidden; }
|
||||
PRBool ShowSessions() const { return mShowSessions; }
|
||||
PRBool ApplyOptionsToContainers() const { return mApplyOptionsToContainers; }
|
||||
PRUint32 MaxResults() const { return mMaxResults; }
|
||||
PRUint16 QueryType() const { return mQueryType; }
|
||||
|
||||
|
@ -159,8 +153,6 @@ public:
|
|||
private:
|
||||
nsNavHistoryQueryOptions(const nsNavHistoryQueryOptions& other) {} // no copy
|
||||
|
||||
~nsNavHistoryQueryOptions() { delete[] mGroupings; }
|
||||
|
||||
// IF YOU ADD MORE ITEMS:
|
||||
// * Add a new getter for C++ above if it makes sense
|
||||
// * Add to the serialization code (see nsNavHistory::QueriesToQueryString())
|
||||
|
@ -171,15 +163,12 @@ private:
|
|||
nsCString mSortingAnnotation;
|
||||
nsCString mParentAnnotationToExclude;
|
||||
PRUint16 mResultType;
|
||||
PRUint32 mGroupCount;
|
||||
PRUint16 *mGroupings;
|
||||
PRPackedBool mExcludeItems;
|
||||
PRPackedBool mExcludeQueries;
|
||||
PRPackedBool mExcludeReadOnlyFolders;
|
||||
PRPackedBool mExpandQueries;
|
||||
PRPackedBool mIncludeHidden;
|
||||
PRPackedBool mShowSessions;
|
||||
PRPackedBool mApplyOptionsToContainers;
|
||||
PRUint32 mMaxResults;
|
||||
PRUint16 mQueryType;
|
||||
};
|
||||
|
|
|
@ -373,6 +373,21 @@ nsNavHistoryContainerResultNode::nsNavHistoryContainerResultNode(
|
|||
{
|
||||
}
|
||||
|
||||
nsNavHistoryContainerResultNode::nsNavHistoryContainerResultNode(
|
||||
const nsACString& aURI, const nsACString& aTitle,
|
||||
PRTime aTime,
|
||||
const nsACString& aIconURI, PRUint32 aContainerType, PRBool aReadOnly,
|
||||
const nsACString& aDynamicContainerType,
|
||||
nsNavHistoryQueryOptions* aOptions) :
|
||||
nsNavHistoryResultNode(aURI, aTitle, 0, aTime, aIconURI),
|
||||
mResult(nsnull),
|
||||
mContainerType(aContainerType),
|
||||
mExpanded(PR_FALSE),
|
||||
mChildrenReadOnly(aReadOnly),
|
||||
mDynamicContainerType(aDynamicContainerType),
|
||||
mOptions(aOptions)
|
||||
{
|
||||
}
|
||||
|
||||
// nsNavHistoryContainerResultNode::OnRemoving
|
||||
//
|
||||
|
@ -526,8 +541,9 @@ nsNavHistoryContainerResultNode::CloseContainer(PRBool aUpdateView)
|
|||
void
|
||||
nsNavHistoryContainerResultNode::FillStats()
|
||||
{
|
||||
mAccessCount = 0;
|
||||
mTime = 0;
|
||||
PRUint32 accessCount = 0;
|
||||
PRTime newTime = 0;
|
||||
|
||||
for (PRInt32 i = 0; i < mChildren.Count(); i ++) {
|
||||
nsNavHistoryResultNode* node = mChildren[i];
|
||||
node->mParent = this;
|
||||
|
@ -537,12 +553,17 @@ nsNavHistoryContainerResultNode::FillStats()
|
|||
container->mResult = mResult;
|
||||
container->FillStats();
|
||||
}
|
||||
mAccessCount += node->mAccessCount;
|
||||
accessCount += node->mAccessCount;
|
||||
// this is how container nodes get sorted by date
|
||||
// (of type nsINavHistoryResultNode::RESULT_TYPE_DAY, for example)
|
||||
// The container gets the most recent time of the child nodes.
|
||||
if (node->mTime > mTime)
|
||||
mTime = node->mTime;
|
||||
if (node->mTime > newTime)
|
||||
newTime = node->mTime;
|
||||
}
|
||||
|
||||
if (mExpanded) {
|
||||
mAccessCount = accessCount;
|
||||
if (!IsQuery() || newTime > mTime)
|
||||
mTime = newTime;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -676,10 +697,6 @@ nsNavHistoryContainerResultNode::GetSortingComparator(PRUint16 aSortType)
|
|||
return &SortComparison_LastModifiedLess;
|
||||
case nsINavHistoryQueryOptions::SORT_BY_LASTMODIFIED_DESCENDING:
|
||||
return &SortComparison_LastModifiedGreater;
|
||||
case nsINavHistoryQueryOptions::SORT_BY_COUNT_ASCENDING:
|
||||
return &SortComparison_CountLess;
|
||||
case nsINavHistoryQueryOptions::SORT_BY_COUNT_DESCENDING:
|
||||
return &SortComparison_CountGreater;
|
||||
case nsINavHistoryQueryOptions::SORT_BY_TAGS_ASCENDING:
|
||||
return &SortComparison_TagsLess;
|
||||
case nsINavHistoryQueryOptions::SORT_BY_TAGS_DESCENDING:
|
||||
|
@ -721,8 +738,11 @@ nsNavHistoryContainerResultNode::RecursiveSort(
|
|||
PRUint32
|
||||
nsNavHistoryContainerResultNode::FindInsertionPoint(
|
||||
nsNavHistoryResultNode* aNode, SortComparator aComparator,
|
||||
const char* aData)
|
||||
const char* aData, PRBool* aItemExists)
|
||||
{
|
||||
if (aItemExists)
|
||||
(*aItemExists) = PR_FALSE;
|
||||
|
||||
if (mChildren.Count() == 0)
|
||||
return 0;
|
||||
|
||||
|
@ -730,10 +750,19 @@ nsNavHistoryContainerResultNode::FindInsertionPoint(
|
|||
|
||||
// The common case is the beginning or the end because this is used to insert
|
||||
// new items that are added to history, which is usually sorted by date.
|
||||
if (aComparator(aNode, mChildren[0], data) <= 0)
|
||||
PRInt32 res;
|
||||
res = aComparator(aNode, mChildren[0], data);
|
||||
if (res <= 0) {
|
||||
if (aItemExists && res == 0)
|
||||
(*aItemExists) = PR_TRUE;
|
||||
return 0;
|
||||
if (aComparator(aNode, mChildren[mChildren.Count() - 1], data) >= 0)
|
||||
}
|
||||
res = aComparator(aNode, mChildren[mChildren.Count() - 1], data);
|
||||
if (res >= 0) {
|
||||
if (aItemExists && res == 0)
|
||||
(*aItemExists) = PR_TRUE;
|
||||
return mChildren.Count();
|
||||
}
|
||||
|
||||
PRUint32 beginRange = 0; // inclusive
|
||||
PRUint32 endRange = mChildren.Count(); // exclusive
|
||||
|
@ -741,10 +770,15 @@ nsNavHistoryContainerResultNode::FindInsertionPoint(
|
|||
if (beginRange == endRange)
|
||||
return endRange;
|
||||
PRUint32 center = beginRange + (endRange - beginRange) / 2;
|
||||
if (aComparator(aNode, mChildren[center], data) <= 0)
|
||||
PRInt32 res = aComparator(aNode, mChildren[center], data);
|
||||
if (res <= 0) {
|
||||
endRange = center; // left side
|
||||
else
|
||||
if (aItemExists && res == 0)
|
||||
(*aItemExists) = PR_TRUE;
|
||||
}
|
||||
else {
|
||||
beginRange = center + 1; // right site
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -787,7 +821,7 @@ PRInt32 nsNavHistoryContainerResultNode::SortComparison_StringLess(
|
|||
nsNavHistory* history = nsNavHistory::GetHistoryService();
|
||||
NS_ENSURE_TRUE(history, 0);
|
||||
nsICollation* collation = history->GetCollation();
|
||||
NS_ENSURE_TRUE(history, 0);
|
||||
NS_ENSURE_TRUE(collation, 0);
|
||||
|
||||
PRInt32 res = 0;
|
||||
collation->CompareString(nsICollation::kCollationCaseInSensitive, a, b, &res);
|
||||
|
@ -821,18 +855,6 @@ PRInt32 PR_CALLBACK nsNavHistoryContainerResultNode::SortComparison_TitleLess(
|
|||
PRUint32 aType;
|
||||
a->GetType(&aType);
|
||||
|
||||
if (aType == nsINavHistoryResultNode::RESULT_TYPE_DAY) {
|
||||
// for the history sidebar, when we do "View | By Date" or
|
||||
// "View | By Date and Site" we sort by SORT_BY_TITLE_ASCENDING.
|
||||
//
|
||||
// so to make the day container show up in the desired order
|
||||
// we need to compare by time, instead of by title.
|
||||
//
|
||||
// hard coding this isn't ideal, but we can't currently have
|
||||
// one sort per grouping. see bug #359332 on that issue.
|
||||
return -ComparePRTime(a->mTime, b->mTime);
|
||||
}
|
||||
|
||||
PRInt32 value = SortComparison_StringLess(NS_ConvertUTF8toUTF16(a->mTitle),
|
||||
NS_ConvertUTF8toUTF16(b->mTitle));
|
||||
if (value == 0) {
|
||||
|
@ -921,70 +943,6 @@ PRInt32 PR_CALLBACK nsNavHistoryContainerResultNode::SortComparison_LastModified
|
|||
return -nsNavHistoryContainerResultNode::SortComparison_LastModifiedLess(a, b, closure);
|
||||
}
|
||||
|
||||
// nsNavHistoryContainerResultNode::SortComparison_Count*
|
||||
//
|
||||
|
||||
PRInt32 PR_CALLBACK nsNavHistoryContainerResultNode::SortComparison_CountLess(
|
||||
nsNavHistoryResultNode* a, nsNavHistoryResultNode* b, void* closure)
|
||||
{
|
||||
PRUint32 count1 = 0;
|
||||
PRUint32 count2 = 0;
|
||||
|
||||
nsresult rv;
|
||||
|
||||
if (a->IsContainer()) {
|
||||
nsNavHistoryResult* result = a->GetResult();
|
||||
nsCOMPtr<nsINavHistoryResultViewer> viewer;
|
||||
if (result) {
|
||||
rv = result->GetViewer(getter_AddRefs(viewer));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
result->SetViewer(nsnull);
|
||||
}
|
||||
|
||||
rv = a->GetAsContainer()->SetContainerOpen(PR_TRUE);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = a->GetAsContainer()->GetChildCount(&count1);
|
||||
if (NS_FAILED(rv))
|
||||
count1 = 0;
|
||||
(void)a->GetAsContainer()->SetContainerOpen(PR_FALSE);
|
||||
if (result && viewer)
|
||||
result->SetViewer(viewer);
|
||||
}
|
||||
|
||||
if (b->IsContainer()) {
|
||||
nsNavHistoryResult* result = a->GetResult();
|
||||
nsCOMPtr<nsINavHistoryResultViewer> viewer;
|
||||
if (result) {
|
||||
rv = result->GetViewer(getter_AddRefs(viewer));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
result->SetViewer(nsnull);
|
||||
}
|
||||
|
||||
rv = b->GetAsContainer()->SetContainerOpen(PR_TRUE);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = b->GetAsContainer()->GetChildCount(&count2);
|
||||
if (NS_FAILED(rv))
|
||||
count2 = 0;
|
||||
(void)b->GetAsContainer()->SetContainerOpen(PR_FALSE);
|
||||
if (result && viewer)
|
||||
result->SetViewer(viewer);
|
||||
}
|
||||
|
||||
PRInt32 value = CompareIntegers(count1, count2);
|
||||
if (value == 0) {
|
||||
value = SortComparison_StringLess(NS_ConvertUTF8toUTF16(a->mTitle),
|
||||
NS_ConvertUTF8toUTF16(b->mTitle));
|
||||
if (value == 0)
|
||||
value = nsNavHistoryContainerResultNode::SortComparison_Bookmark(a, b, closure);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
PRInt32 PR_CALLBACK nsNavHistoryContainerResultNode::SortComparison_CountGreater(
|
||||
nsNavHistoryResultNode* a, nsNavHistoryResultNode* b, void* closure)
|
||||
{
|
||||
return -nsNavHistoryContainerResultNode::SortComparison_CountLess(a, b, closure);
|
||||
}
|
||||
|
||||
// nsNavHistoryContainerResultNode::SortComparison_URI*
|
||||
//
|
||||
// Certain types of parent nodes are treated specially because URIs are not
|
||||
|
@ -1372,7 +1330,8 @@ nsNavHistoryContainerResultNode::InsertChildAt(nsNavHistoryResultNode* aNode,
|
|||
|
||||
nsresult
|
||||
nsNavHistoryContainerResultNode::InsertSortedChild(
|
||||
nsNavHistoryResultNode* aNode, PRBool aIsTemporary)
|
||||
nsNavHistoryResultNode* aNode,
|
||||
PRBool aIsTemporary, PRBool aIgnoreDuplicates)
|
||||
{
|
||||
|
||||
if (mChildren.Count() == 0)
|
||||
|
@ -1395,8 +1354,14 @@ nsNavHistoryContainerResultNode::InsertSortedChild(
|
|||
|
||||
nsCAutoString sortingAnnotation;
|
||||
GetSortingAnnotation(sortingAnnotation);
|
||||
return InsertChildAt(aNode, FindInsertionPoint(aNode, comparator, sortingAnnotation.get()),
|
||||
aIsTemporary);
|
||||
PRBool itemExists;
|
||||
PRUint32 position = FindInsertionPoint(aNode, comparator,
|
||||
sortingAnnotation.get(),
|
||||
&itemExists);
|
||||
if (aIgnoreDuplicates && itemExists)
|
||||
return NS_OK;
|
||||
|
||||
return InsertChildAt(aNode, position, aIsTemporary);
|
||||
}
|
||||
return InsertChildAt(aNode, mChildren.Count(), aIsTemporary);
|
||||
}
|
||||
|
@ -1426,7 +1391,8 @@ nsNavHistoryContainerResultNode::EnsureItemPosition(PRUint32 aIndex) {
|
|||
nsRefPtr<nsNavHistoryResultNode> node(mChildren[aIndex]);
|
||||
mChildren.RemoveObjectAt(aIndex);
|
||||
|
||||
PRUint32 newIndex = FindInsertionPoint(node, comparator,sortAnno.get());
|
||||
PRUint32 newIndex = FindInsertionPoint(
|
||||
node, comparator,sortAnno.get(), nsnull);
|
||||
mChildren.InsertObjectAt(node.get(), newIndex);
|
||||
|
||||
nsNavHistoryResult* result = GetResult();
|
||||
|
@ -1440,9 +1406,8 @@ nsNavHistoryContainerResultNode::EnsureItemPosition(PRUint32 aIndex) {
|
|||
|
||||
// nsNavHistoryContainerResultNode::MergeResults
|
||||
//
|
||||
// This takes a fully grouped list of nodes and merges them into the
|
||||
// current result set. Any containers that are added must already be
|
||||
// sorted.
|
||||
// This takes a list of nodes and merges them into the current result set.
|
||||
// Any containers that are added must already be sorted.
|
||||
//
|
||||
// This assumes that the items in 'aAddition' are new visits or
|
||||
// replacement URIs. We do not update visits.
|
||||
|
@ -1628,12 +1593,6 @@ nsNavHistoryContainerResultNode::RecursiveFindURIs(PRBool aOnlyOne,
|
|||
if (aOnlyOne)
|
||||
return;
|
||||
}
|
||||
} else if (nsNavHistoryResultNode::IsTypeQuerySubcontainer(type)) {
|
||||
// search into sub-containers
|
||||
RecursiveFindURIs(aOnlyOne, aContainer->mChildren[child]->GetAsContainer(),
|
||||
aSpec, aMatches);
|
||||
if (aOnlyOne && aMatches->Count() > 0)
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2078,6 +2037,26 @@ nsNavHistoryQueryResultNode::nsNavHistoryQueryResultNode(
|
|||
&mHasSearchTerms);
|
||||
}
|
||||
|
||||
nsNavHistoryQueryResultNode::nsNavHistoryQueryResultNode(
|
||||
const nsACString& aTitle, const nsACString& aIconURI,
|
||||
PRTime aTime,
|
||||
const nsCOMArray<nsNavHistoryQuery>& aQueries,
|
||||
nsNavHistoryQueryOptions* aOptions) :
|
||||
nsNavHistoryContainerResultNode(EmptyCString(), aTitle, aTime, aIconURI,
|
||||
nsNavHistoryResultNode::RESULT_TYPE_QUERY,
|
||||
PR_TRUE, EmptyCString(), aOptions),
|
||||
mQueries(aQueries),
|
||||
mContentsValid(PR_FALSE),
|
||||
mBatchInProgress(PR_FALSE)
|
||||
{
|
||||
NS_ASSERTION(aQueries.Count() > 0, "Must have at least one query");
|
||||
|
||||
nsNavHistory* history = nsNavHistory::GetHistoryService();
|
||||
NS_ASSERTION(history, "History service missing");
|
||||
mLiveUpdate = history->GetUpdateRequirements(mQueries, mOptions,
|
||||
&mHasSearchTerms);
|
||||
}
|
||||
|
||||
|
||||
// nsNavHistoryQueryResultNode::CanExpand
|
||||
//
|
||||
|
@ -2311,19 +2290,26 @@ nsNavHistoryQueryResultNode::FillChildren()
|
|||
// nodes and the result node pointers on the containers
|
||||
FillStats();
|
||||
|
||||
// once we've computed all tree stats, we can sort, because containers will
|
||||
// then have proper visit counts and dates
|
||||
SortComparator comparator = GetSortingComparator(GetSortType());
|
||||
if (comparator) {
|
||||
nsCAutoString sortingAnnotation;
|
||||
GetSortingAnnotation(sortingAnnotation);
|
||||
RecursiveSort(sortingAnnotation.get(), comparator);
|
||||
PRUint16 sortType = GetSortType();
|
||||
|
||||
// The default SORT_BY_NONE sorts by the bookmark index (position),
|
||||
// which we do not have for history queries
|
||||
if (mOptions->QueryType() != nsINavHistoryQueryOptions::QUERY_TYPE_HISTORY ||
|
||||
sortType != nsINavHistoryQueryOptions::SORT_BY_NONE) {
|
||||
// once we've computed all tree stats, we can sort, because containers will
|
||||
// then have proper visit counts and dates
|
||||
SortComparator comparator = GetSortingComparator(GetSortType());
|
||||
if (comparator) {
|
||||
nsCAutoString sortingAnnotation;
|
||||
GetSortingAnnotation(sortingAnnotation);
|
||||
RecursiveSort(sortingAnnotation.get(), comparator);
|
||||
}
|
||||
}
|
||||
|
||||
// if our options apply to containers and we are limiting our results
|
||||
// remove items from the end of the mChildren array after sorting.
|
||||
// if we are limiting our results remove items from the end of the
|
||||
// mChildren array after sorting. This is done for root node only.
|
||||
// note, if count < max results, we won't do anything.
|
||||
if (mOptions->ApplyOptionsToContainers() && mOptions->MaxResults()) {
|
||||
if (!mParent && mOptions->MaxResults()) {
|
||||
while (mChildren.Count() > mOptions->MaxResults())
|
||||
mChildren.RemoveObjectAt(mChildren.Count() - 1);
|
||||
}
|
||||
|
@ -2517,7 +2503,8 @@ NS_IMETHODIMP
|
|||
nsNavHistoryQueryResultNode::OnVisit(nsIURI* aURI, PRInt64 aVisitId,
|
||||
PRTime aTime, PRInt64 aSessionId,
|
||||
PRInt64 aReferringId,
|
||||
PRUint32 aTransitionType)
|
||||
PRUint32 aTransitionType,
|
||||
PRUint32* aAdded)
|
||||
{
|
||||
// ignore everything during batches
|
||||
if (mBatchInProgress)
|
||||
|
@ -2529,11 +2516,37 @@ nsNavHistoryQueryResultNode::OnVisit(nsIURI* aURI, PRInt64 aVisitId,
|
|||
nsresult rv;
|
||||
nsRefPtr<nsNavHistoryResultNode> addition;
|
||||
switch(mLiveUpdate) {
|
||||
|
||||
case QUERYUPDATE_HOST: {
|
||||
// For these simple yet common cases we can check the host ourselves
|
||||
// before doing the overhead of creating a new result node.
|
||||
NS_ASSERTION(mQueries.Count() == 1,
|
||||
"Host updated queries can have only one object");
|
||||
nsCOMPtr<nsNavHistoryQuery> queryHost =
|
||||
do_QueryInterface(mQueries[0], &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRBool hasDomain;
|
||||
queryHost->GetHasDomain(&hasDomain);
|
||||
if (!hasDomain || !queryHost->DomainIsHost())
|
||||
return NS_OK;
|
||||
|
||||
nsCAutoString host;
|
||||
if (NS_FAILED(aURI->GetAsciiHost(host)))
|
||||
return NS_OK;
|
||||
|
||||
if (!queryHost->Domain().Equals(host))
|
||||
return NS_OK;
|
||||
|
||||
} // Let it fall through - we want to check the time too,
|
||||
// if the time is not present it will match too.
|
||||
case QUERYUPDATE_TIME: {
|
||||
// For these simple yet common cases we can check the time ourselves
|
||||
// before doing the overhead of creating a new result node.
|
||||
NS_ASSERTION(mQueries.Count() == 1, "Time updated queries can have only one object");
|
||||
nsCOMPtr<nsNavHistoryQuery> query = do_QueryInterface(mQueries[0], &rv);
|
||||
NS_ASSERTION(mQueries.Count() == 1,
|
||||
"Time updated queries can have only one object");
|
||||
nsCOMPtr<nsNavHistoryQuery> query =
|
||||
do_QueryInterface(mQueries[0], &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRBool hasIt;
|
||||
|
@ -2555,6 +2568,11 @@ nsNavHistoryQueryResultNode::OnVisit(nsIURI* aURI, PRInt64 aVisitId,
|
|||
rv = history->VisitIdToResultNode(aVisitId, mOptions,
|
||||
getter_AddRefs(addition));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// We do not want to add this result to this node
|
||||
if (!addition)
|
||||
return NS_OK;
|
||||
|
||||
break;
|
||||
}
|
||||
case QUERYUPDATE_SIMPLE: {
|
||||
|
@ -2588,23 +2606,16 @@ nsNavHistoryQueryResultNode::OnVisit(nsIURI* aURI, PRInt64 aVisitId,
|
|||
// When more queries are possible (show pages I've visited less than 5 times)
|
||||
// this will be important to add.
|
||||
|
||||
PRUint32 groupCount;
|
||||
const PRUint16* groupings = mOptions->GroupingMode(&groupCount);
|
||||
nsCOMArray<nsNavHistoryResultNode> grouped;
|
||||
if (groupCount > 0) {
|
||||
// feed this one node into the results grouper for this query to see where
|
||||
// it should go in the results
|
||||
nsCOMArray<nsNavHistoryResultNode> itemSource;
|
||||
if (! itemSource.AppendObject(addition))
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
history->RecursiveGroup(this, itemSource, groupings, groupCount, &grouped);
|
||||
} else {
|
||||
// no grouping
|
||||
if (! grouped.AppendObject(addition))
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
nsCOMArray<nsNavHistoryResultNode> mergerNode;
|
||||
|
||||
if (!mergerNode.AppendObject(addition))
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
MergeResults(&mergerNode);
|
||||
|
||||
if (aAdded)
|
||||
(*aAdded)++;
|
||||
|
||||
MergeResults(&grouped);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -2680,7 +2691,7 @@ nsNavHistoryQueryResultNode::OnDeleteURI(nsIURI *aURI)
|
|||
NS_ASSERTION(childIndex >= 0, "Child not found in parent");
|
||||
parent->RemoveChildAt(childIndex);
|
||||
|
||||
if (parent->mChildren.Count() == 0 && parent->IsQuerySubcontainer()) {
|
||||
if (parent->mChildren.Count() == 0 && parent->IsQuery()) {
|
||||
// when query subcontainers (like hosts) get empty we should remove them
|
||||
// as well. Just append this to our list and it will get evaluated later
|
||||
// in the loop.
|
||||
|
@ -3088,6 +3099,14 @@ nsNavHistoryFolderResultNode::FillChildren()
|
|||
RecursiveSort(sortingAnnotation.get(), comparator);
|
||||
}
|
||||
|
||||
// if we are limiting our results remove items from the end of the
|
||||
// mChildren array after sorting. This is done for root node only.
|
||||
// note, if count < max results, we won't do anything.
|
||||
if (!mParent && mOptions->MaxResults()) {
|
||||
while (mChildren.Count() > mOptions->MaxResults())
|
||||
mChildren.RemoveObjectAt(mChildren.Count() - 1);
|
||||
}
|
||||
|
||||
// register with the result for updates
|
||||
nsNavHistoryResult* result = GetResult();
|
||||
NS_ENSURE_TRUE(result, NS_ERROR_FAILURE);
|
||||
|
@ -4107,10 +4126,117 @@ nsNavHistoryResult::OnItemMoved(PRInt64 aItemId,
|
|||
NS_IMETHODIMP
|
||||
nsNavHistoryResult::OnVisit(nsIURI* aURI, PRInt64 aVisitId, PRTime aTime,
|
||||
PRInt64 aSessionId, PRInt64 aReferringId,
|
||||
PRUint32 aTransitionType)
|
||||
PRUint32 aTransitionType, PRUint32* aAdded)
|
||||
{
|
||||
PRUint32 added = 0;
|
||||
|
||||
ENUMERATE_HISTORY_OBSERVERS(OnVisit(aURI, aVisitId, aTime, aSessionId,
|
||||
aReferringId, aTransitionType));
|
||||
aReferringId, aTransitionType, &added));
|
||||
|
||||
if (!added && mRootNode->mExpanded) {
|
||||
nsresult rv;
|
||||
|
||||
// None of registered query observers has accepted our URI, this means,
|
||||
// that a matching query either was not expanded or it does not exist.
|
||||
// If it just was not expanded, we can ignore it, but if it did not
|
||||
// exist, we have to add the query to the right place.
|
||||
PRUint32 resultType = mRootNode->mOptions->ResultType();
|
||||
nsNavHistoryResultNode * siteRoot = mRootNode;
|
||||
nsCAutoString dateRange;
|
||||
|
||||
// For day based queries we just check whether the first item is Today,
|
||||
if (resultType == nsINavHistoryQueryOptions::RESULTS_AS_DATE_QUERY ||
|
||||
resultType == nsINavHistoryQueryOptions::RESULTS_AS_DATE_SITE_QUERY) {
|
||||
nsNavHistory* history = nsNavHistory::GetHistoryService();
|
||||
NS_ENSURE_TRUE(history, 0);
|
||||
|
||||
// code borrowed from xpfe/components/history/src/nsGlobalHistory.cpp
|
||||
// pass in a pre-normalized now and a date, and we'll find
|
||||
// the difference since midnight on each of the days.
|
||||
//
|
||||
// USECS_PER_DAY == PR_USEC_PER_SEC * 60 * 60 * 24;
|
||||
static const PRInt64 USECS_PER_DAY = LL_INIT(20, 500654080);
|
||||
|
||||
dateRange = nsPrintfCString(255,
|
||||
"&beginTime=%lld&endTime=%lld",
|
||||
history->NormalizeTime(
|
||||
nsINavHistoryQuery::TIME_RELATIVE_TODAY, 0),
|
||||
history->NormalizeTime(
|
||||
nsINavHistoryQuery::TIME_RELATIVE_TODAY, USECS_PER_DAY));
|
||||
|
||||
PRBool todayIsMissing = PR_FALSE;
|
||||
PRUint32 childCount;
|
||||
rv = mRootNode->GetChildCount(&childCount);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCAutoString todayLabel;
|
||||
history->GetStringFromName(
|
||||
NS_LITERAL_STRING("finduri-AgeInDays-is-0").get(), todayLabel);
|
||||
|
||||
if (!childCount) {
|
||||
todayIsMissing = PR_TRUE;
|
||||
} else {
|
||||
nsCOMPtr<nsINavHistoryResultNode> firstChild;
|
||||
rv = mRootNode->GetChild(0, getter_AddRefs(firstChild));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCAutoString title;
|
||||
rv = firstChild->GetTitle( title);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (todayLabel.Equals(title)) {
|
||||
siteRoot = static_cast<nsNavHistoryResultNode *>(firstChild.get());
|
||||
} else {
|
||||
todayIsMissing = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (todayIsMissing) { // Add "Today"
|
||||
nsCAutoString queryUri;
|
||||
queryUri = nsPrintfCString(255,
|
||||
"place:type=%ld&sort=%ld%s",
|
||||
resultType == nsINavHistoryQueryOptions::RESULTS_AS_DATE_QUERY
|
||||
?nsINavHistoryQueryOptions::RESULTS_AS_URI
|
||||
:nsINavHistoryQueryOptions::RESULTS_AS_SITE_QUERY,
|
||||
nsINavHistoryQueryOptions::SORT_BY_TITLE_ASCENDING,
|
||||
dateRange.get());
|
||||
|
||||
nsRefPtr<nsNavHistoryQueryResultNode> todayNode;
|
||||
todayNode = new nsNavHistoryQueryResultNode(todayLabel,
|
||||
EmptyCString(), queryUri);
|
||||
rv = mRootNode->InsertChildAt( todayNode, 0);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
// "Today" was missing or we had day query
|
||||
if (resultType == nsINavHistoryQueryOptions::RESULTS_AS_DATE_QUERY ||
|
||||
todayIsMissing)
|
||||
return NS_OK; // No more processing necessary
|
||||
}
|
||||
|
||||
if (siteRoot->IsQuery() && siteRoot->GetAsQuery()->mContentsValid &&
|
||||
(resultType == nsINavHistoryQueryOptions::RESULTS_AS_DATE_SITE_QUERY ||
|
||||
resultType == nsINavHistoryQueryOptions::RESULTS_AS_SITE_QUERY)) {
|
||||
nsCAutoString host;
|
||||
rv = aURI->GetAsciiHost(host);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCAutoString queryUri;
|
||||
queryUri = nsPrintfCString(255,
|
||||
"place:type=%ld&sort=%ld&domain=%s&domainIsHost=true%s",
|
||||
nsINavHistoryQueryOptions::RESULTS_AS_URI,
|
||||
nsINavHistoryQueryOptions::SORT_BY_TITLE_ASCENDING,
|
||||
host.get(),
|
||||
dateRange.get());
|
||||
|
||||
nsRefPtr<nsNavHistoryQueryResultNode> siteNode;
|
||||
siteNode = new nsNavHistoryQueryResultNode(host, EmptyCString(), queryUri);
|
||||
rv = siteRoot->GetAsContainer()->InsertSortedChild(
|
||||
siteNode, PR_FALSE, PR_TRUE/*Ignore duplicates*/);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -98,7 +98,7 @@ private:
|
|||
NS_DECL_NSINAVBOOKMARKOBSERVER \
|
||||
NS_IMETHOD OnVisit(nsIURI* aURI, PRInt64 aVisitId, PRTime aTime, \
|
||||
PRInt64 aSessionId, PRInt64 aReferringId, \
|
||||
PRUint32 aTransitionType); \
|
||||
PRUint32 aTransitionType, PRUint32* aAdded); \
|
||||
NS_IMETHOD OnTitleChanged(nsIURI* aURI, const nsAString& aPageTitle); \
|
||||
NS_IMETHOD OnDeleteURI(nsIURI *aURI); \
|
||||
NS_IMETHOD OnClearHistory(); \
|
||||
|
@ -310,12 +310,10 @@ public:
|
|||
// 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_DYNAMIC_CONTAINER ||
|
||||
return (type == nsINavHistoryResultNode::RESULT_TYPE_DYNAMIC_CONTAINER ||
|
||||
type == nsINavHistoryResultNode::RESULT_TYPE_QUERY ||
|
||||
type == nsINavHistoryResultNode::RESULT_TYPE_FOLDER ||
|
||||
type == nsINavHistoryResultNode::RESULT_TYPE_FOLDER_SHORTCUT ||
|
||||
type == nsINavHistoryResultNode::RESULT_TYPE_DAY);
|
||||
type == nsINavHistoryResultNode::RESULT_TYPE_FOLDER_SHORTCUT);
|
||||
}
|
||||
PRBool IsContainer() {
|
||||
PRUint32 type;
|
||||
|
@ -327,19 +325,6 @@ public:
|
|||
GetType(&type);
|
||||
return (type == nsINavHistoryResultNode::RESULT_TYPE_DYNAMIC_CONTAINER);
|
||||
}
|
||||
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 currently
|
||||
// includes only host containers, but may be extended to support things
|
||||
// like days or other criteria. It 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 ||
|
||||
|
@ -534,6 +519,12 @@ public:
|
|||
const nsACString& aIconURI, PRUint32 aContainerType,
|
||||
PRBool aReadOnly, const nsACString& aDynamicContainerType,
|
||||
nsNavHistoryQueryOptions* aOptions);
|
||||
nsNavHistoryContainerResultNode(
|
||||
const nsACString& aURI, const nsACString& aTitle,
|
||||
PRTime aTime,
|
||||
const nsACString& aIconURI, PRUint32 aContainerType,
|
||||
PRBool aReadOnly, const nsACString& aDynamicContainerType,
|
||||
nsNavHistoryQueryOptions* aOptions);
|
||||
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_NAVHISTORYCONTAINERRESULTNODE_IID)
|
||||
|
||||
|
@ -562,7 +553,7 @@ public:
|
|||
// for every leaf node to the result.
|
||||
nsRefPtr<nsNavHistoryResult> mResult;
|
||||
|
||||
// for example, RESULT_TYPE_HOST. Query and Folder results override GetType
|
||||
// for example, RESULT_TYPE_QUERY. Query and Folder results override GetType
|
||||
// so this is not used, but is still kept in sync.
|
||||
PRUint32 mContainerType;
|
||||
|
||||
|
@ -592,7 +583,7 @@ public:
|
|||
virtual void RecursiveSort(const char* aData,
|
||||
SortComparator aComparator);
|
||||
PRUint32 FindInsertionPoint(nsNavHistoryResultNode* aNode, SortComparator aComparator,
|
||||
const char* aData);
|
||||
const char* aData, PRBool* aItemExists);
|
||||
PRBool DoesChildNeedResorting(PRUint32 aIndex, SortComparator aComparator,
|
||||
const char* aData);
|
||||
|
||||
|
@ -632,10 +623,6 @@ public:
|
|||
nsNavHistoryResultNode* a, nsNavHistoryResultNode* b, void* closure);
|
||||
PR_STATIC_CALLBACK(int) SortComparison_LastModifiedGreater(
|
||||
nsNavHistoryResultNode* a, nsNavHistoryResultNode* b, void* closure);
|
||||
PR_STATIC_CALLBACK(int) SortComparison_CountLess(
|
||||
nsNavHistoryResultNode* a, nsNavHistoryResultNode* b, void* closure);
|
||||
PR_STATIC_CALLBACK(int) SortComparison_CountGreater(
|
||||
nsNavHistoryResultNode* a, nsNavHistoryResultNode* b, void* closure);
|
||||
PR_STATIC_CALLBACK(int) SortComparison_TagsLess(
|
||||
nsNavHistoryResultNode* a, nsNavHistoryResultNode* b, void* closure);
|
||||
PR_STATIC_CALLBACK(int) SortComparison_TagsGreater(
|
||||
|
@ -662,7 +649,8 @@ public:
|
|||
nsresult InsertChildAt(nsNavHistoryResultNode* aNode, PRInt32 aIndex,
|
||||
PRBool aIsTemporary = PR_FALSE);
|
||||
nsresult InsertSortedChild(nsNavHistoryResultNode* aNode,
|
||||
PRBool aIsTemporary = PR_FALSE);
|
||||
PRBool aIsTemporary = PR_FALSE,
|
||||
PRBool aIgnoreDuplicates = PR_FALSE);
|
||||
PRBool EnsureItemPosition(PRUint32 aIndex);
|
||||
void MergeResults(nsCOMArray<nsNavHistoryResultNode>* aNodes);
|
||||
nsresult ReplaceChildURIAt(PRUint32 aIndex, nsNavHistoryResultNode* aNode);
|
||||
|
@ -700,6 +688,11 @@ public:
|
|||
const nsACString& aIconURI,
|
||||
const nsCOMArray<nsNavHistoryQuery>& aQueries,
|
||||
nsNavHistoryQueryOptions* aOptions);
|
||||
nsNavHistoryQueryResultNode(const nsACString& aTitle,
|
||||
const nsACString& aIconURI,
|
||||
PRTime aTime,
|
||||
const nsCOMArray<nsNavHistoryQuery>& aQueries,
|
||||
nsNavHistoryQueryOptions* aOptions);
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_FORWARD_COMMON_RESULTNODE_TO_BASE
|
||||
|
|
|
@ -283,8 +283,9 @@ function run_test() {
|
|||
do_check_eq(observer._itemChangedProperty, "title");
|
||||
|
||||
// insert query item
|
||||
var newId6 = bmsvc.insertBookmark(testRoot, uri("place:domain=google.com&group=1"),
|
||||
bmsvc.DEFAULT_INDEX, "");
|
||||
var uri6 = uri("place:domain=google.com&type="+
|
||||
Ci.nsINavHistoryQueryOptions.RESULTS_AS_SITE_QUERY);
|
||||
var newId6 = bmsvc.insertBookmark(testRoot, uri6, bmsvc.DEFAULT_INDEX, "");
|
||||
do_check_eq(observer._itemAddedParent, testRoot);
|
||||
do_check_eq(observer._itemAddedIndex, 3);
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ function run_test() {
|
|||
bmsvc.DEFAULT_INDEX, "3 title");
|
||||
|
||||
// bookmark query that should result in the "hierarchical" result
|
||||
// because there is one query, no grouping, one folder,
|
||||
// because there is one query, one folder,
|
||||
// no begin time, no end time, no domain, no uri, no search term
|
||||
// and no max results. See GetSimpleBookmarksQueryFolder()
|
||||
// for more details.
|
||||
|
@ -122,43 +122,4 @@ function run_test() {
|
|||
// multiple folders, a begin time, an end time, a domain, a uri
|
||||
// or a search term, that we get the (correct) flat list results
|
||||
// (like we do when specified maxResults)
|
||||
|
||||
// bookmark query that should result in results grouped by folder
|
||||
// because we specified GROUP_BY_FOLDER
|
||||
var options = histsvc.getNewQueryOptions();
|
||||
options.queryType = Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS;
|
||||
options.setGroupingMode([Ci.nsINavHistoryQueryOptions.GROUP_BY_FOLDER], 1);
|
||||
var query = histsvc.getNewQuery();
|
||||
query.setFolders([folder], 1);
|
||||
var result = histsvc.executeQuery(query, options);
|
||||
var root = result.root;
|
||||
root.containerOpen = true;
|
||||
do_check_eq(root.childCount, 3);
|
||||
|
||||
// note these containers are nsNavHistoryContainerResultNodes,
|
||||
// created in GroupByFolder() and not nsNavHistoryFolderResultNodes,
|
||||
do_check_eq(root.getChild(0).title, "test folder");
|
||||
do_check_eq(root.getChild(1).title, "subfolder 1");
|
||||
do_check_eq(root.getChild(2).title, "subfolder 2");
|
||||
|
||||
// check the contents of the "test folder" container
|
||||
var rfNode = root.getChild(0);
|
||||
rfNode = rfNode.QueryInterface(Ci.nsINavHistoryContainerResultNode);
|
||||
rfNode.containerOpen = true;
|
||||
do_check_eq(rfNode.childCount, 1);
|
||||
do_check_eq(rfNode.getChild(0).itemId, b1);
|
||||
|
||||
// check the contents of the "subfolder 1" container
|
||||
var sf1Node = root.getChild(1);
|
||||
sf1Node = sf1Node.QueryInterface(Ci.nsINavHistoryContainerResultNode);
|
||||
sf1Node.containerOpen = true;
|
||||
do_check_eq(sf1Node.childCount, 1);
|
||||
do_check_eq(sf1Node.getChild(0).itemId, b2);
|
||||
|
||||
// check the contents of the "subfolder 1" container
|
||||
var sf2Node = root.getChild(2);
|
||||
sf2Node = sf2Node.QueryInterface(Ci.nsINavHistoryContainerResultNode);
|
||||
sf2Node.containerOpen = true;
|
||||
do_check_eq(sf2Node.childCount, 1);
|
||||
do_check_eq(sf2Node.getChild(0).itemId, b3);
|
||||
}
|
||||
|
|
|
@ -91,7 +91,8 @@ var observer = {
|
|||
},
|
||||
onEndUpdateBatch: function() {
|
||||
},
|
||||
onVisit: function(aURI, aVisitID, aTime, aSessionID, aReferringID, aTransitionType) {
|
||||
onVisit: function(aURI, aVisitID, aTime, aSessionID,
|
||||
aReferringID, aTransitionType, aAdded) {
|
||||
do_check_eq(aURI.spec, gVisits[this._visitCount].url);
|
||||
do_check_eq(aTransitionType, gVisits[this._visitCount].transition);
|
||||
this._visitCount++;
|
||||
|
@ -110,7 +111,7 @@ var observer = {
|
|||
onPageExpired: function(aURI, aVisitTime, aWholeEntry) {
|
||||
},
|
||||
QueryInterface: function(iid) {
|
||||
if (iid.equals(Ci.nsINavBookmarkObserver) ||
|
||||
if (iid.equals(Ci.nsINavHistoryObserver) ||
|
||||
iid.equals(Ci.nsISupports)) {
|
||||
return this;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче