Bug 639105 - A new entry does not appear in History menu for the certain pages.

r=dietrich
This commit is contained in:
Marco Bonardo 2011-05-03 15:30:19 +02:00
parent 9bbf268d81
commit d7a99498fb
3 changed files with 108 additions and 49 deletions

View File

@ -3560,21 +3560,24 @@ PlacesSQLQueryBuilder::Where()
nsCAutoString additionalPlacesConditions;
if (mRedirectsMode == nsINavHistoryQueryOptions::REDIRECTS_MODE_SOURCE) {
// At least one visit that is not a redirect target should exist.
additionalVisitsConditions += NS_LITERAL_CSTRING(
"AND visit_type NOT IN ") +
nsPrintfCString("(%d,%d) ", nsINavHistoryService::TRANSITION_REDIRECT_PERMANENT,
nsINavHistoryService::TRANSITION_REDIRECT_TEMPORARY);
}
else if (mRedirectsMode == nsINavHistoryQueryOptions::REDIRECTS_MODE_TARGET) {
additionalPlacesConditions += NS_LITERAL_CSTRING(
"AND NOT EXISTS ( "
"SELECT 1 FROM moz_historyvisits v1 "
"JOIN moz_historyvisits v2 ON v2.from_visit = v1.id "
"WHERE v1.place_id = h.id "
"AND v2.visit_type IN ") +
nsPrintfCString("(%d,%d) ", nsINavHistoryService::TRANSITION_REDIRECT_PERMANENT,
nsINavHistoryService::TRANSITION_REDIRECT_TEMPORARY) +
NS_LITERAL_CSTRING(") ");
// At least one visit that is not a redirect source should exist.
additionalPlacesConditions += nsPrintfCString(1024,
"AND EXISTS ( "
"SELECT id "
"FROM moz_historyvisits v "
"WHERE place_id = h.id "
"AND NOT EXISTS(SELECT id FROM moz_historyvisits "
"WHERE from_visit = v.id AND visit_type IN (%d,%d)) "
") ",
nsINavHistoryService::TRANSITION_REDIRECT_PERMANENT,
nsINavHistoryService::TRANSITION_REDIRECT_TEMPORARY);
}
if (!mIncludeHidden) {
@ -3817,22 +3820,26 @@ nsNavHistory::ConstructQueryString(
nsCAutoString additionalQueryOptions;
if (aOptions->RedirectsMode() ==
nsINavHistoryQueryOptions::REDIRECTS_MODE_SOURCE) {
// At least one visit that is not a redirect target should exist.
additionalQueryOptions += nsPrintfCString(256,
"AND NOT EXISTS ( "
"SELECT id FROM moz_historyvisits WHERE place_id = h.id "
"AND visit_type IN (%d,%d)"
"AND EXISTS ( "
"SELECT id "
"FROM moz_historyvisits "
"WHERE place_id = h.id "
"AND visit_type NOT IN (%d,%d)"
") ",
TRANSITION_REDIRECT_PERMANENT,
TRANSITION_REDIRECT_TEMPORARY);
}
else if (aOptions->RedirectsMode() ==
nsINavHistoryQueryOptions::REDIRECTS_MODE_TARGET) {
// At least one visit that is not a redirect source should exist.
additionalQueryOptions += nsPrintfCString(1024,
"AND NOT EXISTS ( "
"AND EXISTS ( "
"SELECT id "
"FROM moz_historyvisits v "
"WHERE place_id = h.id "
"AND EXISTS(SELECT id FROM moz_historyvisits "
"AND NOT EXISTS(SELECT id FROM moz_historyvisits "
"WHERE from_visit = v.id AND visit_type IN (%d,%d)) "
") ",
TRANSITION_REDIRECT_PERMANENT,

View File

@ -329,6 +329,20 @@ function compareArrayToResult(aArray, aRoot) {
// check expected number of results against actual
var expectedResultCount = aArray.filter(function(aEl) { return aEl.isInQuery; }).length;
if (expectedResultCount != aRoot.childCount) {
// Debugging code for failures.
dump_table("moz_places");
dump_table("moz_historyvisits");
LOG("Found children:");
for (let i = 0; i < aRoot.childCount; i++) {
LOG(aRoot.getChild(i).uri);
}
LOG("Expected:");
for (let i = 0; i < aArray.length; i++) {
if (aArray[i].isInQuery)
LOG(aArray[i].uri);
}
}
do_check_eq(expectedResultCount, aRoot.childCount);
var inQueryIndex = 0;

View File

@ -62,51 +62,67 @@ function check_results_callback(aSequence) {
" sortingMode(" + sortingMode + ").");
// Build expectedData array.
let expectedData = visits.filter(function(aVisit, aIndex, aArray) {
switch (aVisit.transType) {
case Ci.nsINavHistoryService.TRANSITION_TYPED:
case Ci.nsINavHistoryService.TRANSITION_LINK:
case Ci.nsINavHistoryService.TRANSITION_BOOKMARK:
case Ci.nsINavHistoryService.TRANSITION_DOWNLOAD:
return redirectsMode != Ci.nsINavHistoryQueryOptions.REDIRECTS_MODE_TARGET;
case Ci.nsINavHistoryService.TRANSITION_EMBED:
return false;
case Ci.nsINavHistoryService.TRANSITION_FRAMED_LINK:
return includeHidden && redirectsMode != Ci.nsINavHistoryQueryOptions.REDIRECTS_MODE_TARGET;
case Ci.nsINavHistoryService.TRANSITION_REDIRECT_TEMPORARY:
case Ci.nsINavHistoryService.TRANSITION_REDIRECT_PERMANENT:
if (redirectsMode == Ci.nsINavHistoryQueryOptions.REDIRECTS_MODE_ALL)
return true;
if (redirectsMode == Ci.nsINavHistoryQueryOptions.REDIRECTS_MODE_TARGET) {
// We must check if this redirect will redirect again.
return aArray.filter(function(refVisit) {
return refVisit.referrer == aVisit.uri;
}).length == 0;
}
return false;
default:
let expectedData = visits.filter(function (aVisit, aIndex, aArray) {
// Embed visits never appear in results.
if (aVisit.transType == Ci.nsINavHistoryService.TRANSITION_EMBED)
return false;
if (aVisit.transType == Ci.nsINavHistoryService.TRANSITION_FRAMED_LINK &&
!includeHidden) {
// If the page has any non-hidden visit, then it's visible.
if (visits.filter(function (refVisit) {
return refVisit.uri == aVisit.uri &&
refVisit.transType != Ci.nsINavHistoryService.TRANSITION_FRAMED_LINK;
}).length == 0)
return false;
}
if (redirectsMode == Ci.nsINavHistoryQueryOptions.REDIRECTS_MODE_SOURCE) {
// Filter out any redirect target.
return aVisit.transType != Ci.nsINavHistoryService.TRANSITION_REDIRECT_PERMANENT &&
aVisit.transType != Ci.nsINavHistoryService.TRANSITION_REDIRECT_TEMPORARY;
}
if (redirectsMode == Ci.nsINavHistoryQueryOptions.REDIRECTS_MODE_TARGET) {
// Filter out any entry that is a redirect source.
return visits.filter(function (refVisit) {
return !refVisit.isRedirect && refVisit.uri == aVisit.uri;
}).length > 0;
}
return true;
});
// Remove duplicates, since queries are RESULTS_AS_URI (unique pages).
let seen = [];
expectedData = expectedData.filter(function (aData) {
if (seen.indexOf(aData.uri) != -1)
return false;
else
seen.push(aData.uri);
return true;
});
// Sort expectedData.
if (sortingMode > 0) {
function comparator(a, b) {
if (sortingMode == Ci.nsINavHistoryQueryOptions.SORT_BY_DATE_DESCENDING)
return b.lastVisit - a.lastVisit;
else if (sortingMode == Ci.nsINavHistoryQueryOptions.SORT_BY_VISITCOUNT_DESCENDING)
return b.visitCount - a.visitCount;
else
return 0;
function getFirstIndexFor(aEntry) {
for (let i = 0; i < visits.length; i++) {
if (visits[i].uri == aEntry.uri)
return i;
}
expectedData.sort(comparator);
}
function comparator(a, b) {
if (sortingMode == Ci.nsINavHistoryQueryOptions.SORT_BY_DATE_DESCENDING)
return b.lastVisit - a.lastVisit;
else if (sortingMode == Ci.nsINavHistoryQueryOptions.SORT_BY_VISITCOUNT_DESCENDING)
return b.visitCount - a.visitCount;
else
return getFirstIndexFor(a) - getFirstIndexFor(b);
}
expectedData.sort(comparator);
// Crop results to maxResults if it's defined.
if (maxResults) {
expectedData = expectedData.filter(function(aVisit, aIndex) {
return aIndex < maxResults;
});
expectedData = expectedData.slice(0, maxResults);
}
// Create a new query with required options.
@ -269,6 +285,28 @@ function add_visits_to_database() {
visitCount: visitCount++,
isInQuery: true }));
// Add a REDIRECT_PERMANENT layer of visits that loop to the first visit.
// These entries should not change visitCount or lastVisit, otherwise
// guessing an order would be a nightmare.
function getLastValue(aURI, aProperty) {
for (let i = 0; i < visits.length; i++) {
if (visits[i].uri == aURI) {
return visits[i][aProperty];
}
}
do_throw("Unknown uri.");
return null;
}
t.forEach(function (transition) visits.push(
{ isVisit: true,
transType: Ci.nsINavHistoryService.TRANSITION_REDIRECT_PERMANENT,
uri: "http://" + transition + ".example.com/",
title: getLastValue("http://" + transition + ".example.com/", "title"),
lastVisit: getLastValue("http://" + transition + ".example.com/", "lastVisit"),
referrer: "http://" + transition + ".redirect.perm.example.com/",
visitCount: getLastValue("http://" + transition + ".example.com/", "visitCount"),
isInQuery: true }));
// Add an unvisited bookmark in the database, it should never appear.
visits.push({ isBookmark: true,
uri: "http://unvisited.bookmark.com/",