Bug 720258 - Inline autocomplete should only autocomplete URLs you've typed.
r=dietrich
This commit is contained in:
@@ -282,6 +282,7 @@ pref("browser.urlbar.doubleClickSelectsAll", true);
|
||||
pref("browser.urlbar.doubleClickSelectsAll", false);
|
||||
#endif
|
||||
pref("browser.urlbar.autoFill", false);
|
||||
pref("browser.urlbar.autoFill.typed", true);
|
||||
// 0: Match anywhere (e.g., middle of words)
|
||||
// 1: Match on word boundaries and then try matching anywhere
|
||||
// 2: Match only on word boundaries (e.g., after / or .)
|
||||
|
||||
@@ -744,6 +744,13 @@ Database::InitSchema(bool* aDatabaseMigrated)
|
||||
|
||||
// Firefox 12 uses schema version 17.
|
||||
|
||||
if (currentSchemaVersion < 18) {
|
||||
rv = MigrateV18Up();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
// Firefox 13 uses schema version 18.
|
||||
|
||||
// Schema Upgrades must add migration code here.
|
||||
|
||||
rv = UpdateBookmarkRootTitles();
|
||||
@@ -790,8 +797,6 @@ Database::InitSchema(bool* aDatabaseMigrated)
|
||||
// moz_hosts.
|
||||
rv = mMainConn->ExecuteSimpleSQL(CREATE_MOZ_HOSTS);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = mMainConn->ExecuteSimpleSQL(CREATE_IDX_MOZ_HOSTS_FRECENCYHOST);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// moz_bookmarks.
|
||||
rv = mMainConn->ExecuteSimpleSQL(CREATE_MOZ_BOOKMARKS);
|
||||
@@ -961,7 +966,9 @@ Database::InitTempTriggers()
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = mMainConn->ExecuteSimpleSQL(CREATE_PLACES_AFTERDELETE_TRIGGER);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = mMainConn->ExecuteSimpleSQL(CREATE_PLACES_AFTERUPDATE_TRIGGER);
|
||||
rv = mMainConn->ExecuteSimpleSQL(CREATE_PLACES_AFTERUPDATE_FRECENCY_TRIGGER);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = mMainConn->ExecuteSimpleSQL(CREATE_PLACES_AFTERUPDATE_TYPED_TRIGGER);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
@@ -1675,8 +1682,6 @@ Database::MigrateV17Up()
|
||||
// Add the moz_hosts table so we can get hostnames for URL autocomplete.
|
||||
rv = mMainConn->ExecuteSimpleSQL(CREATE_MOZ_HOSTS);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = mMainConn->ExecuteSimpleSQL(CREATE_IDX_MOZ_HOSTS_FRECENCYHOST);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
// Fill the moz_hosts table with all the domains in moz_places.
|
||||
@@ -1700,6 +1705,50 @@ Database::MigrateV17Up()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Database::MigrateV18Up()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
// moz_hosts should distinguish on typed entries.
|
||||
|
||||
// Check if the profile already has a typed column.
|
||||
nsCOMPtr<mozIStorageStatement> stmt;
|
||||
nsresult rv = mMainConn->CreateStatement(NS_LITERAL_CSTRING(
|
||||
"SELECT typed FROM moz_hosts"
|
||||
), getter_AddRefs(stmt));
|
||||
if (NS_FAILED(rv)) {
|
||||
rv = mMainConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"ALTER TABLE moz_hosts ADD COLUMN typed NOT NULL DEFAULT 0"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
// With the addition of the typed column the covering index loses its
|
||||
// advantages. On the other side querying on host and (optionally) typed
|
||||
// largely restricts the number of results, making scans decently fast.
|
||||
rv = mMainConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"DROP INDEX IF EXISTS moz_hosts_frecencyhostindex"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Update typed data.
|
||||
nsCOMPtr<mozIStorageAsyncStatement> updateTypedStmt;
|
||||
rv = mMainConn->CreateAsyncStatement(NS_LITERAL_CSTRING(
|
||||
"UPDATE moz_hosts SET typed = 1 WHERE host IN ( "
|
||||
"SELECT fixup_url(get_unreversed_host(rev_host)) "
|
||||
"FROM moz_places WHERE typed = 1 "
|
||||
") "
|
||||
), getter_AddRefs(updateTypedStmt));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<mozIStoragePendingStatement> ps;
|
||||
rv = updateTypedStmt->ExecuteAsync(nsnull, getter_AddRefs(ps));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
Database::Shutdown()
|
||||
{
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
|
||||
// This is the schema version. Update it at any schema change and add a
|
||||
// corresponding migrateVxx method below.
|
||||
#define DATABASE_SCHEMA_VERSION 17
|
||||
#define DATABASE_SCHEMA_VERSION 18
|
||||
|
||||
// Fired after Places inited.
|
||||
#define TOPIC_PLACES_INIT_COMPLETE "places-init-complete"
|
||||
@@ -300,6 +300,7 @@ protected:
|
||||
nsresult MigrateV15Up();
|
||||
nsresult MigrateV16Up();
|
||||
nsresult MigrateV17Up();
|
||||
nsresult MigrateV18Up();
|
||||
|
||||
nsresult UpdateBookmarkRootTitles();
|
||||
nsresult CheckAndUpdateGUIDs();
|
||||
|
||||
@@ -102,7 +102,11 @@ const kQueryTypeFiltered = 1;
|
||||
const kTitleTagsSeparator = " \u2013 ";
|
||||
|
||||
const kBrowserUrlbarBranch = "browser.urlbar.";
|
||||
const kBrowserUrlbarAutofillPref = "browser.urlbar.autoFill";
|
||||
|
||||
// Toggle autoFill.
|
||||
const kBrowserUrlbarAutofillPref = "autoFill";
|
||||
// Whether to search only typed entries.
|
||||
const kBrowserUrlbarAutofillTypedPref = "autoFill.typed";
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Globals
|
||||
@@ -840,8 +844,6 @@ nsPlacesAutoComplete.prototype = {
|
||||
*/
|
||||
_loadPrefs: function PAC_loadPrefs(aRegisterObserver)
|
||||
{
|
||||
let self = this;
|
||||
|
||||
this._enabled = safePrefGetter(this._prefs, "autocomplete.enabled", true);
|
||||
this._matchBehavior = safePrefGetter(this._prefs,
|
||||
"matchBehavior",
|
||||
@@ -1287,8 +1289,7 @@ nsPlacesAutoComplete.prototype = {
|
||||
function urlInlineComplete()
|
||||
{
|
||||
this._loadPrefs(true);
|
||||
// register observers
|
||||
Services.obs.addObserver(this, kTopicShutdown, false);
|
||||
Services.obs.addObserver(this, kTopicShutdown, true);
|
||||
}
|
||||
|
||||
urlInlineComplete.prototype = {
|
||||
@@ -1301,10 +1302,8 @@ urlInlineComplete.prototype = {
|
||||
get _db()
|
||||
{
|
||||
if (!this.__db && this._autofill) {
|
||||
this.__db = Cc["@mozilla.org/browser/nav-history-service;1"].
|
||||
getService(Ci.nsPIPlacesDatabase).
|
||||
DBConnection.
|
||||
clone(true);
|
||||
this.__db = PlacesUtils.history.QueryInterface(Ci.nsPIPlacesDatabase).
|
||||
DBConnection.clone(true);
|
||||
}
|
||||
return this.__db;
|
||||
},
|
||||
@@ -1317,9 +1316,11 @@ urlInlineComplete.prototype = {
|
||||
// Add a trailing slash at the end of the hostname, since we always
|
||||
// want to complete up to and including a URL separator.
|
||||
this.__syncQuery = this._db.createStatement(
|
||||
"SELECT host || '/' "
|
||||
"/* do not warn (bug no): could index on (typed,frecency) but not worth it */ "
|
||||
+ "SELECT host || '/' "
|
||||
+ "FROM moz_hosts "
|
||||
+ "WHERE host BETWEEN :search_string AND :search_string || X'FFFF' "
|
||||
+ (this._autofillTyped ? "AND typed = 1 " : "")
|
||||
+ "ORDER BY frecency DESC "
|
||||
+ "LIMIT 1"
|
||||
);
|
||||
@@ -1333,9 +1334,11 @@ urlInlineComplete.prototype = {
|
||||
{
|
||||
if (!this.__asyncQuery) {
|
||||
this.__asyncQuery = this._db.createAsyncStatement(
|
||||
"SELECT h.url "
|
||||
"/* do not warn (bug no): can't use an index */ "
|
||||
+ "SELECT h.url "
|
||||
+ "FROM moz_places h "
|
||||
+ "WHERE h.frecency <> 0 "
|
||||
+ (this._autofillTyped ? "AND h.typed = 1 " : "")
|
||||
+ "AND AUTOCOMPLETE_MATCH(:searchString, h.url, "
|
||||
+ "h.title, '', "
|
||||
+ "h.visit_count, h.typed, 0, 0, "
|
||||
@@ -1463,11 +1466,15 @@ urlInlineComplete.prototype = {
|
||||
*/
|
||||
_loadPrefs: function UIC_loadPrefs(aRegisterObserver)
|
||||
{
|
||||
this._autofill = safePrefGetter(Services.prefs,
|
||||
let prefBranch = Services.prefs.getBranch(kBrowserUrlbarBranch);
|
||||
this._autofill = safePrefGetter(prefBranch,
|
||||
kBrowserUrlbarAutofillPref,
|
||||
true);
|
||||
this._autofillTyped = safePrefGetter(prefBranch,
|
||||
kBrowserUrlbarAutofillTypedPref,
|
||||
true);
|
||||
if (aRegisterObserver) {
|
||||
Services.prefs.addObserver(kBrowserUrlbarAutofillPref, this, true);
|
||||
Services.prefs.addObserver(kBrowserUrlbarBranch, this, true);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1511,27 +1518,31 @@ urlInlineComplete.prototype = {
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//// nsIObserver
|
||||
|
||||
observe: function PAC_observe(aSubject, aTopic, aData)
|
||||
observe: function UIC_observe(aSubject, aTopic, aData)
|
||||
{
|
||||
if (aTopic == kTopicShutdown) {
|
||||
Services.obs.removeObserver(this, kTopicShutdown);
|
||||
this._closeDatabase();
|
||||
}
|
||||
else if (aTopic == kPrefChanged) {
|
||||
else if (aTopic == kPrefChanged &&
|
||||
(aData.substr(kBrowserUrlbarBranch.length) == kBrowserUrlbarAutofillPref ||
|
||||
aData.substr(kBrowserUrlbarBranch.length) == kBrowserUrlbarAutofillTypedPref)) {
|
||||
let previousAutofillTyped = this._autofillTyped;
|
||||
this._loadPrefs();
|
||||
if (!this._autofill) {
|
||||
this.stopSearch();
|
||||
this._closeDatabase();
|
||||
}
|
||||
else if (this._autofillTyped != previousAutofillTyped) {
|
||||
// Invalidate the statements to update them for the new typed status.
|
||||
this._invalidateStatements();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* Finalize and close the database safely
|
||||
*
|
||||
**/
|
||||
_closeDatabase: function UIC_closeDatabase()
|
||||
* Finalizes and invalidates cached statements.
|
||||
*/
|
||||
_invalidateStatements: function UIC_invalidateStatements()
|
||||
{
|
||||
// Finalize the statements that we have used.
|
||||
let stmts = [
|
||||
@@ -1546,6 +1557,14 @@ urlInlineComplete.prototype = {
|
||||
this[stmts[i]] = null;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Closes the database.
|
||||
*/
|
||||
_closeDatabase: function UIC_closeDatabase()
|
||||
{
|
||||
this._invalidateStatements();
|
||||
if (this.__db) {
|
||||
this._db.asyncClose();
|
||||
this.__db = null;
|
||||
|
||||
@@ -136,15 +136,6 @@
|
||||
"placeattributeindex", "moz_annos", "place_id, anno_attribute_id", "UNIQUE" \
|
||||
)
|
||||
|
||||
/**
|
||||
* moz_hosts
|
||||
*/
|
||||
|
||||
#define CREATE_IDX_MOZ_HOSTS_FRECENCYHOST \
|
||||
CREATE_PLACES_IDX( \
|
||||
"frecencyhostindex", "moz_hosts", "frecency, host", "" \
|
||||
)
|
||||
|
||||
/**
|
||||
* moz_items_annos
|
||||
*/
|
||||
|
||||
@@ -167,6 +167,7 @@
|
||||
" id INTEGER PRIMARY KEY" \
|
||||
", host TEXT NOT NULL UNIQUE" \
|
||||
", frecency INTEGER" \
|
||||
", typed INTEGER NOT NULL DEFAULT 0" \
|
||||
")" \
|
||||
)
|
||||
|
||||
|
||||
@@ -87,11 +87,12 @@
|
||||
"AFTER INSERT ON moz_places FOR EACH ROW " \
|
||||
"WHEN LENGTH(NEW.rev_host) > 1 " \
|
||||
"BEGIN " \
|
||||
"INSERT OR REPLACE INTO moz_hosts (id, host, frecency) " \
|
||||
"INSERT OR REPLACE INTO moz_hosts (id, host, frecency, typed) " \
|
||||
"VALUES (" \
|
||||
"(SELECT id FROM moz_hosts WHERE host = fixup_url(get_unreversed_host(NEW.rev_host))), " \
|
||||
"fixup_url(get_unreversed_host(NEW.rev_host)), " \
|
||||
"MAX((SELECT frecency FROM moz_hosts WHERE host = fixup_url(get_unreversed_host(NEW.rev_host))), NEW.frecency) " \
|
||||
"MAX((SELECT frecency FROM moz_hosts WHERE host = fixup_url(get_unreversed_host(NEW.rev_host))), NEW.frecency), " \
|
||||
"MAX(IFNULL((SELECT typed FROM moz_hosts WHERE host = fixup_url(get_unreversed_host(NEW.rev_host))), 0), NEW.typed) " \
|
||||
"); " \
|
||||
"END" \
|
||||
)
|
||||
@@ -110,7 +111,7 @@
|
||||
// frecency changes by a meaningful percentage. This is because the frecency
|
||||
// decay algorithm requires to update all the frecencies at once, causing a
|
||||
// too high overhead, while leaving the ordering unchanged.
|
||||
#define CREATE_PLACES_AFTERUPDATE_TRIGGER NS_LITERAL_CSTRING( \
|
||||
#define CREATE_PLACES_AFTERUPDATE_FRECENCY_TRIGGER NS_LITERAL_CSTRING( \
|
||||
"CREATE TEMP TRIGGER moz_places_afterupdate_frecency_trigger " \
|
||||
"AFTER UPDATE OF frecency ON moz_places FOR EACH ROW " \
|
||||
"WHEN NEW.frecency >= 0 " \
|
||||
@@ -127,6 +128,17 @@
|
||||
"END" \
|
||||
)
|
||||
|
||||
#define CREATE_PLACES_AFTERUPDATE_TYPED_TRIGGER NS_LITERAL_CSTRING( \
|
||||
"CREATE TEMP TRIGGER moz_places_afterupdate_typed_trigger " \
|
||||
"AFTER UPDATE OF typed ON moz_places FOR EACH ROW " \
|
||||
"WHEN NEW.typed = 1 " \
|
||||
"BEGIN " \
|
||||
"UPDATE moz_hosts " \
|
||||
"SET typed = 1 " \
|
||||
"WHERE host = fixup_url(get_unreversed_host(NEW.rev_host)); " \
|
||||
"END" \
|
||||
)
|
||||
|
||||
/**
|
||||
* This trigger removes a row from moz_openpages_temp when open_count reaches 0.
|
||||
*
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
const CURRENT_SCHEMA_VERSION = 17;
|
||||
const CURRENT_SCHEMA_VERSION = 18;
|
||||
|
||||
const NS_APP_USER_PROFILE_50_DIR = "ProfD";
|
||||
const NS_APP_PROFILE_DIR_STARTUP = "ProfDS";
|
||||
|
||||
@@ -21,29 +21,6 @@ XPCOMUtils.defineLazyServiceGetter(this, "gHistory",
|
||||
"@mozilla.org/browser/history;1",
|
||||
"mozIAsyncHistory");
|
||||
|
||||
function VisitInfo(aTransitionType, aVisitTime)
|
||||
{
|
||||
this.transitionType =
|
||||
aTransitionType === undefined ? TRANSITION_LINK : aTransitionType;
|
||||
this.visitDate = aVisitTime || Date.now() * 1000;
|
||||
}
|
||||
|
||||
function addVisits(aUrls)
|
||||
{
|
||||
let places = [];
|
||||
aUrls.forEach(function(url) {
|
||||
places.push({
|
||||
uri: url.url,
|
||||
title: "test for " + url.url,
|
||||
visits: [
|
||||
new VisitInfo(url.transition),
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
gHistory.updatePlaces(places);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param aSearches
|
||||
* Array of AutoCompleteSearch names.
|
||||
@@ -168,8 +145,10 @@ function ensure_results(aSearchString, aExpectedValue) {
|
||||
|
||||
function run_test() {
|
||||
Services.prefs.setBoolPref("browser.urlbar.autoFill", true);
|
||||
Services.prefs.setBoolPref("browser.urlbar.autoFill.typed", false);
|
||||
do_register_cleanup(function () {
|
||||
Services.prefs.clearUserPref("browser.urlbar.autoFill");
|
||||
Services.prefs.clearUserPref("browser.urlbar.autoFill.typed");
|
||||
});
|
||||
|
||||
gAutoCompleteTests.forEach(function (testData) {
|
||||
@@ -214,3 +193,26 @@ function addBookmark(aBookmarkObj) {
|
||||
PlacesUtils.bookmarks.setKeywordForBookmark(itemId, aBookmarkObj.keyword);
|
||||
}
|
||||
}
|
||||
|
||||
function VisitInfo(aTransitionType, aVisitTime)
|
||||
{
|
||||
this.transitionType =
|
||||
aTransitionType === undefined ? TRANSITION_LINK : aTransitionType;
|
||||
this.visitDate = aVisitTime || Date.now() * 1000;
|
||||
}
|
||||
|
||||
function addVisits(aUrls)
|
||||
{
|
||||
let places = [];
|
||||
aUrls.forEach(function(url) {
|
||||
places.push({
|
||||
uri: url.url,
|
||||
title: "test for " + url.url,
|
||||
visits: [
|
||||
new VisitInfo(url.transition),
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
gHistory.updatePlaces(places);
|
||||
}
|
||||
|
||||
80
toolkit/components/places/tests/inline/test_typed.js
Normal file
80
toolkit/components/places/tests/inline/test_typed.js
Normal file
@@ -0,0 +1,80 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// First do searches with typed behavior forced to false, so later tests will
|
||||
// ensure autocomplete is able to dinamically switch behavior.
|
||||
|
||||
add_autocomplete_test([
|
||||
"Searching for domain should autoFill it",
|
||||
"moz",
|
||||
"mozilla.org/",
|
||||
function () {
|
||||
Services.prefs.setBoolPref("browser.urlbar.autoFill.typed", false);
|
||||
addVisits([ { url: NetUtil.newURI("http://mozilla.org/link/")
|
||||
, transition: TRANSITION_LINK }
|
||||
]);
|
||||
}
|
||||
]);
|
||||
|
||||
add_autocomplete_test([
|
||||
"Searching for url should autoFill it",
|
||||
"mozilla.org/li",
|
||||
"mozilla.org/link/",
|
||||
function () {
|
||||
Services.prefs.setBoolPref("browser.urlbar.autoFill.typed", false);
|
||||
addVisits([ { url: NetUtil.newURI("http://mozilla.org/link/")
|
||||
, transition: TRANSITION_LINK }
|
||||
]);
|
||||
}
|
||||
]);
|
||||
|
||||
// Now do searches with typed behavior forced to true.
|
||||
|
||||
add_autocomplete_test([
|
||||
"Searching for non-typed domain should not autoFill it",
|
||||
"moz",
|
||||
"moz",
|
||||
function () {
|
||||
Services.prefs.setBoolPref("browser.urlbar.autoFill.typed", true);
|
||||
addVisits([ { url: NetUtil.newURI("http://mozilla.org/link/")
|
||||
, transition: TRANSITION_LINK }
|
||||
]);
|
||||
}
|
||||
]);
|
||||
|
||||
add_autocomplete_test([
|
||||
"Searching for typed domain should autoFill it",
|
||||
"moz",
|
||||
"mozilla.org/",
|
||||
function () {
|
||||
Services.prefs.setBoolPref("browser.urlbar.autoFill.typed", true);
|
||||
addVisits([ { url: NetUtil.newURI("http://mozilla.org/typed/")
|
||||
, transition: TRANSITION_TYPED }
|
||||
]);
|
||||
}
|
||||
]);
|
||||
|
||||
add_autocomplete_test([
|
||||
"Searching for non-typed url should not autoFill it",
|
||||
"mozilla.org/li",
|
||||
"mozilla.org/li",
|
||||
function () {
|
||||
Services.prefs.setBoolPref("browser.urlbar.autoFill.typed", true);
|
||||
addVisits([ { url: NetUtil.newURI("http://mozilla.org/link/")
|
||||
, transition: TRANSITION_LINK }
|
||||
]);
|
||||
}
|
||||
]);
|
||||
|
||||
add_autocomplete_test([
|
||||
"Searching for typed url should autoFill it",
|
||||
"mozilla.org/li",
|
||||
"mozilla.org/link/",
|
||||
function () {
|
||||
Services.prefs.setBoolPref("browser.urlbar.autoFill.typed", true);
|
||||
addVisits([ { url: NetUtil.newURI("http://mozilla.org/link/")
|
||||
, transition: TRANSITION_TYPED }
|
||||
]);
|
||||
}
|
||||
]);
|
||||
@@ -5,3 +5,4 @@ tail =
|
||||
[test_autocomplete_functional.js]
|
||||
[test_casing.js]
|
||||
[test_keywords.js]
|
||||
[test_typed.js]
|
||||
|
||||
@@ -282,30 +282,40 @@ function test_moz_hosts()
|
||||
{
|
||||
// This will throw if the column does not exist
|
||||
let stmt = DBConn().createStatement(
|
||||
"SELECT host, frecency "
|
||||
"SELECT host, frecency, typed "
|
||||
+ "FROM moz_hosts "
|
||||
);
|
||||
stmt.finalize();
|
||||
|
||||
// moz_hosts is populated asynchronously, so query asynchronously to serialize
|
||||
// to that.
|
||||
// check the number of entries in moz_hosts equals the number of
|
||||
// unique rev_host in moz_places
|
||||
var query = "SELECT ("
|
||||
+ "SELECT COUNT(host) "
|
||||
+ "FROM moz_hosts), ("
|
||||
+ "SELECT COUNT(DISTINCT rev_host) "
|
||||
+ "FROM moz_places "
|
||||
+ "WHERE LENGTH(rev_host) > 1)";
|
||||
|
||||
stmt = DBConn().createStatement(query);
|
||||
stmt = DBConn().createAsyncStatement(
|
||||
"SELECT ("
|
||||
+ "SELECT COUNT(host) "
|
||||
+ "FROM moz_hosts), ("
|
||||
+ "SELECT COUNT(DISTINCT rev_host) "
|
||||
+ "FROM moz_places "
|
||||
+ "WHERE LENGTH(rev_host) > 1)"
|
||||
);
|
||||
try {
|
||||
stmt.executeStep();
|
||||
let mozPlacesCount = stmt.getInt32(0);
|
||||
let mozHostsCount = stmt.getInt32(1);
|
||||
do_check_eq(mozPlacesCount, mozHostsCount);
|
||||
stmt.executeAsync({
|
||||
handleResult: function (aResultSet) {
|
||||
let row = aResult.getNextRow();
|
||||
let mozPlacesCount = row.getResultByIndex(0);
|
||||
let mozHostsCount = row.getResultByIndex(1);
|
||||
do_check_eq(mozPlacesCount, mozHostsCount);
|
||||
},
|
||||
handleError: function () {},
|
||||
handleCompletion: function (aReason) {
|
||||
do_check_eq(aReason, Ci.mozIStorageStatementCallback.REASON_FINISHED);
|
||||
run_next_test();
|
||||
}
|
||||
});
|
||||
}
|
||||
finally {
|
||||
stmt.finalize();
|
||||
run_next_test();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -328,8 +338,6 @@ function test_final_state()
|
||||
do_check_true(db.indexExists("moz_places_guid_uniqueindex"));
|
||||
do_check_true(db.indexExists("moz_favicons_guid_uniqueindex"));
|
||||
|
||||
do_check_true(db.indexExists("moz_hosts_frecencyhostindex"));
|
||||
|
||||
do_check_eq(db.schemaVersion, CURRENT_SCHEMA_VERSION);
|
||||
|
||||
db.close();
|
||||
|
||||
@@ -5,6 +5,10 @@
|
||||
* This file tests the validity of various triggers that add remove hosts from moz_hosts
|
||||
*/
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "gHistory",
|
||||
"@mozilla.org/browser/history;1",
|
||||
"mozIAsyncHistory");
|
||||
|
||||
// add some visits and remove them, add a bookmark,
|
||||
// change its uri, then remove it, and
|
||||
// for each change check that moz_hosts has correctly been updated.
|
||||
@@ -28,10 +32,10 @@ function isHostInMozPlaces(aURI)
|
||||
return result;
|
||||
}
|
||||
|
||||
function isHostInMozHosts(aURI)
|
||||
function isHostInMozHosts(aURI, aTyped)
|
||||
{
|
||||
let stmt = DBConn().createStatement(
|
||||
"SELECT host "
|
||||
"SELECT host, typed "
|
||||
+ "FROM moz_hosts "
|
||||
+ "WHERE host = :host"
|
||||
);
|
||||
@@ -39,7 +43,10 @@ function isHostInMozHosts(aURI)
|
||||
stmt.params.host = aURI.host;
|
||||
while(stmt.executeStep()) {
|
||||
if (stmt.row.host == aURI.host) {
|
||||
result = true;
|
||||
if (aTyped != null)
|
||||
result = aTyped == stmt.row.typed;
|
||||
else
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -49,12 +56,15 @@ function isHostInMozHosts(aURI)
|
||||
|
||||
let urls = [{uri: NetUtil.newURI("http://visit1.mozilla.org"),
|
||||
expected: "visit1.mozilla.org",
|
||||
typed: 0
|
||||
},
|
||||
{uri: NetUtil.newURI("http://visit2.mozilla.org"),
|
||||
expected: "visit2.mozilla.org",
|
||||
typed: 0
|
||||
},
|
||||
{uri: NetUtil.newURI("http://www.foo.mozilla.org"),
|
||||
expected: "foo.mozilla.org",
|
||||
typed: 1
|
||||
},
|
||||
];
|
||||
|
||||
@@ -75,16 +85,12 @@ function test_moz_hosts_update()
|
||||
uri: url.uri,
|
||||
title: "test for " + url.url,
|
||||
visits: [
|
||||
new VisitInfo(),
|
||||
new VisitInfo(url.typed ? TRANSITION_TYPED : undefined),
|
||||
],
|
||||
};
|
||||
places.push(place);
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "gHistory",
|
||||
"@mozilla.org/browser/history;1",
|
||||
"mozIAsyncHistory");
|
||||
|
||||
gHistory.updatePlaces(places, {
|
||||
handleResult: function () {
|
||||
},
|
||||
@@ -92,10 +98,11 @@ function test_moz_hosts_update()
|
||||
do_throw("gHistory.updatePlaces() failed");
|
||||
},
|
||||
handleCompletion: function () {
|
||||
do_check_true(isHostInMozHosts(urls[0].uri));
|
||||
do_check_true(isHostInMozHosts(urls[1].uri));
|
||||
do_check_true(isHostInMozHosts(urls[0].uri, urls[0].typed));
|
||||
do_check_true(isHostInMozHosts(urls[1].uri, urls[1].typed));
|
||||
// strip the WWW from the url before testing...
|
||||
do_check_true(isHostInMozHosts(NetUtil.newURI("http://foo.mozilla.org")));
|
||||
do_check_true(isHostInMozHosts(NetUtil.newURI("http://foo.mozilla.org"),
|
||||
urls[2].typed));
|
||||
run_next_test();
|
||||
}
|
||||
});
|
||||
@@ -148,7 +155,29 @@ function test_bookmark_removal()
|
||||
do_check_false(isHostInMozHosts(newUri));
|
||||
run_next_test();
|
||||
});
|
||||
}
|
||||
|
||||
function test_moz_hosts_typed_update()
|
||||
{
|
||||
const TEST_URI = NetUtil.newURI("http://typed.mozilla.com");
|
||||
let places = [{ uri: TEST_URI
|
||||
, title: "test for " + TEST_URI.spec
|
||||
, visits: [ new VisitInfo(TRANSITION_LINK)
|
||||
, new VisitInfo(TRANSITION_TYPED)
|
||||
]
|
||||
}];
|
||||
|
||||
gHistory.updatePlaces(places, {
|
||||
handleResult: function () {
|
||||
},
|
||||
handleError: function () {
|
||||
do_throw("gHistory.updatePlaces() failed");
|
||||
},
|
||||
handleCompletion: function () {
|
||||
do_check_true(isHostInMozHosts(TEST_URI, true));
|
||||
run_next_test();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -159,6 +188,7 @@ function test_bookmark_removal()
|
||||
test_remove_places,
|
||||
test_bookmark_changes,
|
||||
test_bookmark_removal,
|
||||
test_moz_hosts_typed_update,
|
||||
].forEach(add_test);
|
||||
|
||||
function run_test()
|
||||
|
||||
Reference in New Issue
Block a user