gecko/toolkit/components/passwordmgr/nsLoginManagerPrompter.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

1530 lines
55 KiB
JavaScript

/* ***** 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 Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Justin Dolske <dolske@mozilla.com> (original author)
* Ehsan Akhgari <ehsan.akhgari@gmail.com>
* Frank Yan <fyan@mozilla.com>
* Margaret Leibovic <margaret.leibovic@gmail.com>
*
* 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 ***** */
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cr = Components.results;
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
Components.utils.import("resource://gre/modules/Services.jsm");
/*
* LoginManagerPromptFactory
*
* Implements nsIPromptFactory
*
* Invoked by [toolkit/components/prompts/src/nsPrompter.js]
*/
function LoginManagerPromptFactory() {
Services.obs.addObserver(this, "quit-application-granted", true);
Services.obs.addObserver(this, "passwordmgr-crypto-login", true);
Services.obs.addObserver(this, "passwordmgr-crypto-loginCanceled", true);
}
LoginManagerPromptFactory.prototype = {
classID : Components.ID("{749e62f4-60ae-4569-a8a2-de78b649660e}"),
QueryInterface : XPCOMUtils.generateQI([Ci.nsIPromptFactory, Ci.nsIObserver, Ci.nsISupportsWeakReference]),
_debug : false,
_asyncPrompts : {},
_asyncPromptInProgress : false,
observe : function (subject, topic, data) {
this.log("Observed: " + topic);
if (topic == "quit-application-granted") {
this._cancelPendingPrompts();
} else if (topic == "passwordmgr-crypto-login") {
// Start processing the deferred prompters.
this._doAsyncPrompt();
} else if (topic == "passwordmgr-crypto-loginCanceled") {
// User canceled a Master Password prompt, so go ahead and cancel
// all pending auth prompts to avoid nagging over and over.
this._cancelPendingPrompts();
}
},
getPrompt : function (aWindow, aIID) {
var prefBranch = Services.prefs.getBranch("signon.");
this._debug = prefBranch.getBoolPref("debug");
var prompt = new LoginManagerPrompter().QueryInterface(aIID);
prompt.init(aWindow, this);
return prompt;
},
_doAsyncPrompt : function() {
if (this._asyncPromptInProgress) {
this.log("_doAsyncPrompt bypassed, already in progress");
return;
}
// Find the first prompt key we have in the queue
var hashKey = null;
for (hashKey in this._asyncPrompts)
break;
if (!hashKey) {
this.log("_doAsyncPrompt:run bypassed, no prompts in the queue");
return;
}
// If login manger has logins for this host, defer prompting if we're
// already waiting on a master password entry.
var prompt = this._asyncPrompts[hashKey];
var prompter = prompt.prompter;
var [hostname, httpRealm] = prompter._getAuthTarget(prompt.channel, prompt.authInfo);
var hasLogins = (prompter._pwmgr.countLogins(hostname, null, httpRealm) > 0);
if (hasLogins && prompter._pwmgr.uiBusy) {
this.log("_doAsyncPrompt:run bypassed, master password UI busy");
return;
}
this._asyncPromptInProgress = true;
prompt.inProgress = true;
var self = this;
var runnable = {
run : function() {
var ok = false;
try {
self.log("_doAsyncPrompt:run - performing the prompt for '" + hashKey + "'");
ok = prompter.promptAuth(prompt.channel,
prompt.level,
prompt.authInfo);
} catch (e) {
Components.utils.reportError("LoginManagerPrompter: " +
"_doAsyncPrompt:run: " + e + "\n");
}
delete self._asyncPrompts[hashKey];
prompt.inProgress = false;
self._asyncPromptInProgress = false;
for each (var consumer in prompt.consumers) {
if (!consumer.callback)
// Not having a callback means that consumer didn't provide it
// or canceled the notification
continue;
self.log("Calling back to " + consumer.callback + " ok=" + ok);
try {
if (ok)
consumer.callback.onAuthAvailable(consumer.context, prompt.authInfo);
else
consumer.callback.onAuthCancelled(consumer.context, true);
} catch (e) { /* Throw away exceptions caused by callback */ }
}
self._doAsyncPrompt();
}
}
Services.tm.mainThread.dispatch(runnable, Ci.nsIThread.DISPATCH_NORMAL);
this.log("_doAsyncPrompt:run dispatched");
},
_cancelPendingPrompts : function() {
this.log("Canceling all pending prompts...");
var asyncPrompts = this._asyncPrompts;
this.__proto__._asyncPrompts = {};
for each (var prompt in asyncPrompts) {
// Watch out! If this prompt is currently prompting, let it handle
// notifying the callbacks of success/failure, since it's already
// asking the user for input. Reusing a callback can be crashy.
if (prompt.inProgress) {
this.log("skipping a prompt in progress");
continue;
}
for each (var consumer in prompt.consumers) {
if (!consumer.callback)
continue;
this.log("Canceling async auth prompt callback " + consumer.callback);
try {
consumer.callback.onAuthCancelled(consumer.context, true);
} catch (e) { /* Just ignore exceptions from the callback */ }
}
}
},
log : function (message) {
if (!this._debug)
return;
dump("Pwmgr PromptFactory: " + message + "\n");
Services.console.logStringMessage("Pwmgr PrompFactory: " + message);
}
}; // end of LoginManagerPromptFactory implementation
/* ==================== LoginManagerPrompter ==================== */
/*
* LoginManagerPrompter
*
* Implements interfaces for prompting the user to enter/save/change auth info.
*
* nsIAuthPrompt: Used by SeaMonkey, Thunderbird, but not Firefox.
*
* nsIAuthPrompt2: Is invoked by a channel for protocol-based authentication
* (eg HTTP Authenticate, FTP login).
*
* nsILoginManagerPrompter: Used by Login Manager for saving/changing logins
* found in HTML forms.
*/
function LoginManagerPrompter() {}
LoginManagerPrompter.prototype = {
classID : Components.ID("{8aa66d77-1bbb-45a6-991e-b8f47751c291}"),
QueryInterface : XPCOMUtils.generateQI([Ci.nsIAuthPrompt,
Ci.nsIAuthPrompt2,
Ci.nsILoginManagerPrompter]),
_factory : null,
_window : null,
_debug : false, // mirrors signon.debug
__pwmgr : null, // Password Manager service
get _pwmgr() {
if (!this.__pwmgr)
this.__pwmgr = Cc["@mozilla.org/login-manager;1"].
getService(Ci.nsILoginManager);
return this.__pwmgr;
},
__promptService : null, // Prompt service for user interaction
get _promptService() {
if (!this.__promptService)
this.__promptService =
Cc["@mozilla.org/embedcomp/prompt-service;1"].
getService(Ci.nsIPromptService2);
return this.__promptService;
},
__strBundle : null, // String bundle for L10N
get _strBundle() {
if (!this.__strBundle) {
var bunService = Cc["@mozilla.org/intl/stringbundle;1"].
getService(Ci.nsIStringBundleService);
this.__strBundle = bunService.createBundle(
"chrome://passwordmgr/locale/passwordmgr.properties");
if (!this.__strBundle)
throw "String bundle for Login Manager not present!";
}
return this.__strBundle;
},
__brandBundle : null, // String bundle for L10N
get _brandBundle() {
if (!this.__brandBundle) {
var bunService = Cc["@mozilla.org/intl/stringbundle;1"].
getService(Ci.nsIStringBundleService);
this.__brandBundle = bunService.createBundle(
"chrome://branding/locale/brand.properties");
if (!this.__brandBundle)
throw "Branding string bundle not present!";
}
return this.__brandBundle;
},
__ellipsis : null,
get _ellipsis() {
if (!this.__ellipsis) {
this.__ellipsis = "\u2026";
try {
this.__ellipsis = Services.prefs.getComplexValue(
"intl.ellipsis", Ci.nsIPrefLocalizedString).data;
} catch (e) { }
}
return this.__ellipsis;
},
// Whether we are in private browsing mode
get _inPrivateBrowsing() {
// The Private Browsing service might not be available.
try {
var pbs = Cc["@mozilla.org/privatebrowsing;1"].
getService(Ci.nsIPrivateBrowsingService);
return pbs.privateBrowsingEnabled;
} catch (e) {
return false;
}
},
/*
* log
*
* Internal function for logging debug messages to the Error Console window.
*/
log : function (message) {
if (!this._debug)
return;
dump("Pwmgr Prompter: " + message + "\n");
Services.console.logStringMessage("Pwmgr Prompter: " + message);
},
/* ---------- nsIAuthPrompt prompts ---------- */
/*
* prompt
*
* Wrapper around the prompt service prompt. Saving random fields here
* doesn't really make sense and therefore isn't implemented.
*/
prompt : function (aDialogTitle, aText, aPasswordRealm,
aSavePassword, aDefaultText, aResult) {
if (aSavePassword != Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER)
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
this.log("===== prompt() called =====");
if (aDefaultText) {
aResult.value = aDefaultText;
}
return this._promptService.prompt(this._window,
aDialogTitle, aText, aResult, null, {});
},
/*
* promptUsernameAndPassword
*
* Looks up a username and password in the database. Will prompt the user
* with a dialog, even if a username and password are found.
*/
promptUsernameAndPassword : function (aDialogTitle, aText, aPasswordRealm,
aSavePassword, aUsername, aPassword) {
this.log("===== promptUsernameAndPassword() called =====");
if (aSavePassword == Ci.nsIAuthPrompt.SAVE_PASSWORD_FOR_SESSION)
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
var selectedLogin = null;
var checkBox = { value : false };
var checkBoxLabel = null;
var [hostname, realm, unused] = this._getRealmInfo(aPasswordRealm);
// If hostname is null, we can't save this login.
if (hostname) {
var canRememberLogin;
if (this._inPrivateBrowsing)
canRememberLogin = false;
else
canRememberLogin = (aSavePassword ==
Ci.nsIAuthPrompt.SAVE_PASSWORD_PERMANENTLY) &&
this._pwmgr.getLoginSavingEnabled(hostname);
// if checkBoxLabel is null, the checkbox won't be shown at all.
if (canRememberLogin)
checkBoxLabel = this._getLocalizedString("rememberPassword");
// Look for existing logins.
var foundLogins = this._pwmgr.findLogins({}, hostname, null,
realm);
// XXX Like the original code, we can't deal with multiple
// account selection. (bug 227632)
if (foundLogins.length > 0) {
selectedLogin = foundLogins[0];
// If the caller provided a username, try to use it. If they
// provided only a password, this will try to find a password-only
// login (or return null if none exists).
if (aUsername.value)
selectedLogin = this._repickSelectedLogin(foundLogins,
aUsername.value);
if (selectedLogin) {
checkBox.value = true;
aUsername.value = selectedLogin.username;
// If the caller provided a password, prefer it.
if (!aPassword.value)
aPassword.value = selectedLogin.password;
}
}
}
var ok = this._promptService.promptUsernameAndPassword(this._window,
aDialogTitle, aText, aUsername, aPassword,
checkBoxLabel, checkBox);
if (!ok || !checkBox.value || !hostname)
return ok;
if (!aPassword.value) {
this.log("No password entered, so won't offer to save.");
return ok;
}
// XXX We can't prompt with multiple logins yet (bug 227632), so
// the entered login might correspond to an existing login
// other than the one we originally selected.
selectedLogin = this._repickSelectedLogin(foundLogins, aUsername.value);
// If we didn't find an existing login, or if the username
// changed, save as a new login.
if (!selectedLogin) {
// add as new
this.log("New login seen for " + realm);
var newLogin = Cc["@mozilla.org/login-manager/loginInfo;1"].
createInstance(Ci.nsILoginInfo);
newLogin.init(hostname, null, realm,
aUsername.value, aPassword.value, "", "");
this._pwmgr.addLogin(newLogin);
} else if (aPassword.value != selectedLogin.password) {
// update password
this.log("Updating password for " + realm);
this._updateLogin(selectedLogin, aPassword.value);
} else {
this.log("Login unchanged, no further action needed.");
this._updateLogin(selectedLogin);
}
return ok;
},
/*
* promptPassword
*
* If a password is found in the database for the password realm, it is
* returned straight away without displaying a dialog.
*
* If a password is not found in the database, the user will be prompted
* with a dialog with a text field and ok/cancel buttons. If the user
* allows it, then the password will be saved in the database.
*/
promptPassword : function (aDialogTitle, aText, aPasswordRealm,
aSavePassword, aPassword) {
this.log("===== promptPassword called() =====");
if (aSavePassword == Ci.nsIAuthPrompt.SAVE_PASSWORD_FOR_SESSION)
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
var checkBox = { value : false };
var checkBoxLabel = null;
var [hostname, realm, username] = this._getRealmInfo(aPasswordRealm);
username = decodeURIComponent(username);
// If hostname is null, we can't save this login.
if (hostname && !this._inPrivateBrowsing) {
var canRememberLogin = (aSavePassword ==
Ci.nsIAuthPrompt.SAVE_PASSWORD_PERMANENTLY) &&
this._pwmgr.getLoginSavingEnabled(hostname);
// if checkBoxLabel is null, the checkbox won't be shown at all.
if (canRememberLogin)
checkBoxLabel = this._getLocalizedString("rememberPassword");
if (!aPassword.value) {
// Look for existing logins.
var foundLogins = this._pwmgr.findLogins({}, hostname, null,
realm);
// XXX Like the original code, we can't deal with multiple
// account selection (bug 227632). We can deal with finding the
// account based on the supplied username - but in this case we'll
// just return the first match.
for (var i = 0; i < foundLogins.length; ++i) {
if (foundLogins[i].username == username) {
aPassword.value = foundLogins[i].password;
// wallet returned straight away, so this mimics that code
return true;
}
}
}
}
var ok = this._promptService.promptPassword(this._window, aDialogTitle,
aText, aPassword,
checkBoxLabel, checkBox);
if (ok && checkBox.value && hostname && aPassword.value) {
var newLogin = Cc["@mozilla.org/login-manager/loginInfo;1"].
createInstance(Ci.nsILoginInfo);
newLogin.init(hostname, null, realm, username,
aPassword.value, "", "");
this.log("New login seen for " + realm);
this._pwmgr.addLogin(newLogin);
}
return ok;
},
/* ---------- nsIAuthPrompt helpers ---------- */
/**
* Given aRealmString, such as "http://user@example.com/foo", returns an
* array of:
* - the formatted hostname
* - the realm (hostname + path)
* - the username, if present
*
* If aRealmString is in the format produced by NS_GetAuthKey for HTTP[S]
* channels, e.g. "example.com:80 (httprealm)", null is returned for all
* arguments to let callers know the login can't be saved because we don't
* know whether it's http or https.
*/
_getRealmInfo : function (aRealmString) {
var httpRealm = /^.+ \(.+\)$/;
if (httpRealm.test(aRealmString))
return [null, null, null];
var uri = Services.io.newURI(aRealmString, null, null);
var pathname = "";
if (uri.path != "/")
pathname = uri.path;
var formattedHostname = this._getFormattedHostname(uri);
return [formattedHostname, formattedHostname + pathname, uri.username];
},
/* ---------- nsIAuthPrompt2 prompts ---------- */
/*
* promptAuth
*
* Implementation of nsIAuthPrompt2.
*
* nsIChannel aChannel
* int aLevel
* nsIAuthInformation aAuthInfo
*/
promptAuth : function (aChannel, aLevel, aAuthInfo) {
var selectedLogin = null;
var checkbox = { value : false };
var checkboxLabel = null;
var epicfail = false;
var canAutologin = false;
try {
this.log("===== promptAuth called =====");
// If the user submits a login but it fails, we need to remove the
// notification bar that was displayed. Conveniently, the user will
// be prompted for authentication again, which brings us here.
this._removeLoginNotifications();
var [hostname, httpRealm] = this._getAuthTarget(aChannel, aAuthInfo);
// Looks for existing logins to prefill the prompt with.
var foundLogins = this._pwmgr.findLogins({},
hostname, null, httpRealm);
this.log("found " + foundLogins.length + " matching logins.");
// XXX Can't select from multiple accounts yet. (bug 227632)
if (foundLogins.length > 0) {
selectedLogin = foundLogins[0];
this._SetAuthInfo(aAuthInfo, selectedLogin.username,
selectedLogin.password);
// Allow automatic proxy login
if (aAuthInfo.flags & Ci.nsIAuthInformation.AUTH_PROXY &&
!(aAuthInfo.flags & Ci.nsIAuthInformation.PREVIOUS_FAILED) &&
Services.prefs.getBoolPref("signon.autologin.proxy") &&
!this._inPrivateBrowsing) {
this.log("Autologin enabled, skipping auth prompt.");
canAutologin = true;
}
checkbox.value = true;
}
var canRememberLogin = this._pwmgr.getLoginSavingEnabled(hostname);
if (this._inPrivateBrowsing)
canRememberLogin = false;
// if checkboxLabel is null, the checkbox won't be shown at all.
var notifyBox = this._getNotifyBox();
if (canRememberLogin && !notifyBox)
checkboxLabel = this._getLocalizedString("rememberPassword");
} catch (e) {
// Ignore any errors and display the prompt anyway.
epicfail = true;
Components.utils.reportError("LoginManagerPrompter: " +
"Epic fail in promptAuth: " + e + "\n");
}
var ok = canAutologin ||
this._promptService.promptAuth(this._window,
aChannel, aLevel, aAuthInfo,
checkboxLabel, checkbox);
// If there's a notification box, use it to allow the user to
// determine if the login should be saved. If there isn't a
// notification box, only save the login if the user set the
// checkbox to do so.
var rememberLogin = notifyBox ? canRememberLogin : checkbox.value;
if (!ok || !rememberLogin || epicfail)
return ok;
try {
var [username, password] = this._GetAuthInfo(aAuthInfo);
if (!password) {
this.log("No password entered, so won't offer to save.");
return ok;
}
// XXX We can't prompt with multiple logins yet (bug 227632), so
// the entered login might correspond to an existing login
// other than the one we originally selected.
selectedLogin = this._repickSelectedLogin(foundLogins, username);
// If we didn't find an existing login, or if the username
// changed, save as a new login.
if (!selectedLogin) {
this.log("New login seen for " + username +
" @ " + hostname + " (" + httpRealm + ")");
var newLogin = Cc["@mozilla.org/login-manager/loginInfo;1"].
createInstance(Ci.nsILoginInfo);
newLogin.init(hostname, null, httpRealm,
username, password, "", "");
var notifyObj = this._getPopupNote() || notifyBox;
if (notifyObj)
this._showSaveLoginNotification(notifyObj, newLogin);
else
this._pwmgr.addLogin(newLogin);
} else if (password != selectedLogin.password) {
this.log("Updating password for " + username +
" @ " + hostname + " (" + httpRealm + ")");
var notifyObj = this._getPopupNote() || notifyBox;
if (notifyObj)
this._showChangeLoginNotification(notifyObj,
selectedLogin, password);
else
this._updateLogin(selectedLogin, password);
} else {
this.log("Login unchanged, no further action needed.");
this._updateLogin(selectedLogin);
}
} catch (e) {
Components.utils.reportError("LoginManagerPrompter: " +
"Fail2 in promptAuth: " + e + "\n");
}
return ok;
},
asyncPromptAuth : function (aChannel, aCallback, aContext, aLevel, aAuthInfo) {
var cancelable = null;
try {
this.log("===== asyncPromptAuth called =====");
// If the user submits a login but it fails, we need to remove the
// notification bar that was displayed. Conveniently, the user will
// be prompted for authentication again, which brings us here.
this._removeLoginNotifications();
cancelable = this._newAsyncPromptConsumer(aCallback, aContext);
var [hostname, httpRealm] = this._getAuthTarget(aChannel, aAuthInfo);
var hashKey = aLevel + "|" + hostname + "|" + httpRealm;
this.log("Async prompt key = " + hashKey);
var asyncPrompt = this._factory._asyncPrompts[hashKey];
if (asyncPrompt) {
this.log("Prompt bound to an existing one in the queue, callback = " + aCallback);
asyncPrompt.consumers.push(cancelable);
return cancelable;
}
this.log("Adding new prompt to the queue, callback = " + aCallback);
asyncPrompt = {
consumers: [cancelable],
channel: aChannel,
authInfo: aAuthInfo,
level: aLevel,
inProgress : false,
prompter: this
}
this._factory._asyncPrompts[hashKey] = asyncPrompt;
this._factory._doAsyncPrompt();
}
catch (e) {
Components.utils.reportError("LoginManagerPrompter: " +
"asyncPromptAuth: " + e + "\nFalling back to promptAuth\n");
// Fail the prompt operation to let the consumer fall back
// to synchronous promptAuth method
throw e;
}
return cancelable;
},
/* ---------- nsILoginManagerPrompter prompts ---------- */
/*
* init
*
*/
init : function (aWindow, aFactory) {
this._window = aWindow;
this._factory = aFactory || null;
var prefBranch = Services.prefs.getBranch("signon.");
this._debug = prefBranch.getBoolPref("debug");
this.log("===== initialized =====");
},
/*
* promptToSavePassword
*
*/
promptToSavePassword : function (aLogin) {
var notifyObj = this._getPopupNote() || this._getNotifyBox();
if (notifyObj)
this._showSaveLoginNotification(notifyObj, aLogin);
else
this._showSaveLoginDialog(aLogin);
},
/*
* _showLoginNotification
*
* Displays a notification bar.
*
*/
_showLoginNotification : function (aNotifyBox, aName, aText, aButtons) {
var oldBar = aNotifyBox.getNotificationWithValue(aName);
const priority = aNotifyBox.PRIORITY_INFO_MEDIUM;
this.log("Adding new " + aName + " notification bar");
var newBar = aNotifyBox.appendNotification(
aText, aName,
"chrome://mozapps/skin/passwordmgr/key.png",
priority, aButtons);
// The page we're going to hasn't loaded yet, so we want to persist
// across the first location change.
newBar.persistence++;
// Sites like Gmail perform a funky redirect dance before you end up
// at the post-authentication page. I don't see a good way to
// heuristically determine when to ignore such location changes, so
// we'll try ignoring location changes based on a time interval.
newBar.timeout = Date.now() + 20000; // 20 seconds
if (oldBar) {
this.log("(...and removing old " + aName + " notification bar)");
aNotifyBox.removeNotification(oldBar);
}
},
/*
* _showSaveLoginNotification
*
* Displays a notification bar or a popup notification, to allow the user
* to save the specified login. This allows the user to see the results of
* their login, and only save a login which they know worked.
*
* @param aNotifyObj
* A notification box or a popup notification.
*/
_showSaveLoginNotification : function (aNotifyObj, aLogin) {
// Ugh. We can't use the strings from the popup window, because they
// have the access key marked in the string (eg "Mo&zilla"), along
// with some weird rules for handling access keys that do not occur
// in the string, for L10N. See commonDialog.js's setLabelForNode().
var neverButtonText =
this._getLocalizedString("notifyBarNeverRememberButtonText");
var neverButtonAccessKey =
this._getLocalizedString("notifyBarNeverRememberButtonAccessKey");
var rememberButtonText =
this._getLocalizedString("notifyBarRememberPasswordButtonText");
var rememberButtonAccessKey =
this._getLocalizedString("notifyBarRememberPasswordButtonAccessKey");
var displayHost = this._getShortDisplayHost(aLogin.hostname);
var notificationText;
if (aLogin.username) {
var displayUser = this._sanitizeUsername(aLogin.username);
notificationText = this._getLocalizedString(
"rememberPasswordText",
[displayUser, displayHost]);
} else {
notificationText = this._getLocalizedString(
"rememberPasswordTextNoUsername",
[displayHost]);
}
// The callbacks in |buttons| have a closure to access the variables
// in scope here; set one to |this._pwmgr| so we can get back to pwmgr
// without a getService() call.
var pwmgr = this._pwmgr;
// Notification is a PopupNotification
if (aNotifyObj == this._getPopupNote()) {
// "Remember" button
var mainAction = {
label: rememberButtonText,
accessKey: rememberButtonAccessKey,
callback: function(aNotifyObj, aButton) {
pwmgr.addLogin(aLogin);
}
};
var secondaryActions = [
// "Never for this site" button
{
label: neverButtonText,
accessKey: neverButtonAccessKey,
callback: function(aNotifyObj, aButton) {
pwmgr.setLoginSavingEnabled(aLogin.hostname, false);
}
}
];
var notifyWin = this._getNotifyWindow();
var chromeWin = this._getChromeWindow(notifyWin).wrappedJSObject;
var browser = chromeWin.gBrowser.
getBrowserForDocument(this._window.top.document);
aNotifyObj.show(browser, "password-save", notificationText,
"password-notification-icon", mainAction,
secondaryActions, { timeout: Date.now() + 10000,
persistWhileVisible: true });
} else {
var notNowButtonText =
this._getLocalizedString("notifyBarNotNowButtonText");
var notNowButtonAccessKey =
this._getLocalizedString("notifyBarNotNowButtonAccessKey");
var buttons = [
// "Remember" button
{
label: rememberButtonText,
accessKey: rememberButtonAccessKey,
popup: null,
callback: function(aNotifyObj, aButton) {
pwmgr.addLogin(aLogin);
}
},
// "Never for this site" button
{
label: neverButtonText,
accessKey: neverButtonAccessKey,
popup: null,
callback: function(aNotifyObj, aButton) {
pwmgr.setLoginSavingEnabled(aLogin.hostname, false);
}
},
// "Not now" button
{
label: notNowButtonText,
accessKey: notNowButtonAccessKey,
popup: null,
callback: function() { /* NOP */ }
}
];
this._showLoginNotification(aNotifyObj, "password-save",
notificationText, buttons);
}
},
/*
* _removeLoginNotifications
*
*/
_removeLoginNotifications : function () {
var popupNote = this._getPopupNote();
if (popupNote)
popupNote = popupNote.getNotification("password-save");
if (popupNote)
popupNote.remove();
var notifyBox = this._getNotifyBox();
if (notifyBox) {
var oldBar = notifyBox.getNotificationWithValue("password-save");
if (oldBar) {
this.log("Removing save-password notification bar.");
notifyBox.removeNotification(oldBar);
}
oldBar = notifyBox.getNotificationWithValue("password-change");
if (oldBar) {
this.log("Removing change-password notification bar.");
notifyBox.removeNotification(oldBar);
}
}
},
/*
* _showSaveLoginDialog
*
* Called when we detect a new login in a form submission,
* asks the user what to do.
*
*/
_showSaveLoginDialog : function (aLogin) {
const buttonFlags = Ci.nsIPrompt.BUTTON_POS_1_DEFAULT +
(Ci.nsIPrompt.BUTTON_TITLE_IS_STRING * Ci.nsIPrompt.BUTTON_POS_0) +
(Ci.nsIPrompt.BUTTON_TITLE_IS_STRING * Ci.nsIPrompt.BUTTON_POS_1) +
(Ci.nsIPrompt.BUTTON_TITLE_IS_STRING * Ci.nsIPrompt.BUTTON_POS_2);
var brandShortName =
this._brandBundle.GetStringFromName("brandShortName");
var displayHost = this._getShortDisplayHost(aLogin.hostname);
var dialogText;
if (aLogin.username) {
var displayUser = this._sanitizeUsername(aLogin.username);
dialogText = this._getLocalizedString(
"saveLoginText",
[brandShortName, displayUser, displayHost]);
} else {
dialogText = this._getLocalizedString(
"saveLoginTextNoUsername",
[brandShortName, displayHost]);
}
var dialogTitle = this._getLocalizedString(
"savePasswordTitle");
var neverButtonText = this._getLocalizedString(
"neverForSiteButtonText");
var rememberButtonText = this._getLocalizedString(
"rememberButtonText");
var notNowButtonText = this._getLocalizedString(
"notNowButtonText");
this.log("Prompting user to save/ignore login");
var userChoice = this._promptService.confirmEx(this._window,
dialogTitle, dialogText,
buttonFlags, rememberButtonText,
notNowButtonText, neverButtonText,
null, {});
// Returns:
// 0 - Save the login
// 1 - Ignore the login this time
// 2 - Never save logins for this site
if (userChoice == 2) {
this.log("Disabling " + aLogin.hostname + " logins by request.");
this._pwmgr.setLoginSavingEnabled(aLogin.hostname, false);
} else if (userChoice == 0) {
this.log("Saving login for " + aLogin.hostname);
this._pwmgr.addLogin(aLogin);
} else {
// userChoice == 1 --> just ignore the login.
this.log("Ignoring login.");
}
},
/*
* promptToChangePassword
*
* Called when we think we detect a password change for an existing
* login, when the form being submitted contains multiple password
* fields.
*
*/
promptToChangePassword : function (aOldLogin, aNewLogin) {
var notifyObj = this._getPopupNote() || this._getNotifyBox();
if (notifyObj)
this._showChangeLoginNotification(notifyObj, aOldLogin,
aNewLogin.password);
else
this._showChangeLoginDialog(aOldLogin, aNewLogin.password);
},
/*
* _showChangeLoginNotification
*
* Shows the Change Password notification bar or popup notification.
*
* @param aNotifyObj
* A notification box or a popup notification.
*/
_showChangeLoginNotification : function (aNotifyObj, aOldLogin, aNewPassword) {
var notificationText;
if (aOldLogin.username)
notificationText = this._getLocalizedString(
"updatePasswordText",
[aOldLogin.username]);
else
notificationText = this._getLocalizedString(
"updatePasswordTextNoUser");
var changeButtonText =
this._getLocalizedString("notifyBarUpdateButtonText");
var changeButtonAccessKey =
this._getLocalizedString("notifyBarUpdateButtonAccessKey");
// The callbacks in |buttons| have a closure to access the variables
// in scope here; set one to |this._pwmgr| so we can get back to pwmgr
// without a getService() call.
var self = this;
// Notification is a PopupNotification
if (aNotifyObj == this._getPopupNote()) {
// "Yes" button
var mainAction = {
label: changeButtonText,
accessKey: changeButtonAccessKey,
popup: null,
callback: function(aNotifyObj, aButton) {
self._updateLogin(aOldLogin, aNewPassword);
}
};
var notifyWin = this._getNotifyWindow();
var chromeWin = this._getChromeWindow(notifyWin).wrappedJSObject;
var browser = chromeWin.gBrowser.
getBrowserForDocument(this._window.top.document);
aNotifyObj.show(browser, "password-change", notificationText,
"password-notification-icon", mainAction,
null, { timeout: Date.now() + 10000,
persistWhileVisible: true });
} else {
var dontChangeButtonText =
this._getLocalizedString("notifyBarDontChangeButtonText");
var dontChangeButtonAccessKey =
this._getLocalizedString("notifyBarDontChangeButtonAccessKey");
var buttons = [
// "Yes" button
{
label: changeButtonText,
accessKey: changeButtonAccessKey,
popup: null,
callback: function(aNotifyObj, aButton) {
self._updateLogin(aOldLogin, aNewPassword);
}
},
// "No" button
{
label: dontChangeButtonText,
accessKey: dontChangeButtonAccessKey,
popup: null,
callback: function(aNotifyObj, aButton) {
// do nothing
}
}
];
this._showLoginNotification(aNotifyObj, "password-change",
notificationText, buttons);
}
},
/*
* _showChangeLoginDialog
*
* Shows the Change Password dialog.
*
*/
_showChangeLoginDialog : function (aOldLogin, aNewPassword) {
const buttonFlags = Ci.nsIPrompt.STD_YES_NO_BUTTONS;
var dialogText;
if (aOldLogin.username)
dialogText = this._getLocalizedString(
"passwordChangeText",
[aOldLogin.username]);
else
dialogText = this._getLocalizedString(
"passwordChangeTextNoUser");
var dialogTitle = this._getLocalizedString(
"passwordChangeTitle");
// returns 0 for yes, 1 for no.
var ok = !this._promptService.confirmEx(this._window,
dialogTitle, dialogText, buttonFlags,
null, null, null,
null, {});
if (ok) {
this.log("Updating password for user " + aOldLogin.username);
this._updateLogin(aOldLogin, aNewPassword);
}
},
/*
* promptToChangePasswordWithUsernames
*
* Called when we detect a password change in a form submission, but we
* don't know which existing login (username) it's for. Asks the user
* to select a username and confirm the password change.
*
* Note: The caller doesn't know the username for aNewLogin, so this
* function fills in .username and .usernameField with the values
* from the login selected by the user.
*
* Note; XPCOM stupidity: |count| is just |logins.length|.
*/
promptToChangePasswordWithUsernames : function (logins, count, aNewLogin) {
const buttonFlags = Ci.nsIPrompt.STD_YES_NO_BUTTONS;
var usernames = logins.map(function (l) l.username);
var dialogText = this._getLocalizedString("userSelectText");
var dialogTitle = this._getLocalizedString("passwordChangeTitle");
var selectedIndex = { value: null };
// If user selects ok, outparam.value is set to the index
// of the selected username.
var ok = this._promptService.select(this._window,
dialogTitle, dialogText,
usernames.length, usernames,
selectedIndex);
if (ok) {
// Now that we know which login to use, modify its password.
var selectedLogin = logins[selectedIndex.value];
this.log("Updating password for user " + selectedLogin.username);
this._updateLogin(selectedLogin, aNewLogin.password);
}
},
/* ---------- Internal Methods ---------- */
/*
* _updateLogin
*/
_updateLogin : function (login, newPassword) {
var now = Date.now();
var propBag = Cc["@mozilla.org/hash-property-bag;1"].
createInstance(Ci.nsIWritablePropertyBag);
if (newPassword) {
propBag.setProperty("password", newPassword);
// Explicitly set the password change time here (even though it would
// be changed automatically), to ensure that it's exactly the same
// value as timeLastUsed.
propBag.setProperty("timePasswordChanged", now);
}
propBag.setProperty("timeLastUsed", now);
propBag.setProperty("timesUsedIncrement", 1);
this._pwmgr.modifyLogin(login, propBag);
},
/*
* _getChromeWindow
*
* Given a content DOM window, returns the chrome window it's in.
*/
_getChromeWindow: function (aWindow) {
var chromeWin = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShell)
.chromeEventHandler.ownerDocument.defaultView;
return chromeWin;
},
/*
* _getNotifyWindow
*/
_getNotifyWindow: function () {
try {
// Get topmost window, in case we're in a frame.
var notifyWin = this._window.top;
// Some sites pop up a temporary login window, when disappears
// upon submission of credentials. We want to put the notification
// bar in the opener window if this seems to be happening.
if (notifyWin.opener) {
var chromeDoc = this._getChromeWindow(notifyWin).
document.documentElement;
var webnav = notifyWin.
QueryInterface(Ci.nsIInterfaceRequestor).
getInterface(Ci.nsIWebNavigation);
// Check to see if the current window was opened with chrome
// disabled, and if so use the opener window. But if the window
// has been used to visit other pages (ie, has a history),
// assume it'll stick around and *don't* use the opener.
if (chromeDoc.getAttribute("chromehidden") &&
webnav.sessionHistory.count == 1) {
this.log("Using opener window for notification bar.");
notifyWin = notifyWin.opener;
}
}
return notifyWin;
} catch (e) {
// If any errors happen, just assume no notification box.
this.log("Unable to get notify window");
return null;
}
},
/*
* _getPopupNote
*
* Returns the popup notification to this prompter,
* or null if there isn't one available.
*/
_getPopupNote : function () {
let popupNote = null;
try {
let notifyWin = this._getNotifyWindow();
// Get the chrome window for the content window we're using.
// .wrappedJSObject needed here -- see bug 422974 comment 5.
let chromeWin = this._getChromeWindow(notifyWin).wrappedJSObject;
popupNote = chromeWin.PopupNotifications;
} catch (e) {
this.log("Popup notifications not available on window");
}
return popupNote;
},
/*
* _getNotifyBox
*
* Returns the notification box to this prompter, or null if there isn't
* a notification box available.
*/
_getNotifyBox : function () {
let notifyBox = null;
try {
let notifyWin = this._getNotifyWindow();
// Get the chrome window for the content window we're using.
// .wrappedJSObject needed here -- see bug 422974 comment 5.
let chromeWin = this._getChromeWindow(notifyWin).wrappedJSObject;
notifyBox = chromeWin.getNotificationBox(notifyWin);
} catch (e) {
this.log("Notification bars not available on window");
}
return notifyBox;
},
/*
* _repickSelectedLogin
*
* The user might enter a login that isn't the one we prefilled, but
* is the same as some other existing login. So, pick a login with a
* matching username, or return null.
*/
_repickSelectedLogin : function (foundLogins, username) {
for (var i = 0; i < foundLogins.length; i++)
if (foundLogins[i].username == username)
return foundLogins[i];
return null;
},
/*
* _getLocalizedString
*
* Can be called as:
* _getLocalizedString("key1");
* _getLocalizedString("key2", ["arg1"]);
* _getLocalizedString("key3", ["arg1", "arg2"]);
* (etc)
*
* Returns the localized string for the specified key,
* formatted if required.
*
*/
_getLocalizedString : function (key, formatArgs) {
if (formatArgs)
return this._strBundle.formatStringFromName(
key, formatArgs, formatArgs.length);
else
return this._strBundle.GetStringFromName(key);
},
/*
* _sanitizeUsername
*
* Sanitizes the specified username, by stripping quotes and truncating if
* it's too long. This helps prevent an evil site from messing with the
* "save password?" prompt too much.
*/
_sanitizeUsername : function (username) {
if (username.length > 30) {
username = username.substring(0, 30);
username += this._ellipsis;
}
return username.replace(/['"]/g, "");
},
/*
* _getFormattedHostname
*
* The aURI parameter may either be a string uri, or an nsIURI instance.
*
* Returns the hostname to use in a nsILoginInfo object (for example,
* "http://example.com").
*/
_getFormattedHostname : function (aURI) {
var uri;
if (aURI instanceof Ci.nsIURI) {
uri = aURI;
} else {
uri = Services.io.newURI(aURI, null, null);
}
var scheme = uri.scheme;
var hostname = scheme + "://" + uri.host;
// If the URI explicitly specified a port, only include it when
// it's not the default. (We never want "http://foo.com:80")
port = uri.port;
if (port != -1) {
var handler = Services.io.getProtocolHandler(scheme);
if (port != handler.defaultPort)
hostname += ":" + port;
}
return hostname;
},
/*
* _getShortDisplayHost
*
* Converts a login's hostname field (a URL) to a short string for
* prompting purposes. Eg, "http://foo.com" --> "foo.com", or
* "ftp://www.site.co.uk" --> "site.co.uk".
*/
_getShortDisplayHost: function (aURIString) {
var displayHost;
var eTLDService = Cc["@mozilla.org/network/effective-tld-service;1"].
getService(Ci.nsIEffectiveTLDService);
var idnService = Cc["@mozilla.org/network/idn-service;1"].
getService(Ci.nsIIDNService);
try {
var uri = Services.io.newURI(aURIString, null, null);
var baseDomain = eTLDService.getBaseDomain(uri);
displayHost = idnService.convertToDisplayIDN(baseDomain, {});
} catch (e) {
this.log("_getShortDisplayHost couldn't process " + aURIString);
}
if (!displayHost)
displayHost = aURIString;
return displayHost;
},
/*
* _getAuthTarget
*
* Returns the hostname and realm for which authentication is being
* requested, in the format expected to be used with nsILoginInfo.
*/
_getAuthTarget : function (aChannel, aAuthInfo) {
var hostname, realm;
// If our proxy is demanding authentication, don't use the
// channel's actual destination.
if (aAuthInfo.flags & Ci.nsIAuthInformation.AUTH_PROXY) {
this.log("getAuthTarget is for proxy auth");
if (!(aChannel instanceof Ci.nsIProxiedChannel))
throw "proxy auth needs nsIProxiedChannel";
var info = aChannel.proxyInfo;
if (!info)
throw "proxy auth needs nsIProxyInfo";
// Proxies don't have a scheme, but we'll use "moz-proxy://"
// so that it's more obvious what the login is for.
var idnService = Cc["@mozilla.org/network/idn-service;1"].
getService(Ci.nsIIDNService);
hostname = "moz-proxy://" +
idnService.convertUTF8toACE(info.host) +
":" + info.port;
realm = aAuthInfo.realm;
if (!realm)
realm = hostname;
return [hostname, realm];
}
hostname = this._getFormattedHostname(aChannel.URI);
// If a HTTP WWW-Authenticate header specified a realm, that value
// will be available here. If it wasn't set or wasn't HTTP, we'll use
// the formatted hostname instead.
realm = aAuthInfo.realm;
if (!realm)
realm = hostname;
return [hostname, realm];
},
/**
* Returns [username, password] as extracted from aAuthInfo (which
* holds this info after having prompted the user).
*
* If the authentication was for a Windows domain, we'll prepend the
* return username with the domain. (eg, "domain\user")
*/
_GetAuthInfo : function (aAuthInfo) {
var username, password;
var flags = aAuthInfo.flags;
if (flags & Ci.nsIAuthInformation.NEED_DOMAIN && aAuthInfo.domain)
username = aAuthInfo.domain + "\\" + aAuthInfo.username;
else
username = aAuthInfo.username;
password = aAuthInfo.password;
return [username, password];
},
/**
* Given a username (possibly in DOMAIN\user form) and password, parses the
* domain out of the username if necessary and sets domain, username and
* password on the auth information object.
*/
_SetAuthInfo : function (aAuthInfo, username, password) {
var flags = aAuthInfo.flags;
if (flags & Ci.nsIAuthInformation.NEED_DOMAIN) {
// Domain is separated from username by a backslash
var idx = username.indexOf("\\");
if (idx == -1) {
aAuthInfo.username = username;
} else {
aAuthInfo.domain = username.substring(0, idx);
aAuthInfo.username = username.substring(idx+1);
}
} else {
aAuthInfo.username = username;
}
aAuthInfo.password = password;
},
_newAsyncPromptConsumer : function(aCallback, aContext) {
return {
QueryInterface: XPCOMUtils.generateQI([Ci.nsICancelable]),
callback: aCallback,
context: aContext,
cancel: function() {
this.callback.onAuthCancelled(this.context, false);
this.callback = null;
this.context = null;
}
}
}
}; // end of LoginManagerPrompter implementation
var component = [LoginManagerPromptFactory, LoginManagerPrompter];
var NSGetFactory = XPCOMUtils.generateNSGetFactory(component);