gecko/toolkit/components/places/nsPlacesAutoComplete.js
Mitchell Field 0b02d21584 Bug 595513 - Reduce makefile recursion in toolkit. r=khuey
--HG--
rename : toolkit/components/alerts/src/mac/Makefile.in => toolkit/components/alerts/mac/Makefile.in
rename : toolkit/components/alerts/src/mac/growl/CFGrowlAdditions.c => toolkit/components/alerts/mac/growl/CFGrowlAdditions.c
rename : toolkit/components/alerts/src/mac/growl/CFGrowlAdditions.h => toolkit/components/alerts/mac/growl/CFGrowlAdditions.h
rename : toolkit/components/alerts/src/mac/growl/CFGrowlDefines.h => toolkit/components/alerts/mac/growl/CFGrowlDefines.h
rename : toolkit/components/alerts/src/mac/growl/CFMutableDictionaryAdditions.c => toolkit/components/alerts/mac/growl/CFMutableDictionaryAdditions.c
rename : toolkit/components/alerts/src/mac/growl/CFMutableDictionaryAdditions.h => toolkit/components/alerts/mac/growl/CFMutableDictionaryAdditions.h
rename : toolkit/components/alerts/src/mac/growl/CFURLAdditions.c => toolkit/components/alerts/mac/growl/CFURLAdditions.c
rename : toolkit/components/alerts/src/mac/growl/CFURLAdditions.h => toolkit/components/alerts/mac/growl/CFURLAdditions.h
rename : toolkit/components/alerts/src/mac/growl/GrowlAbstractSingletonObject.h => toolkit/components/alerts/mac/growl/GrowlAbstractSingletonObject.h
rename : toolkit/components/alerts/src/mac/growl/GrowlApplicationBridge.h => toolkit/components/alerts/mac/growl/GrowlApplicationBridge.h
rename : toolkit/components/alerts/src/mac/growl/GrowlApplicationBridge.m => toolkit/components/alerts/mac/growl/GrowlApplicationBridge.m
rename : toolkit/components/alerts/src/mac/growl/GrowlDefines.h => toolkit/components/alerts/mac/growl/GrowlDefines.h
rename : toolkit/components/alerts/src/mac/growl/GrowlDefinesInternal.h => toolkit/components/alerts/mac/growl/GrowlDefinesInternal.h
rename : toolkit/components/alerts/src/mac/growl/GrowlPathUtilities.h => toolkit/components/alerts/mac/growl/GrowlPathUtilities.h
rename : toolkit/components/alerts/src/mac/growl/GrowlPathUtilities.m => toolkit/components/alerts/mac/growl/GrowlPathUtilities.m
rename : toolkit/components/alerts/src/mac/growl/GrowlPathway.h => toolkit/components/alerts/mac/growl/GrowlPathway.h
rename : toolkit/components/alerts/src/mac/growl/GrowlPreferencesController.h => toolkit/components/alerts/mac/growl/GrowlPreferencesController.h
rename : toolkit/components/alerts/src/mac/growl/GrowlTicketController.h => toolkit/components/alerts/mac/growl/GrowlTicketController.h
rename : toolkit/components/alerts/src/mac/growl/Makefile.in => toolkit/components/alerts/mac/growl/Makefile.in
rename : toolkit/components/alerts/src/mac/growl/license.txt => toolkit/components/alerts/mac/growl/license.txt
rename : toolkit/components/alerts/src/mac/mozGrowlDelegate.h => toolkit/components/alerts/mac/mozGrowlDelegate.h
rename : toolkit/components/alerts/src/mac/mozGrowlDelegate.mm => toolkit/components/alerts/mac/mozGrowlDelegate.mm
rename : toolkit/components/alerts/src/mac/nsAlertsImageLoadListener.h => toolkit/components/alerts/mac/nsAlertsImageLoadListener.h
rename : toolkit/components/alerts/src/mac/nsAlertsImageLoadListener.mm => toolkit/components/alerts/mac/nsAlertsImageLoadListener.mm
rename : toolkit/components/alerts/src/mac/nsAlertsService.h => toolkit/components/alerts/mac/nsAlertsService.h
rename : toolkit/components/alerts/src/mac/nsAlertsService.mm => toolkit/components/alerts/mac/nsAlertsService.mm
rename : toolkit/components/alerts/src/mac/nsAlertsServiceModule.cpp => toolkit/components/alerts/mac/nsAlertsServiceModule.cpp
rename : toolkit/components/alerts/src/mac/nsNotificationsList.h => toolkit/components/alerts/mac/nsNotificationsList.h
rename : toolkit/components/alerts/src/mac/nsNotificationsList.mm => toolkit/components/alerts/mac/nsNotificationsList.mm
rename : toolkit/components/alerts/src/nsAlertsService.cpp => toolkit/components/alerts/nsAlertsService.cpp
rename : toolkit/components/alerts/src/nsAlertsService.h => toolkit/components/alerts/nsAlertsService.h
rename : toolkit/components/alerts/public/nsIAlertsService.idl => toolkit/components/alerts/nsIAlertsService.idl
rename : toolkit/components/alerts/public/nsINotificationsList.idl => toolkit/components/alerts/nsINotificationsList.idl
rename : toolkit/components/autocomplete/src/nsAutoCompleteController.cpp => toolkit/components/autocomplete/nsAutoCompleteController.cpp
rename : toolkit/components/autocomplete/src/nsAutoCompleteController.h => toolkit/components/autocomplete/nsAutoCompleteController.h
rename : toolkit/components/autocomplete/src/nsAutoCompleteSimpleResult.cpp => toolkit/components/autocomplete/nsAutoCompleteSimpleResult.cpp
rename : toolkit/components/autocomplete/src/nsAutoCompleteSimpleResult.h => toolkit/components/autocomplete/nsAutoCompleteSimpleResult.h
rename : toolkit/components/autocomplete/public/nsIAutoCompleteController.idl => toolkit/components/autocomplete/nsIAutoCompleteController.idl
rename : toolkit/components/autocomplete/public/nsIAutoCompleteInput.idl => toolkit/components/autocomplete/nsIAutoCompleteInput.idl
rename : toolkit/components/autocomplete/public/nsIAutoCompletePopup.idl => toolkit/components/autocomplete/nsIAutoCompletePopup.idl
rename : toolkit/components/autocomplete/public/nsIAutoCompleteResult.idl => toolkit/components/autocomplete/nsIAutoCompleteResult.idl
rename : toolkit/components/autocomplete/public/nsIAutoCompleteSearch.idl => toolkit/components/autocomplete/nsIAutoCompleteSearch.idl
rename : toolkit/components/autocomplete/public/nsIAutoCompleteSimpleResult.idl => toolkit/components/autocomplete/nsIAutoCompleteSimpleResult.idl
rename : toolkit/components/commandlines/src/nsCommandLine.cpp => toolkit/components/commandlines/nsCommandLine.cpp
rename : toolkit/components/commandlines/public/nsICommandLine.idl => toolkit/components/commandlines/nsICommandLine.idl
rename : toolkit/components/commandlines/public/nsICommandLineHandler.idl => toolkit/components/commandlines/nsICommandLineHandler.idl
rename : toolkit/components/commandlines/public/nsICommandLineRunner.idl => toolkit/components/commandlines/nsICommandLineRunner.idl
rename : toolkit/components/commandlines/public/nsICommandLineValidator.idl => toolkit/components/commandlines/nsICommandLineValidator.idl
rename : toolkit/components/contentprefs/src/nsContentPrefService.js => toolkit/components/contentprefs/nsContentPrefService.js
rename : toolkit/components/contentprefs/src/nsContentPrefService.manifest => toolkit/components/contentprefs/nsContentPrefService.manifest
rename : toolkit/components/downloads/src/nsDownloadManager.cpp => toolkit/components/downloads/nsDownloadManager.cpp
rename : toolkit/components/downloads/src/nsDownloadManager.h => toolkit/components/downloads/nsDownloadManager.h
rename : toolkit/components/downloads/src/nsDownloadManagerUI.js => toolkit/components/downloads/nsDownloadManagerUI.js
rename : toolkit/components/downloads/src/nsDownloadManagerUI.manifest => toolkit/components/downloads/nsDownloadManagerUI.manifest
rename : toolkit/components/downloads/src/nsDownloadProxy.h => toolkit/components/downloads/nsDownloadProxy.h
rename : toolkit/components/downloads/src/nsDownloadScanner.cpp => toolkit/components/downloads/nsDownloadScanner.cpp
rename : toolkit/components/downloads/src/nsDownloadScanner.h => toolkit/components/downloads/nsDownloadScanner.h
rename : toolkit/components/downloads/public/nsIDownload.idl => toolkit/components/downloads/nsIDownload.idl
rename : toolkit/components/downloads/public/nsIDownloadManager.idl => toolkit/components/downloads/nsIDownloadManager.idl
rename : toolkit/components/downloads/public/nsIDownloadManagerUI.idl => toolkit/components/downloads/nsIDownloadManagerUI.idl
rename : toolkit/components/downloads/public/nsIDownloadProgressListener.idl => toolkit/components/downloads/nsIDownloadProgressListener.idl
rename : toolkit/components/feeds/src/FeedProcessor.js => toolkit/components/feeds/FeedProcessor.js
rename : toolkit/components/feeds/src/FeedProcessor.manifest => toolkit/components/feeds/FeedProcessor.manifest
rename : toolkit/components/feeds/public/nsIFeed.idl => toolkit/components/feeds/nsIFeed.idl
rename : toolkit/components/feeds/public/nsIFeedContainer.idl => toolkit/components/feeds/nsIFeedContainer.idl
rename : toolkit/components/feeds/public/nsIFeedElementBase.idl => toolkit/components/feeds/nsIFeedElementBase.idl
rename : toolkit/components/feeds/public/nsIFeedEntry.idl => toolkit/components/feeds/nsIFeedEntry.idl
rename : toolkit/components/feeds/public/nsIFeedGenerator.idl => toolkit/components/feeds/nsIFeedGenerator.idl
rename : toolkit/components/feeds/public/nsIFeedListener.idl => toolkit/components/feeds/nsIFeedListener.idl
rename : toolkit/components/feeds/public/nsIFeedPerson.idl => toolkit/components/feeds/nsIFeedPerson.idl
rename : toolkit/components/feeds/public/nsIFeedProcessor.idl => toolkit/components/feeds/nsIFeedProcessor.idl
rename : toolkit/components/feeds/public/nsIFeedResult.idl => toolkit/components/feeds/nsIFeedResult.idl
rename : toolkit/components/feeds/public/nsIFeedTextConstruct.idl => toolkit/components/feeds/nsIFeedTextConstruct.idl
rename : toolkit/components/feeds/public/nsIScriptableUnescapeHTML.idl => toolkit/components/feeds/nsIScriptableUnescapeHTML.idl
rename : toolkit/components/feeds/src/nsScriptableUnescapeHTML.cpp => toolkit/components/feeds/nsScriptableUnescapeHTML.cpp
rename : toolkit/components/feeds/src/nsScriptableUnescapeHTML.h => toolkit/components/feeds/nsScriptableUnescapeHTML.h
rename : toolkit/components/filepicker/src/nsFilePicker.js => toolkit/components/filepicker/nsFilePicker.js
rename : toolkit/components/filepicker/src/nsFilePicker.manifest => toolkit/components/filepicker/nsFilePicker.manifest
rename : toolkit/components/filepicker/src/nsFileView.cpp => toolkit/components/filepicker/nsFileView.cpp
rename : toolkit/components/filepicker/public/nsIFileView.idl => toolkit/components/filepicker/nsIFileView.idl
rename : toolkit/components/find/src/nsFindService.cpp => toolkit/components/find/nsFindService.cpp
rename : toolkit/components/find/src/nsFindService.h => toolkit/components/find/nsFindService.h
rename : toolkit/components/find/public/nsIFindService.idl => toolkit/components/find/nsIFindService.idl
rename : toolkit/components/microformats/src/Microformats.js => toolkit/components/microformats/Microformats.js
rename : toolkit/components/parentalcontrols/public/nsIParentalControlsService.idl => toolkit/components/parentalcontrols/nsIParentalControlsService.idl
rename : toolkit/components/parentalcontrols/src/nsParentalControlsServiceWin.cpp => toolkit/components/parentalcontrols/nsParentalControlsServiceWin.cpp
rename : toolkit/components/parentalcontrols/src/nsParentalControlsServiceWin.h => toolkit/components/parentalcontrols/nsParentalControlsServiceWin.h
rename : toolkit/components/passwordmgr/src/crypto-SDR.js => toolkit/components/passwordmgr/crypto-SDR.js
rename : toolkit/components/passwordmgr/public/nsILoginInfo.idl => toolkit/components/passwordmgr/nsILoginInfo.idl
rename : toolkit/components/passwordmgr/public/nsILoginManager.idl => toolkit/components/passwordmgr/nsILoginManager.idl
rename : toolkit/components/passwordmgr/public/nsILoginManagerCrypto.idl => toolkit/components/passwordmgr/nsILoginManagerCrypto.idl
rename : toolkit/components/passwordmgr/public/nsILoginManagerIEMigrationHelper.idl => toolkit/components/passwordmgr/nsILoginManagerIEMigrationHelper.idl
rename : toolkit/components/passwordmgr/public/nsILoginManagerPrompter.idl => toolkit/components/passwordmgr/nsILoginManagerPrompter.idl
rename : toolkit/components/passwordmgr/public/nsILoginManagerStorage.idl => toolkit/components/passwordmgr/nsILoginManagerStorage.idl
rename : toolkit/components/passwordmgr/public/nsILoginMetaInfo.idl => toolkit/components/passwordmgr/nsILoginMetaInfo.idl
rename : toolkit/components/passwordmgr/src/nsLoginInfo.js => toolkit/components/passwordmgr/nsLoginInfo.js
rename : toolkit/components/passwordmgr/src/nsLoginManager.js => toolkit/components/passwordmgr/nsLoginManager.js
rename : toolkit/components/passwordmgr/src/nsLoginManagerPrompter.js => toolkit/components/passwordmgr/nsLoginManagerPrompter.js
rename : toolkit/components/passwordmgr/src/passwordmgr.manifest => toolkit/components/passwordmgr/passwordmgr.manifest
rename : toolkit/components/passwordmgr/src/storage-Legacy.js => toolkit/components/passwordmgr/storage-Legacy.js
rename : toolkit/components/passwordmgr/src/storage-mozStorage.js => toolkit/components/passwordmgr/storage-mozStorage.js
rename : toolkit/components/places/src/AsyncFaviconHelpers.cpp => toolkit/components/places/AsyncFaviconHelpers.cpp
rename : toolkit/components/places/src/AsyncFaviconHelpers.h => toolkit/components/places/AsyncFaviconHelpers.h
rename : toolkit/components/places/src/Helpers.cpp => toolkit/components/places/Helpers.cpp
rename : toolkit/components/places/src/Helpers.h => toolkit/components/places/Helpers.h
rename : toolkit/components/places/src/History.cpp => toolkit/components/places/History.cpp
rename : toolkit/components/places/src/History.h => toolkit/components/places/History.h
rename : toolkit/components/places/src/PlaceInfo.cpp => toolkit/components/places/PlaceInfo.cpp
rename : toolkit/components/places/src/PlaceInfo.h => toolkit/components/places/PlaceInfo.h
rename : toolkit/components/places/src/PlacesCategoriesStarter.js => toolkit/components/places/PlacesCategoriesStarter.js
rename : toolkit/components/places/src/PlacesDBUtils.jsm => toolkit/components/places/PlacesDBUtils.jsm
rename : toolkit/components/places/src/PlacesUtils.jsm => toolkit/components/places/PlacesUtils.jsm
rename : toolkit/components/places/src/SQLFunctions.cpp => toolkit/components/places/SQLFunctions.cpp
rename : toolkit/components/places/src/SQLFunctions.h => toolkit/components/places/SQLFunctions.h
rename : toolkit/components/places/src/VisitInfo.cpp => toolkit/components/places/VisitInfo.cpp
rename : toolkit/components/places/src/VisitInfo.h => toolkit/components/places/VisitInfo.h
rename : toolkit/components/places/public/mozIAsyncHistory.idl => toolkit/components/places/mozIAsyncHistory.idl
rename : toolkit/components/places/public/mozIPlacesAutoComplete.idl => toolkit/components/places/mozIPlacesAutoComplete.idl
rename : toolkit/components/places/src/nsAnnoProtocolHandler.cpp => toolkit/components/places/nsAnnoProtocolHandler.cpp
rename : toolkit/components/places/src/nsAnnoProtocolHandler.h => toolkit/components/places/nsAnnoProtocolHandler.h
rename : toolkit/components/places/src/nsAnnotationService.cpp => toolkit/components/places/nsAnnotationService.cpp
rename : toolkit/components/places/src/nsAnnotationService.h => toolkit/components/places/nsAnnotationService.h
rename : toolkit/components/places/src/nsFaviconService.cpp => toolkit/components/places/nsFaviconService.cpp
rename : toolkit/components/places/src/nsFaviconService.h => toolkit/components/places/nsFaviconService.h
rename : toolkit/components/places/public/nsIAnnotationService.idl => toolkit/components/places/nsIAnnotationService.idl
rename : toolkit/components/places/public/nsIBrowserHistory.idl => toolkit/components/places/nsIBrowserHistory.idl
rename : toolkit/components/places/public/nsIDynamicContainer.idl => toolkit/components/places/nsIDynamicContainer.idl
rename : toolkit/components/places/public/nsIFaviconService.idl => toolkit/components/places/nsIFaviconService.idl
rename : toolkit/components/places/public/nsILivemarkService.idl => toolkit/components/places/nsILivemarkService.idl
rename : toolkit/components/places/public/nsIMicrosummaryService.idl => toolkit/components/places/nsIMicrosummaryService.idl
rename : toolkit/components/places/public/nsINavBookmarksService.idl => toolkit/components/places/nsINavBookmarksService.idl
rename : toolkit/components/places/public/nsINavHistoryService.idl => toolkit/components/places/nsINavHistoryService.idl
rename : toolkit/components/places/public/nsIPlacesImportExportService.idl => toolkit/components/places/nsIPlacesImportExportService.idl
rename : toolkit/components/places/public/nsITaggingService.idl => toolkit/components/places/nsITaggingService.idl
rename : toolkit/components/places/src/nsLivemarkService.js => toolkit/components/places/nsLivemarkService.js
rename : toolkit/components/places/src/nsMaybeWeakPtr.cpp => toolkit/components/places/nsMaybeWeakPtr.cpp
rename : toolkit/components/places/src/nsMaybeWeakPtr.h => toolkit/components/places/nsMaybeWeakPtr.h
rename : toolkit/components/places/src/nsMicrosummaryService.js => toolkit/components/places/nsMicrosummaryService.js
rename : toolkit/components/places/src/nsMorkHistoryImporter.cpp => toolkit/components/places/nsMorkHistoryImporter.cpp
rename : toolkit/components/places/src/nsNavBookmarks.cpp => toolkit/components/places/nsNavBookmarks.cpp
rename : toolkit/components/places/src/nsNavBookmarks.h => toolkit/components/places/nsNavBookmarks.h
rename : toolkit/components/places/src/nsNavHistory.cpp => toolkit/components/places/nsNavHistory.cpp
rename : toolkit/components/places/src/nsNavHistory.h => toolkit/components/places/nsNavHistory.h
rename : toolkit/components/places/src/nsNavHistoryQuery.cpp => toolkit/components/places/nsNavHistoryQuery.cpp
rename : toolkit/components/places/src/nsNavHistoryQuery.h => toolkit/components/places/nsNavHistoryQuery.h
rename : toolkit/components/places/src/nsNavHistoryResult.cpp => toolkit/components/places/nsNavHistoryResult.cpp
rename : toolkit/components/places/src/nsNavHistoryResult.h => toolkit/components/places/nsNavHistoryResult.h
rename : toolkit/components/places/public/nsPIPlacesDatabase.idl => toolkit/components/places/nsPIPlacesDatabase.idl
rename : toolkit/components/places/public/nsPIPlacesHistoryListenersNotifier.idl => toolkit/components/places/nsPIPlacesHistoryListenersNotifier.idl
rename : toolkit/components/places/src/nsPlacesAutoComplete.js => toolkit/components/places/nsPlacesAutoComplete.js
rename : toolkit/components/places/src/nsPlacesAutoComplete.manifest => toolkit/components/places/nsPlacesAutoComplete.manifest
rename : toolkit/components/places/src/nsPlacesExpiration.js => toolkit/components/places/nsPlacesExpiration.js
rename : toolkit/components/places/src/nsPlacesImportExportService.cpp => toolkit/components/places/nsPlacesImportExportService.cpp
rename : toolkit/components/places/src/nsPlacesImportExportService.h => toolkit/components/places/nsPlacesImportExportService.h
rename : toolkit/components/places/src/nsPlacesIndexes.h => toolkit/components/places/nsPlacesIndexes.h
rename : toolkit/components/places/src/nsPlacesMacros.h => toolkit/components/places/nsPlacesMacros.h
rename : toolkit/components/places/src/nsPlacesModule.cpp => toolkit/components/places/nsPlacesModule.cpp
rename : toolkit/components/places/src/nsPlacesTables.h => toolkit/components/places/nsPlacesTables.h
rename : toolkit/components/places/src/nsPlacesTriggers.h => toolkit/components/places/nsPlacesTriggers.h
rename : toolkit/components/places/src/nsTaggingService.js => toolkit/components/places/nsTaggingService.js
rename : toolkit/components/places/src/toolkitplaces.manifest => toolkit/components/places/toolkitplaces.manifest
rename : toolkit/components/places/src/utils.js => toolkit/components/places/utils.js
rename : toolkit/components/satchel/src/formSubmitListener.js => toolkit/components/satchel/formSubmitListener.js
rename : toolkit/components/satchel/src/nsFormAutoComplete.js => toolkit/components/satchel/nsFormAutoComplete.js
rename : toolkit/components/satchel/src/nsFormAutoCompleteResult.jsm => toolkit/components/satchel/nsFormAutoCompleteResult.jsm
rename : toolkit/components/satchel/src/nsFormFillController.cpp => toolkit/components/satchel/nsFormFillController.cpp
rename : toolkit/components/satchel/src/nsFormFillController.h => toolkit/components/satchel/nsFormFillController.h
rename : toolkit/components/satchel/src/nsFormHistory.js => toolkit/components/satchel/nsFormHistory.js
rename : toolkit/components/satchel/public/nsIFormAutoComplete.idl => toolkit/components/satchel/nsIFormAutoComplete.idl
rename : toolkit/components/satchel/public/nsIFormFillController.idl => toolkit/components/satchel/nsIFormFillController.idl
rename : toolkit/components/satchel/public/nsIFormHistory.idl => toolkit/components/satchel/nsIFormHistory.idl
rename : toolkit/components/satchel/public/nsIInputListAutoComplete.idl => toolkit/components/satchel/nsIInputListAutoComplete.idl
rename : toolkit/components/satchel/src/nsInputListAutoComplete.js => toolkit/components/satchel/nsInputListAutoComplete.js
rename : toolkit/components/satchel/src/satchel.manifest => toolkit/components/satchel/satchel.manifest
rename : toolkit/components/startup/src/nsAppStartup.cpp => toolkit/components/startup/nsAppStartup.cpp
rename : toolkit/components/startup/src/nsAppStartup.h => toolkit/components/startup/nsAppStartup.h
rename : toolkit/components/startup/src/nsTryToClose.js => toolkit/components/startup/nsTryToClose.js
rename : toolkit/components/startup/src/nsTryToClose.manifest => toolkit/components/startup/nsTryToClose.manifest
rename : toolkit/components/startup/src/nsUserInfo.h => toolkit/components/startup/nsUserInfo.h
rename : toolkit/components/startup/src/nsUserInfoMac.h => toolkit/components/startup/nsUserInfoMac.h
rename : toolkit/components/startup/src/nsUserInfoMac.mm => toolkit/components/startup/nsUserInfoMac.mm
rename : toolkit/components/startup/src/nsUserInfoOS2.cpp => toolkit/components/startup/nsUserInfoOS2.cpp
rename : toolkit/components/startup/src/nsUserInfoUnix.cpp => toolkit/components/startup/nsUserInfoUnix.cpp
rename : toolkit/components/startup/src/nsUserInfoWin.cpp => toolkit/components/startup/nsUserInfoWin.cpp
rename : toolkit/components/typeaheadfind/public/nsITypeAheadFind.idl => toolkit/components/typeaheadfind/nsITypeAheadFind.idl
rename : toolkit/components/typeaheadfind/src/nsTypeAheadFind.cpp => toolkit/components/typeaheadfind/nsTypeAheadFind.cpp
rename : toolkit/components/typeaheadfind/src/nsTypeAheadFind.h => toolkit/components/typeaheadfind/nsTypeAheadFind.h
rename : toolkit/components/url-classifier/public/nsIUrlClassifierDBService.idl => toolkit/components/url-classifier/nsIUrlClassifierDBService.idl
rename : toolkit/components/url-classifier/public/nsIUrlClassifierHashCompleter.idl => toolkit/components/url-classifier/nsIUrlClassifierHashCompleter.idl
rename : toolkit/components/url-classifier/public/nsIUrlClassifierStreamUpdater.idl => toolkit/components/url-classifier/nsIUrlClassifierStreamUpdater.idl
rename : toolkit/components/url-classifier/public/nsIUrlClassifierTable.idl => toolkit/components/url-classifier/nsIUrlClassifierTable.idl
rename : toolkit/components/url-classifier/public/nsIUrlClassifierUtils.idl => toolkit/components/url-classifier/nsIUrlClassifierUtils.idl
rename : toolkit/components/url-classifier/public/nsIUrlListManager.idl => toolkit/components/url-classifier/nsIUrlListManager.idl
rename : toolkit/components/url-classifier/src/nsURLClassifier.manifest => toolkit/components/url-classifier/nsURLClassifier.manifest
rename : toolkit/components/url-classifier/src/nsUrlClassifierDBService.cpp => toolkit/components/url-classifier/nsUrlClassifierDBService.cpp
rename : toolkit/components/url-classifier/src/nsUrlClassifierDBService.h => toolkit/components/url-classifier/nsUrlClassifierDBService.h
rename : toolkit/components/url-classifier/src/nsUrlClassifierHashCompleter.cpp => toolkit/components/url-classifier/nsUrlClassifierHashCompleter.cpp
rename : toolkit/components/url-classifier/src/nsUrlClassifierHashCompleter.h => toolkit/components/url-classifier/nsUrlClassifierHashCompleter.h
rename : toolkit/components/url-classifier/src/nsUrlClassifierLib.js => toolkit/components/url-classifier/nsUrlClassifierLib.js
rename : toolkit/components/url-classifier/src/nsUrlClassifierListManager.js => toolkit/components/url-classifier/nsUrlClassifierListManager.js
rename : toolkit/components/url-classifier/src/nsUrlClassifierStreamUpdater.cpp => toolkit/components/url-classifier/nsUrlClassifierStreamUpdater.cpp
rename : toolkit/components/url-classifier/src/nsUrlClassifierStreamUpdater.h => toolkit/components/url-classifier/nsUrlClassifierStreamUpdater.h
rename : toolkit/components/url-classifier/src/nsUrlClassifierUtils.cpp => toolkit/components/url-classifier/nsUrlClassifierUtils.cpp
rename : toolkit/components/url-classifier/src/nsUrlClassifierUtils.h => toolkit/components/url-classifier/nsUrlClassifierUtils.h
rename : toolkit/components/urlformatter/public/nsIURLFormatter.idl => toolkit/components/urlformatter/nsIURLFormatter.idl
rename : toolkit/components/urlformatter/src/nsURLFormatter.js => toolkit/components/urlformatter/nsURLFormatter.js
rename : toolkit/components/urlformatter/src/nsURLFormatter.manifest => toolkit/components/urlformatter/nsURLFormatter.manifest
rename : toolkit/profile/public/nsIProfileMigrator.idl => toolkit/profile/nsIProfileMigrator.idl
rename : toolkit/profile/public/nsIToolkitProfile.idl => toolkit/profile/nsIToolkitProfile.idl
rename : toolkit/profile/public/nsIToolkitProfileService.idl => toolkit/profile/nsIToolkitProfileService.idl
rename : toolkit/profile/src/nsToolkitProfileService.cpp => toolkit/profile/nsToolkitProfileService.cpp
2011-03-08 14:58:46 +11:00

1186 lines
41 KiB
JavaScript

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: sw=2 ts=2 sts=2 expandtab
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* the Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2008
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Shawn Wilsher <me@shawnwilsher.com> (Original Author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
////////////////////////////////////////////////////////////////////////////////
//// Constants
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cr = Components.results;
// This is just a helper for the next constant.
function book_tag_sql_fragment(aName, aColumn, aForTag)
{
return ["(",
"SELECT ", aColumn, " ",
"FROM moz_bookmarks b ",
"JOIN moz_bookmarks t ",
"ON t.id = b.parent ",
"AND t.parent ", (aForTag ? "" : "!"), "= :parent ",
"WHERE b.fk = h.id ",
(aForTag ? "" : "ORDER BY b.lastModified DESC LIMIT 1"),
") AS ", aName].join("");
}
// This SQL query fragment provides the following:
// - the parent folder for bookmarked entries (kQueryIndexParent)
// - the bookmark title, if it is a bookmark (kQueryIndexBookmarkTitle)
// - the tags associated with a bookmarked entry (kQueryIndexTags)
const kBookTagSQLFragment =
book_tag_sql_fragment("parent", "b.parent", false) + ", " +
book_tag_sql_fragment("bookmark", "b.title", false) + ", " +
book_tag_sql_fragment("tags", "GROUP_CONCAT(t.title, ',')", true);
// observer topics
const kTopicShutdown = "places-shutdown";
const kPrefChanged = "nsPref:changed";
// Match type constants. These indicate what type of search function we should
// be using.
const MATCH_ANYWHERE = Ci.mozIPlacesAutoComplete.MATCH_ANYWHERE;
const MATCH_BOUNDARY_ANYWHERE = Ci.mozIPlacesAutoComplete.MATCH_BOUNDARY_ANYWHERE;
const MATCH_BOUNDARY = Ci.mozIPlacesAutoComplete.MATCH_BOUNDARY;
const MATCH_BEGINNING = Ci.mozIPlacesAutoComplete.MATCH_BEGINNING;
// AutoComplete index constants. All AutoComplete queries will provide these
// columns in this order.
const kQueryIndexURL = 0;
const kQueryIndexTitle = 1;
const kQueryIndexFaviconURL = 2;
const kQueryIndexParentId = 3;
const kQueryIndexBookmarkTitle = 4;
const kQueryIndexTags = 5;
const kQueryIndexVisitCount = 6;
const kQueryIndexTyped = 7;
const kQueryIndexPlaceId = 8;
const kQueryIndexQueryType = 9;
const kQueryIndexOpenPageCount = 10;
// AutoComplete query type constants. Describes the various types of queries
// that we can process.
const kQueryTypeKeyword = 0;
const kQueryTypeFiltered = 1;
// This separator is used as an RTL-friendly way to split the title and tags.
// It can also be used by an nsIAutoCompleteResult consumer to re-split the
// "comment" back into the title and the tag.
const kTitleTagsSeparator = " \u2013 ";
const kBrowserUrlbarBranch = "browser.urlbar.";
////////////////////////////////////////////////////////////////////////////////
//// Helpers
/**
* Initializes our temporary table on a given database.
*
* @param aDatabase
* The mozIStorageConnection to set up the temp table on.
*/
function initTempTable(aDatabase)
{
// Keep our temporary table in memory.
aDatabase.executeSimpleSQL("PRAGMA temp_store = MEMORY");
// Note: this should be kept up-to-date with the definition in
// nsPlacesTables.h.
let stmt = aDatabase.createAsyncStatement(
"CREATE TEMP TABLE moz_openpages_temp ( "
+ " url TEXT PRIMARY KEY "
+ ", open_count INTEGER "
+ ") "
);
stmt.executeAsync();
stmt.finalize();
// Note: this should be kept up-to-date with the definition in
// nsPlacesTriggers.h.
stmt = aDatabase.createAsyncStatement(
"CREATE TEMPORARY TRIGGER moz_openpages_temp_afterupdate_trigger "
+ "AFTER UPDATE OF open_count ON moz_openpages_temp FOR EACH ROW "
+ "WHEN NEW.open_count = 0 "
+ "BEGIN "
+ "DELETE FROM moz_openpages_temp "
+ "WHERE url = NEW.url; "
+ "END "
);
stmt.executeAsync();
stmt.finalize();
}
////////////////////////////////////////////////////////////////////////////////
//// AutoCompleteStatementCallbackWrapper class
/**
* Wraps a callback and ensures that handleCompletion is not dispatched if the
* query is no longer tracked.
*
* @param aCallback
* A reference to a nsPlacesAutoComplete.
* @param aDBConnection
* The database connection to execute the queries on.
*/
function AutoCompleteStatementCallbackWrapper(aCallback,
aDBConnection)
{
this._callback = aCallback;
this._db = aDBConnection;
}
AutoCompleteStatementCallbackWrapper.prototype = {
//////////////////////////////////////////////////////////////////////////////
//// mozIStorageStatementCallback
handleResult: function ACSCW_handleResult(aResultSet)
{
this._callback.handleResult.apply(this._callback, arguments);
},
handleError: function ACSCW_handleError(aError)
{
this._callback.handleError.apply(this._callback, arguments);
},
handleCompletion: function ACSCW_handleCompletion(aReason)
{
// Only dispatch handleCompletion if we are not done searching and are a
// pending search.
let callback = this._callback;
if (!callback.isSearchComplete() && callback.isPendingSearch(this._handle))
callback.handleCompletion.apply(callback, arguments);
},
//////////////////////////////////////////////////////////////////////////////
//// AutoCompleteStatementCallbackWrapper
/**
* Executes the specified query asynchronously. This object will notify
* this._callback if we should notify (logic explained in handleCompletion).
*
* @param aQueries
* The queries to execute asynchronously.
* @return a mozIStoragePendingStatement that can be used to cancel the
* queries.
*/
executeAsync: function ACSCW_executeAsync(aQueries)
{
return this._handle = this._db.executeAsync(aQueries, aQueries.length,
this);
},
//////////////////////////////////////////////////////////////////////////////
//// nsISupports
QueryInterface: XPCOMUtils.generateQI([
Ci.mozIStorageStatementCallback,
])
};
////////////////////////////////////////////////////////////////////////////////
//// nsPlacesAutoComplete class
function nsPlacesAutoComplete()
{
//////////////////////////////////////////////////////////////////////////////
//// Shared Constants for Smart Getters
// TODO bug 412736 in case of a frecency tie, break it with h.typed and
// h.visit_count which is better than nothing. This is slow, so not doing it
// yet...
const SQL_BASE = "SELECT h.url, h.title, f.url, " + kBookTagSQLFragment + ", "
+ "h.visit_count, h.typed, h.id, :query_type, "
+ "t.open_count "
+ "FROM moz_places h "
+ "LEFT JOIN moz_favicons f ON f.id = h.favicon_id "
+ "LEFT JOIN moz_openpages_temp t ON t.url = h.url "
+ "WHERE h.frecency <> 0 "
+ "AND AUTOCOMPLETE_MATCH(:searchString, h.url, "
+ "IFNULL(bookmark, h.title), tags, "
+ "h.visit_count, h.typed, parent, "
+ "t.open_count, "
+ ":matchBehavior, :searchBehavior) "
+ "{ADDITIONAL_CONDITIONS} "
+ "ORDER BY h.frecency DESC, h.id DESC "
+ "LIMIT :maxResults";
//////////////////////////////////////////////////////////////////////////////
//// Smart Getters
XPCOMUtils.defineLazyGetter(this, "_db", function() {
// Get a cloned, read-only version of the database. We'll only ever write
// to our own in-memory temp table, and having a cloned copy means we do not
// run the risk of our queries taking longer due to the main database
// connection performing a long-running task.
let db = Cc["@mozilla.org/browser/nav-history-service;1"].
getService(Ci.nsPIPlacesDatabase).
DBConnection.
clone(true);
// Create our in-memory tables for tab tracking.
initTempTable(db);
return db;
});
XPCOMUtils.defineLazyServiceGetter(this, "_bh",
"@mozilla.org/browser/global-history;2",
"nsIBrowserHistory");
XPCOMUtils.defineLazyServiceGetter(this, "_textURIService",
"@mozilla.org/intl/texttosuburi;1",
"nsITextToSubURI");
XPCOMUtils.defineLazyServiceGetter(this, "_bs",
"@mozilla.org/browser/nav-bookmarks-service;1",
"nsINavBookmarksService");
XPCOMUtils.defineLazyServiceGetter(this, "_ioService",
"@mozilla.org/network/io-service;1",
"nsIIOService");
XPCOMUtils.defineLazyServiceGetter(this, "_faviconService",
"@mozilla.org/browser/favicon-service;1",
"nsIFaviconService");
XPCOMUtils.defineLazyGetter(this, "_defaultQuery", function() {
let replacementText = "";
return this._db.createAsyncStatement(
SQL_BASE.replace("{ADDITIONAL_CONDITIONS}", replacementText, "g")
);
});
XPCOMUtils.defineLazyGetter(this, "_historyQuery", function() {
let replacementText = "AND h.visit_count > 0";
return this._db.createAsyncStatement(
SQL_BASE.replace("{ADDITIONAL_CONDITIONS}", replacementText, "g")
);
});
XPCOMUtils.defineLazyGetter(this, "_bookmarkQuery", function() {
let replacementText = "AND bookmark IS NOT NULL";
return this._db.createAsyncStatement(
SQL_BASE.replace("{ADDITIONAL_CONDITIONS}", replacementText, "g")
);
});
XPCOMUtils.defineLazyGetter(this, "_tagsQuery", function() {
let replacementText = "AND tags IS NOT NULL";
return this._db.createAsyncStatement(
SQL_BASE.replace("{ADDITIONAL_CONDITIONS}", replacementText, "g")
);
});
XPCOMUtils.defineLazyGetter(this, "_openPagesQuery", function() {
return this._db.createAsyncStatement(
"SELECT t.url, t.url, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "
+ ":query_type, t.open_count, NULL "
+ "FROM moz_openpages_temp t "
+ "LEFT JOIN moz_places h ON h.url = t.url "
+ "WHERE h.id IS NULL "
+ "AND AUTOCOMPLETE_MATCH(:searchString, t.url, t.url, NULL, "
+ "NULL, NULL, NULL, t.open_count, "
+ ":matchBehavior, :searchBehavior) "
+ "ORDER BY t.ROWID DESC "
+ "LIMIT :maxResults "
);
});
XPCOMUtils.defineLazyGetter(this, "_typedQuery", function() {
let replacementText = "AND h.typed = 1";
return this._db.createAsyncStatement(
SQL_BASE.replace("{ADDITIONAL_CONDITIONS}", replacementText, "g")
);
});
XPCOMUtils.defineLazyGetter(this, "_adaptiveQuery", function() {
// In this query, we are taking kBookTagSQLFragment only for h.id because it
// uses data from the moz_bookmarks table and we sync tables on bookmark
// insert. So, most likely, h.id will always be populated when we have any
// bookmark.
return this._db.createAsyncStatement(
"/* do not warn (bug 487789) */ "
+ "SELECT h.url, h.title, f.url, " + kBookTagSQLFragment + ", "
+ "h.visit_count, h.typed, h.id, :query_type, t.open_count, rank "
+ "FROM ( "
+ "SELECT ROUND( "
+ "MAX(((i.input = :search_string) + "
+ "(SUBSTR(i.input, 1, LENGTH(:search_string)) = :search_string) "
+ ") * i.use_count "
+ ") , 1 " // Round at first decimal.
+ ") AS rank, place_id "
+ "FROM moz_inputhistory i "
+ "GROUP BY i.place_id "
+ "HAVING rank > 0 "
+ ") AS i "
+ "JOIN moz_places h ON h.id = i.place_id "
+ "LEFT JOIN moz_favicons f ON f.id = h.favicon_id "
+ "LEFT JOIN moz_openpages_temp t ON t.url = h.url "
+ "WHERE AUTOCOMPLETE_MATCH(NULL, h.url, "
+ "IFNULL(bookmark, h.title), tags, "
+ "h.visit_count, h.typed, parent, "
+ "t.open_count, "
+ ":matchBehavior, :searchBehavior) "
+ "ORDER BY rank DESC, h.frecency DESC "
);
});
XPCOMUtils.defineLazyGetter(this, "_keywordQuery", function() {
return this._db.createAsyncStatement(
"/* do not warn (bug 487787) */ "
+ "SELECT "
+ "(SELECT REPLACE(url, '%s', :query_string) FROM moz_places WHERE id = b.fk) "
+ "AS search_url, h.title, "
+ "IFNULL(f.url, (SELECT f.url "
+ "FROM moz_places "
+ "JOIN moz_favicons f ON f.id = favicon_id "
+ "WHERE rev_host = (SELECT rev_host FROM moz_places WHERE id = b.fk) "
+ "ORDER BY frecency DESC "
+ "LIMIT 1) "
+ "), b.parent, b.title, NULL, h.visit_count, h.typed, IFNULL(h.id, b.fk), "
+ ":query_type, t.open_count "
+ "FROM moz_keywords k "
+ "JOIN moz_bookmarks b ON b.keyword_id = k.id "
+ "LEFT JOIN moz_places h ON h.url = search_url "
+ "LEFT JOIN moz_favicons f ON f.id = h.favicon_id "
+ "LEFT JOIN moz_openpages_temp t ON t.url = search_url "
+ "WHERE LOWER(k.keyword) = LOWER(:keyword) "
+ "ORDER BY h.frecency DESC "
);
});
XPCOMUtils.defineLazyGetter(this, "_registerOpenPageQuery", function() {
return this._db.createAsyncStatement(
"INSERT OR REPLACE INTO moz_openpages_temp (url, open_count) "
+ "VALUES (:page_url, "
+ "IFNULL("
+ "("
+ "SELECT open_count + 1 "
+ "FROM moz_openpages_temp "
+ "WHERE url = :page_url "
+ "), "
+ "1"
+ ")"
+ ")"
);
});
XPCOMUtils.defineLazyGetter(this, "_unregisterOpenPageQuery", function() {
return this._db.createAsyncStatement(
"UPDATE moz_openpages_temp "
+ "SET open_count = open_count - 1 "
+ "WHERE url = :page_url"
);
});
//////////////////////////////////////////////////////////////////////////////
//// Initialization
// load preferences
this._prefs = Cc["@mozilla.org/preferences-service;1"].
getService(Ci.nsIPrefService).
getBranch(kBrowserUrlbarBranch);
this._loadPrefs(true);
// register observers
this._os = Cc["@mozilla.org/observer-service;1"].
getService(Ci.nsIObserverService);
this._os.addObserver(this, kTopicShutdown, false);
}
nsPlacesAutoComplete.prototype = {
//////////////////////////////////////////////////////////////////////////////
//// nsIAutoCompleteSearch
startSearch: function PAC_startSearch(aSearchString, aSearchParam,
aPreviousResult, aListener)
{
// If a previous query is running and the controller has not taken care
// of stopping it, kill it.
if ("_pendingQuery" in this)
this.stopSearch();
// Note: We don't use aPreviousResult to make sure ordering of results are
// consistent. See bug 412730 for more details.
// We want to store the original string with no leading or trailing
// whitespace for case sensitive searches.
this._originalSearchString = aSearchString.trim();
this._currentSearchString =
this._fixupSearchText(this._originalSearchString.toLowerCase());
var searchParamParts = aSearchParam.split(" ");
this._enableActions = searchParamParts.indexOf("enable-actions") != -1;
this._listener = aListener;
let result = Cc["@mozilla.org/autocomplete/simple-result;1"].
createInstance(Ci.nsIAutoCompleteSimpleResult);
result.setSearchString(aSearchString);
result.setListener(this);
this._result = result;
// If we are not enabled, we need to return now.
if (!this._enabled) {
this._finishSearch(true);
return;
}
// Reset our search behavior to the default.
if (this._currentSearchString)
this._behavior = this._defaultBehavior;
else
this._behavior = this._emptySearchDefaultBehavior;
// For any given search, we run up to four queries:
// 1) keywords (this._keywordQuery)
// 2) adaptive learning (this._adaptiveQuery)
// 3) open pages not supported by history (this._openPagesQuery)
// 4) query from this._getSearch
// (1) only gets ran if we get any filtered tokens from this._getSearch,
// since if there are no tokens, there is nothing to match, so there is no
// reason to run the query).
let {query, tokens} =
this._getSearch(this._getUnfilteredSearchTokens(this._currentSearchString));
let queries = tokens.length ?
[this._getBoundKeywordQuery(tokens), this._getBoundAdaptiveQuery(), this._getBoundOpenPagesQuery(tokens), query] :
[this._getBoundAdaptiveQuery(), this._getBoundOpenPagesQuery(tokens), query];
// Start executing our queries.
this._executeQueries(queries);
// Set up our persistent state for the duration of the search.
this._searchTokens = tokens;
this._usedPlaces = {};
},
stopSearch: function PAC_stopSearch()
{
// We need to cancel our searches so we do not get any [more] results.
// However, it's possible we haven't actually started any searches, so this
// method may throw because this._pendingQuery may be undefined.
if (this._pendingQuery)
this._stopActiveQuery();
this._finishSearch(false);
},
//////////////////////////////////////////////////////////////////////////////
//// nsIAutoCompleteSimpleResultListener
onValueRemoved: function PAC_onValueRemoved(aResult, aURISpec, aRemoveFromDB)
{
if (aRemoveFromDB)
this._bh.removePage(this._ioService.newURI(aURISpec, null, null));
},
//////////////////////////////////////////////////////////////////////////////
//// mozIPlacesAutoComplete
registerOpenPage: function PAC_registerOpenPage(aURI)
{
let stmt = this._registerOpenPageQuery;
stmt.params.page_url = aURI.spec;
stmt.executeAsync();
},
unregisterOpenPage: function PAC_unregisterOpenPage(aURI)
{
let stmt = this._unregisterOpenPageQuery;
stmt.params.page_url = aURI.spec;
stmt.executeAsync();
},
//////////////////////////////////////////////////////////////////////////////
//// mozIStorageStatementCallback
handleResult: function PAC_handleResult(aResultSet)
{
let row, haveMatches = false;
while (row = aResultSet.getNextRow()) {
let match = this._processRow(row);
haveMatches = haveMatches || match;
if (this._result.matchCount == this._maxRichResults) {
// We have enough results, so stop running our search.
this._stopActiveQuery();
// And finish our search.
this._finishSearch(true);
return;
}
}
// Notify about results if we've gotten them.
if (haveMatches)
this._notifyResults(true);
},
handleError: function PAC_handleError(aError)
{
Components.utils.reportError("Places AutoComplete: An async statement encountered an " +
"error: " + aError.result + ", '" + aError.message + "'");
},
handleCompletion: function PAC_handleCompletion(aReason)
{
// If we have already finished our search, we should bail out early.
if (this.isSearchComplete())
return;
// If we do not have enough results, and our match type is
// MATCH_BOUNDARY_ANYWHERE, search again with MATCH_ANYWHERE to get more
// results.
if (this._matchBehavior == MATCH_BOUNDARY_ANYWHERE &&
this._result.matchCount < this._maxRichResults && !this._secondPass) {
this._secondPass = true;
let queries = [
this._getBoundAdaptiveQuery(MATCH_ANYWHERE),
this._getBoundSearchQuery(MATCH_ANYWHERE, this._searchTokens),
];
this._executeQueries(queries);
return;
}
this._finishSearch(true);
},
//////////////////////////////////////////////////////////////////////////////
//// nsIObserver
observe: function PAC_observe(aSubject, aTopic, aData)
{
if (aTopic == kTopicShutdown) {
this._os.removeObserver(this, kTopicShutdown);
// Remove our preference observer.
this._prefs.QueryInterface(Ci.nsIPrefBranch2).removeObserver("", this);
delete this._prefs;
// Finalize the statements that we have used.
let stmts = [
"_defaultQuery",
"_historyQuery",
"_bookmarkQuery",
"_tagsQuery",
"_openPagesQuery",
"_typedQuery",
"_adaptiveQuery",
"_keywordQuery",
"_registerOpenPageQuery",
"_unregisterOpenPageQuery",
];
for (let i = 0; i < stmts.length; i++) {
// We do not want to create any query we haven't already created, so
// see if it is a getter first.
if (Object.getOwnPropertyDescriptor(this, stmts[i]).value !== undefined) {
this[stmts[i]].finalize();
}
}
if (Object.getOwnPropertyDescriptor(this, "_db").value !== undefined) {
this._db.asyncClose();
}
}
else if (aTopic == kPrefChanged) {
this._loadPrefs();
}
},
//////////////////////////////////////////////////////////////////////////////
//// nsPlacesAutoComplete
/**
* Used to unescape encoded URI strings, and drop information that we do not
* care about for searching.
*
* @param aURIString
* The text to unescape and modify.
* @return the modified uri.
*/
_fixupSearchText: function PAC_fixupSearchText(aURIString)
{
let uri = aURIString;
if (uri.indexOf("http://") == 0)
uri = uri.slice(7);
else if (uri.indexOf("https://") == 0)
uri = uri.slice(8);
else if (uri.indexOf("ftp://") == 0)
uri = uri.slice(6);
if (uri.indexOf("www.") == 0)
uri = uri.slice(4);
return this._textURIService.unEscapeURIForUI("UTF-8", uri);
},
/**
* Generates the tokens used in searching from a given string.
*
* @param aSearchString
* The string to generate tokens from.
* @return an array of tokens.
*/
_getUnfilteredSearchTokens: function PAC_unfilteredSearchTokens(aSearchString)
{
// Calling split on an empty string will return an array containing one
// empty string. We don't want that, as it'll break our logic, so return an
// empty array then.
return aSearchString.length ? aSearchString.split(" ") : [];
},
/**
* Properly cleans up when searching is completed.
*
* @param aNotify
* Indicates if we should notify the AutoComplete listener about our
* results or not.
*/
_finishSearch: function PAC_finishSearch(aNotify)
{
// Notify about results if we are supposed to.
if (aNotify)
this._notifyResults(false);
// Clear our state
delete this._originalSearchString;
delete this._currentSearchString;
delete this._searchTokens;
delete this._listener;
delete this._result;
delete this._usedPlaces;
delete this._pendingQuery;
this._secondPass = false;
this._enableActions = false;
},
/**
* Executes the given queries asynchronously.
*
* @param aQueries
* The queries to execute.
*/
_executeQueries: function PAC_executeQueries(aQueries)
{
// Because we might get a handleCompletion for canceled queries, we want to
// filter out queries we no longer care about (described in the
// handleCompletion implementation of AutoCompleteStatementCallbackWrapper).
// Create our wrapper object and execute the queries.
let wrapper = new AutoCompleteStatementCallbackWrapper(this, this._db);
this._pendingQuery = wrapper.executeAsync(aQueries);
},
/**
* Stops executing our active query.
*/
_stopActiveQuery: function PAC_stopActiveQuery()
{
this._pendingQuery.cancel();
delete this._pendingQuery;
},
/**
* Notifies the listener about results.
*
* @param aSearchOngoing
* Indicates if the search is ongoing or not.
*/
_notifyResults: function PAC_notifyResults(aSearchOngoing)
{
let result = this._result;
let resultCode = result.matchCount ? "RESULT_SUCCESS" : "RESULT_NOMATCH";
if (aSearchOngoing)
resultCode += "_ONGOING";
result.setSearchResult(Ci.nsIAutoCompleteResult[resultCode]);
result.setDefaultIndex(result.matchCount ? 0 : -1);
this._listener.onSearchResult(this, result);
},
/**
* Loads the preferences that we care about.
*
* @param [optional] aRegisterObserver
* Indicates if the preference observer should be added or not. The
* default value is false.
*/
_loadPrefs: function PAC_loadPrefs(aRegisterObserver)
{
let self = this;
function safeGetter(aName, aDefault) {
let types = {
boolean: "Bool",
number: "Int",
string: "Char"
};
let type = types[typeof(aDefault)];
if (!type)
throw "Unknown type!";
// If the pref isn't set, we want to use the default.
try {
return self._prefs["get" + type + "Pref"](aName);
}
catch (e) {
return aDefault;
}
}
this._enabled = safeGetter("autocomplete.enabled", true);
this._matchBehavior = safeGetter("matchBehavior", MATCH_BOUNDARY_ANYWHERE);
this._filterJavaScript = safeGetter("filter.javascript", true);
this._maxRichResults = safeGetter("maxRichResults", 25);
this._restrictHistoryToken = safeGetter("restrict.history", "^");
this._restrictBookmarkToken = safeGetter("restrict.bookmark", "*");
this._restrictTypedToken = safeGetter("restrict.typed", "~");
this._restrictTagToken = safeGetter("restrict.tag", "+");
this._restrictOpenPageToken = safeGetter("restrict.openpage", "%");
this._matchTitleToken = safeGetter("match.title", "#");
this._matchURLToken = safeGetter("match.url", "@");
this._defaultBehavior = safeGetter("default.behavior", 0);
// Further restrictions to apply for "empty searches" (i.e. searches for "").
this._emptySearchDefaultBehavior =
this._defaultBehavior |
safeGetter("default.behavior.emptyRestriction",
Ci.mozIPlacesAutoComplete.BEHAVIOR_HISTORY |
Ci.mozIPlacesAutoComplete.BEHAVIOR_TYPED);
// Validate matchBehavior; default to MATCH_BOUNDARY_ANYWHERE.
if (this._matchBehavior != MATCH_ANYWHERE &&
this._matchBehavior != MATCH_BOUNDARY &&
this._matchBehavior != MATCH_BEGINNING)
this._matchBehavior = MATCH_BOUNDARY_ANYWHERE;
// register observer
if (aRegisterObserver) {
let pb = this._prefs.QueryInterface(Ci.nsIPrefBranch2);
pb.addObserver("", this, false);
}
},
/**
* Given an array of tokens, this function determines which query should be
* ran. It also removes any special search tokens.
*
* @param aTokens
* An array of search tokens.
* @return an object with two properties:
* query: the correctly optimized, bound query to search the database
* with.
* tokens: the filtered list of tokens to search with.
*/
_getSearch: function PAC_getSearch(aTokens)
{
// Set the proper behavior so our call to _getBoundSearchQuery gives us the
// correct query.
for (let i = aTokens.length - 1; i >= 0; i--) {
switch (aTokens[i]) {
case this._restrictHistoryToken:
this._setBehavior("history");
break;
case this._restrictBookmarkToken:
this._setBehavior("bookmark");
break;
case this._restrictTagToken:
this._setBehavior("tag");
break;
case this._restrictOpenPageToken:
if (!this._enableActions)
continue;
this._setBehavior("openpage");
break;
case this._matchTitleToken:
this._setBehavior("title");
break;
case this._matchURLToken:
this._setBehavior("url");
break;
case this._restrictTypedToken:
this._setBehavior("typed");
break;
default:
// We do not want to remove the token if we did not match.
continue;
};
aTokens.splice(i, 1);
}
// Set the right JavaScript behavior based on our preference. Note that the
// preference is whether or not we should filter JavaScript, and the
// behavior is if we should search it or not.
if (!this._filterJavaScript)
this._setBehavior("javascript");
return {
query: this._getBoundSearchQuery(this._matchBehavior, aTokens),
tokens: aTokens
};
},
/**
* Obtains the search query to be used based on the previously set search
* behaviors (accessed by this._hasBehavior). The query is bound and ready to
* execute.
*
* @param aMatchBehavior
* How this query should match its tokens to the search string.
* @param aTokens
* An array of search tokens.
* @return the correctly optimized query to search the database with and the
* new list of tokens to search with. The query has all the needed
* parameters bound, so consumers can execute it without doing any
* additional work.
*/
_getBoundSearchQuery: function PAC_getBoundSearchQuery(aMatchBehavior,
aTokens)
{
// We use more optimized queries for restricted searches, so we will always
// return the most restrictive one to the least restrictive one if more than
// one token is found.
// Note: "openpages" behavior is supported by the default query.
// _openPagesQuery instead returns only pages not supported by
// history and it is always executed.
let query = this._hasBehavior("tag") ? this._tagsQuery :
this._hasBehavior("bookmark") ? this._bookmarkQuery :
this._hasBehavior("typed") ? this._typedQuery :
this._hasBehavior("history") ? this._historyQuery :
this._defaultQuery;
// Bind the needed parameters to the query so consumers can use it.
let (params = query.params) {
params.parent = this._bs.tagsFolder;
params.query_type = kQueryTypeFiltered;
params.matchBehavior = aMatchBehavior;
params.searchBehavior = this._behavior;
// We only want to search the tokens that we are left with - not the
// original search string.
params.searchString = aTokens.join(" ");
// Limit the query to the the maximum number of desired results.
// This way we can avoid doing more work than needed.
params.maxResults = this._maxRichResults;
}
return query;
},
_getBoundOpenPagesQuery: function PAC_getBoundOpenPagesQuery(aTokens)
{
let query = this._openPagesQuery;
// Bind the needed parameters to the query so consumers can use it.
let (params = query.params) {
params.query_type = kQueryTypeFiltered;
params.matchBehavior = this._matchBehavior;
params.searchBehavior = this._behavior;
// We only want to search the tokens that we are left with - not the
// original search string.
params.searchString = aTokens.join(" ");
params.maxResults = this._maxRichResults;
}
return query;
},
/**
* Obtains the keyword query with the properly bound parameters.
*
* @param aTokens
* The array of search tokens to check against.
* @return the bound keyword query.
*/
_getBoundKeywordQuery: function PAC_getBoundKeywordQuery(aTokens)
{
// The keyword is the first word in the search string, with the parameters
// following it.
let searchString = this._originalSearchString;
let queryString = "";
let queryIndex = searchString.indexOf(" ");
if (queryIndex != -1)
queryString = searchString.substring(queryIndex + 1);
// We need to escape the parameters as if they were the query in a URL
queryString = encodeURIComponent(queryString).replace("%20", "+", "g");
// The first word could be a keyword, so that's what we'll search.
let keyword = aTokens[0];
let query = this._keywordQuery;
let (params = query.params) {
params.keyword = keyword;
params.query_string = queryString;
params.query_type = kQueryTypeKeyword;
}
return query;
},
/**
* Obtains the adaptive query with the properly bound parameters.
*
* @return the bound adaptive query.
*/
_getBoundAdaptiveQuery: function PAC_getBoundAdaptiveQuery(aMatchBehavior)
{
// If we were not given a match behavior, use the stored match behavior.
if (arguments.length == 0)
aMatchBehavior = this._matchBehavior;
let query = this._adaptiveQuery;
let (params = query.params) {
params.parent = this._bs.tagsFolder;
params.search_string = this._currentSearchString;
params.query_type = kQueryTypeFiltered;
params.matchBehavior = aMatchBehavior;
params.searchBehavior = this._behavior;
}
return query;
},
/**
* Processes a mozIStorageRow to generate the proper data for the AutoComplete
* result. This will add an entry to the current result if it matches the
* criteria.
*
* @param aRow
* The row to process.
* @return true if the row is accepted, and false if not.
*/
_processRow: function PAC_processRow(aRow)
{
// Before we do any work, make sure this entry isn't already in our results.
let entryId = aRow.getResultByIndex(kQueryIndexPlaceId);
let escapedEntryURL = aRow.getResultByIndex(kQueryIndexURL);
let openPageCount = aRow.getResultByIndex(kQueryIndexOpenPageCount) || 0;
// If actions are enabled and the page is open, add only the switch-to-tab
// result. Otherwise, add the normal result.
let [url, action] = this._enableActions && openPageCount > 0 ?
["moz-action:switchtab," + escapedEntryURL, "action "] :
[escapedEntryURL, ""];
if (this._inResults(entryId || url)) {
return false;
}
let entryTitle = aRow.getResultByIndex(kQueryIndexTitle) || "";
let entryFavicon = aRow.getResultByIndex(kQueryIndexFaviconURL) || "";
let entryParentId = aRow.getResultByIndex(kQueryIndexParentId);
let entryBookmarkTitle = entryParentId ?
aRow.getResultByIndex(kQueryIndexBookmarkTitle) : null;
let entryTags = aRow.getResultByIndex(kQueryIndexTags) || "";
// Always prefer the bookmark title unless it is empty
let title = entryBookmarkTitle || entryTitle;
let style;
if (aRow.getResultByIndex(kQueryIndexQueryType) == kQueryTypeKeyword) {
// If we do not have a title, then we must have a keyword, so let the UI
// know it is a keyword. Otherwise, we found an exact page match, so just
// show the page like a regular result. Because the page title is likely
// going to be more specific than the bookmark title (keyword title).
if (!entryTitle)
style = "keyword";
else
title = entryTitle;
}
// We will always prefer to show tags if we have them.
let showTags = !!entryTags;
// However, we'll act as if a page is not bookmarked or tagged if the user
// only wants only history and not bookmarks or tags.
if (this._hasBehavior("history") &&
!(this._hasBehavior("bookmark") || this._hasBehavior("tag"))) {
showTags = false;
style = "favicon";
}
// If we have tags and should show them, we need to add them to the title.
if (showTags)
title += kTitleTagsSeparator + entryTags;
// We have to determine the right style to display. Tags show the tag icon,
// bookmarks get the bookmark icon, and keywords get the keyword icon. If
// the result does not fall into any of those, it just gets the favicon.
if (!style) {
// It is possible that we already have a style set (from a keyword
// search or because of the user's preferences), so only set it if we
// haven't already done so.
if (showTags)
style = "tag";
else if (entryParentId)
style = "bookmark";
else
style = "favicon";
}
this._addToResults(entryId, url, title, entryFavicon, action + style);
return true;
},
/**
* Checks to see if the given place has already been added to the results.
*
* @param aPlaceIdOrUrl
* The place id or url (if the entry does not have a id) to check for.
* @return true if the place has been added, false otherwise.
*/
_inResults: function PAC_inResults(aPlaceIdOrUrl)
{
return aPlaceIdOrUrl in this._usedPlaces;
},
/**
* Adds a result to the AutoComplete results. Also tracks that we've added
* this place_id into the result set.
*
* @param aPlaceId
* The place_id of the item to be added to the result set. This is
* used by _inResults.
* @param aURISpec
* The URI spec for the entry.
* @param aTitle
* The title to give the entry.
* @param aFaviconSpec
* The favicon to give to the entry.
* @param aStyle
* Indicates how the entry should be styled when displayed.
*/
_addToResults: function PAC_addToResults(aPlaceId, aURISpec, aTitle,
aFaviconSpec, aStyle)
{
// Add this to our internal tracker to ensure duplicates do not end up in
// the result. _usedPlaces is an Object that is being used as a set.
// Not all entries have a place id, thus we fallback to the url for them.
// We cannot use only the url since keywords entries are modified to
// include the search string, and would be returned multiple times. Ids
// are faster too.
this._usedPlaces[aPlaceId || aURISpec] = true;
// Obtain the favicon for this URI.
let favicon;
if (aFaviconSpec) {
let uri = this._ioService.newURI(aFaviconSpec, null, null);
favicon = this._faviconService.getFaviconLinkForIcon(uri).spec;
}
favicon = favicon || this._faviconService.defaultFavicon.spec;
this._result.appendMatch(aURISpec, aTitle, favicon, aStyle);
},
/**
* Determines if the specified AutoComplete behavior is set.
*
* @param aType
* The behavior type to test for.
* @return true if the behavior is set, false otherwise.
*/
_hasBehavior: function PAC_hasBehavior(aType)
{
return (this._behavior &
Ci.mozIPlacesAutoComplete["BEHAVIOR_" + aType.toUpperCase()]);
},
/**
* Enables the desired AutoComplete behavior.
*
* @param aType
* The behavior type to set.
*/
_setBehavior: function PAC_setBehavior(aType)
{
this._behavior |=
Ci.mozIPlacesAutoComplete["BEHAVIOR_" + aType.toUpperCase()];
},
/**
* Determines if we are done searching or not.
*
* @return true if we have completed searching, false otherwise.
*/
isSearchComplete: function PAC_isSearchComplete()
{
// If _pendingQuery is null, we should no longer do any work since we have
// already called _finishSearch. This means we completed our search.
return this._pendingQuery == null;
},
/**
* Determines if the given handle of a pending statement is a pending search
* or not.
*
* @param aHandle
* A mozIStoragePendingStatement to check and see if we are waiting for
* results from it still.
* @return true if it is a pending query, false otherwise.
*/
isPendingSearch: function PAC_isPendingSearch(aHandle)
{
return this._pendingQuery == aHandle;
},
//////////////////////////////////////////////////////////////////////////////
//// nsISupports
classID: Components.ID("d0272978-beab-4adc-a3d4-04b76acfa4e7"),
QueryInterface: XPCOMUtils.generateQI([
Ci.nsIAutoCompleteSearch,
Ci.nsIAutoCompleteSimpleResultListener,
Ci.mozIPlacesAutoComplete,
Ci.mozIStorageStatementCallback,
Ci.nsIObserver,
])
};
let components = [nsPlacesAutoComplete];
const NSGetFactory = XPCOMUtils.generateNSGetFactory(components);