Files
tubestation/browser/components/migration/src/nsSafariProfileMigrator.cpp

1273 lines
46 KiB
C++

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** 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 The Browser Profile Migrator.
*
* The Initial Developer of the Original Code is Ben Goodger.
* Portions created by the Initial Developer are Copyright (C) 2004
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Ben Goodger <ben@bengoodger.com>
* Asaf Romano <mozilla.mano@sent.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 ***** */
#include "nsAppDirectoryServiceDefs.h"
#include "nsBrowserProfileMigratorUtils.h"
#include "nsDirectoryServiceDefs.h"
#include "nsDirectoryServiceUtils.h"
#include "nsDocShellCID.h"
#include "nsINavBookmarksService.h"
#include "nsBrowserCompsCID.h"
#include "nsIBrowserHistory.h"
#include "nsICookieManager2.h"
#include "nsIFileProtocolHandler.h"
#include "nsIFormHistory.h"
#include "nsIIOService.h"
#include "nsILocalFileMac.h"
#include "nsIObserverService.h"
#include "nsIPrefService.h"
#include "nsIProfileMigrator.h"
#include "nsIProtocolHandler.h"
#include "nsIRDFContainer.h"
#include "nsIRDFDataSource.h"
#include "nsIRDFRemoteDataSource.h"
#include "nsIRDFService.h"
#include "nsIServiceManager.h"
#include "nsIStringBundle.h"
#include "nsISupportsPrimitives.h"
#include "nsSafariProfileMigrator.h"
#include "nsToolkitCompsCID.h"
#include "nsNetUtil.h"
#include "nsTArray.h"
#include <Carbon/Carbon.h>
#define SAFARI_PREFERENCES_FILE_NAME NS_LITERAL_STRING("com.apple.Safari.plist")
#define SAFARI_BOOKMARKS_FILE_NAME NS_LITERAL_STRING("Bookmarks.plist")
#define SAFARI_HISTORY_FILE_NAME NS_LITERAL_STRING("History.plist")
#define SAFARI_COOKIES_FILE_NAME NS_LITERAL_STRING("Cookies.plist")
#define SAFARI_COOKIE_BEHAVIOR_FILE_NAME NS_LITERAL_STRING("com.apple.WebFoundation.plist")
#define SAFARI_DATE_OFFSET 978307200
#define SAFARI_HOME_PAGE_PREF "HomePage"
#define MIGRATION_BUNDLE "chrome://browser/locale/migration/migration.properties"
///////////////////////////////////////////////////////////////////////////////
// nsSafariProfileMigrator
NS_IMPL_ISUPPORTS1(nsSafariProfileMigrator, nsIBrowserProfileMigrator)
nsSafariProfileMigrator::nsSafariProfileMigrator()
{
mObserverService = do_GetService("@mozilla.org/observer-service;1");
}
nsSafariProfileMigrator::~nsSafariProfileMigrator()
{
}
///////////////////////////////////////////////////////////////////////////////
// nsIBrowserProfileMigrator
NS_IMETHODIMP
nsSafariProfileMigrator::Migrate(PRUint16 aItems, nsIProfileStartup* aStartup,
const PRUnichar* aProfile)
{
nsresult rv = NS_OK;
bool replace = false;
if (aStartup) {
replace = true;
rv = aStartup->DoStartup();
NS_ENSURE_SUCCESS(rv, rv);
}
NOTIFY_OBSERVERS(MIGRATION_STARTED, nsnull);
COPY_DATA(CopyPreferences, replace, nsIBrowserProfileMigrator::SETTINGS);
COPY_DATA(CopyCookies, replace, nsIBrowserProfileMigrator::COOKIES);
COPY_DATA(CopyHistory, replace, nsIBrowserProfileMigrator::HISTORY);
COPY_DATA(CopyBookmarks, replace, nsIBrowserProfileMigrator::BOOKMARKS);
COPY_DATA(CopyFormData, replace, nsIBrowserProfileMigrator::FORMDATA);
COPY_DATA(CopyOtherData, replace, nsIBrowserProfileMigrator::OTHERDATA);
NOTIFY_OBSERVERS(MIGRATION_ENDED, nsnull);
return rv;
}
NS_IMETHODIMP
nsSafariProfileMigrator::GetMigrateData(const PRUnichar* aProfile,
bool aReplace,
PRUint16* aResult)
{
*aResult = 0;
nsCOMPtr<nsIProperties> fileLocator(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID));
nsCOMPtr<nsILocalFile> safariSettingsDir, safariCookiesDir;
fileLocator->Get(NS_MAC_USER_LIB_DIR, NS_GET_IID(nsILocalFile),
getter_AddRefs(safariSettingsDir));
safariSettingsDir->Append(NS_LITERAL_STRING("Safari"));
fileLocator->Get(NS_MAC_USER_LIB_DIR, NS_GET_IID(nsILocalFile),
getter_AddRefs(safariCookiesDir));
safariCookiesDir->Append(NS_LITERAL_STRING("Cookies"));
// Safari stores most of its user settings under ~/Library/Safari/
MigrationData data[] = { { ToNewUnicode(SAFARI_HISTORY_FILE_NAME),
nsIBrowserProfileMigrator::HISTORY,
false },
{ ToNewUnicode(SAFARI_BOOKMARKS_FILE_NAME),
nsIBrowserProfileMigrator::BOOKMARKS,
false } };
// Frees file name strings allocated above.
GetMigrateDataFromArray(data, sizeof(data)/sizeof(MigrationData),
aReplace, safariSettingsDir, aResult);
// Safari stores Cookies under ~/Library/Cookies/Cookies.plist
MigrationData data2[] = { { ToNewUnicode(SAFARI_COOKIES_FILE_NAME),
nsIBrowserProfileMigrator::COOKIES,
false } };
GetMigrateDataFromArray(data2, sizeof(data2)/sizeof(MigrationData),
aReplace, safariCookiesDir, aResult);
// Safari stores Preferences under ~/Library/Preferences/
nsCOMPtr<nsILocalFile> systemPrefsDir;
fileLocator->Get(NS_OSX_USER_PREFERENCES_DIR, NS_GET_IID(nsILocalFile),
getter_AddRefs(systemPrefsDir));
MigrationData data3[]= { { ToNewUnicode(SAFARI_PREFERENCES_FILE_NAME),
nsIBrowserProfileMigrator::SETTINGS,
false } };
GetMigrateDataFromArray(data3, sizeof(data3)/sizeof(MigrationData),
aReplace, systemPrefsDir, aResult);
// Don't offer to import the Safari user style sheet if the active profile
// already has a content style sheet (userContent.css)
bool hasContentStylesheet = false;
if (NS_SUCCEEDED(ProfileHasContentStyleSheet(&hasContentStylesheet)) &&
!hasContentStylesheet) {
nsCOMPtr<nsILocalFile> safariUserStylesheetFile;
if (NS_SUCCEEDED(GetSafariUserStyleSheet(getter_AddRefs(safariUserStylesheetFile))))
*aResult |= nsIBrowserProfileMigrator::OTHERDATA;
}
// Don't offer to import that Safari form data if there isn't any
if (HasFormDataToImport())
*aResult |= nsIBrowserProfileMigrator::FORMDATA;
return NS_OK;
}
NS_IMETHODIMP
nsSafariProfileMigrator::GetSourceExists(bool* aResult)
{
PRUint16 data;
GetMigrateData(nsnull, false, &data);
*aResult = data != 0;
return NS_OK;
}
NS_IMETHODIMP
nsSafariProfileMigrator::GetSourceHasMultipleProfiles(bool* aResult)
{
// Safari only has one profile per-user.
*aResult = false;
return NS_OK;
}
NS_IMETHODIMP
nsSafariProfileMigrator::GetSourceProfiles(nsIArray** aResult)
{
*aResult = nsnull;
return NS_OK;
}
///////////////////////////////////////////////////////////////////////////////
// nsSafariProfileMigrator
CFPropertyListRef CopyPListFromFile(nsILocalFile* aPListFile)
{
bool exists;
aPListFile->Exists(&exists);
if (!exists)
return nsnull;
nsCAutoString filePath;
aPListFile->GetNativePath(filePath);
nsCOMPtr<nsILocalFileMac> macFile(do_QueryInterface(aPListFile));
CFURLRef urlRef;
macFile->GetCFURL(&urlRef);
// It is possible for CFURLCreateDataAndPropertiesFromResource to allocate resource
// data and then return a failure so be careful to check both and clean up properly.
SInt32 errorCode;
CFDataRef resourceData = NULL;
Boolean dataSuccess = ::CFURLCreateDataAndPropertiesFromResource(kCFAllocatorDefault,
urlRef,
&resourceData,
NULL,
NULL,
&errorCode);
CFPropertyListRef propertyList = NULL;
if (resourceData) {
if (dataSuccess) {
propertyList = ::CFPropertyListCreateFromXMLData(kCFAllocatorDefault,
resourceData,
kCFPropertyListImmutable,
NULL);
}
::CFRelease(resourceData);
}
::CFRelease(urlRef);
return propertyList;
}
CFDictionaryRef CopySafariPrefs()
{
nsCOMPtr<nsIProperties> fileLocator(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID));
nsCOMPtr<nsILocalFile> safariPrefsFile;
fileLocator->Get(NS_OSX_USER_PREFERENCES_DIR,
NS_GET_IID(nsILocalFile),
getter_AddRefs(safariPrefsFile));
safariPrefsFile->Append(SAFARI_PREFERENCES_FILE_NAME);
return static_cast<CFDictionaryRef>(CopyPListFromFile(safariPrefsFile));
}
char*
GetNullTerminatedString(CFStringRef aStringRef)
{
CFIndex bufferSize = ::CFStringGetLength(aStringRef) + 1;
char* buffer = (char*)malloc(sizeof(char) * bufferSize);
if (!buffer)
return nsnull;
if (::CFStringGetCString(aStringRef, buffer, bufferSize,
kCFStringEncodingASCII))
buffer[bufferSize-1] = '\0';
return buffer;
}
void
FreeNullTerminatedString(char* aString)
{
free(aString);
aString = nsnull;
}
bool
GetDictionaryStringValue(CFDictionaryRef aDictionary, CFStringRef aKey,
nsAString& aResult)
{
CFStringRef value = (CFStringRef)::CFDictionaryGetValue(aDictionary, aKey);
if (value) {
nsAutoTArray<UniChar, 1024> buffer;
CFIndex valueLength = ::CFStringGetLength(value);
buffer.SetLength(valueLength);
::CFStringGetCharacters(value, CFRangeMake(0, valueLength), buffer.Elements());
aResult.Assign(buffer.Elements(), valueLength);
return true;
}
return false;
}
bool
GetDictionaryCStringValue(CFDictionaryRef aDictionary, CFStringRef aKey,
nsACString& aResult, CFStringEncoding aEncoding)
{
CFStringRef value = (CFStringRef)::CFDictionaryGetValue(aDictionary, aKey);
if (value) {
nsAutoTArray<char, 1024> buffer;
CFIndex valueLength = ::CFStringGetLength(value);
buffer.SetLength(valueLength + 1);
if (::CFStringGetCString(value, buffer.Elements(), valueLength + 1, aEncoding)) {
aResult = buffer.Elements();
return true;
}
}
return false;
}
bool
GetArrayStringValue(CFArrayRef aArray, PRInt32 aIndex, nsAString& aResult)
{
CFStringRef value = (CFStringRef)::CFArrayGetValueAtIndex(aArray, aIndex);
if (value) {
nsAutoTArray<UniChar, 1024> buffer;
CFIndex valueLength = ::CFStringGetLength(value);
buffer.SetLength(valueLength);
::CFStringGetCharacters(value, CFRangeMake(0, valueLength), buffer.Elements());
aResult.Assign(buffer.Elements(), valueLength);
return true;
}
return false;
}
#define _SPM(type) nsSafariProfileMigrator::type
static
nsSafariProfileMigrator::PrefTransform gTransforms[] = {
{ CFSTR("AlwaysShowTabBar"), _SPM(BOOL), "browser.tabs.autoHide", _SPM(SetBoolInverted), false, { -1 } },
{ CFSTR("AutoFillPasswords"), _SPM(BOOL), "signon.rememberSignons", _SPM(SetBool), false, { -1 } },
{ CFSTR("OpenNewTabsInFront"), _SPM(BOOL), "browser.tabs.loadInBackground", _SPM(SetBoolInverted), false, { -1 } },
{ CFSTR("NSDefaultOpenDir"), _SPM(STRING), "browser.download.dir", _SPM(SetDownloadFolder), false, { -1 } },
{ CFSTR("AutoOpenSafeDownloads"), _SPM(BOOL), nsnull, _SPM(SetDownloadHandlers), false, { -1 } },
{ CFSTR("DownloadsClearingPolicy"), _SPM(INT), "browser.download.manager.retention", _SPM(SetDownloadRetention), false, { -1 } },
{ CFSTR("WebKitDefaultTextEncodingName"),_SPM(STRING), "intl.charset.default", _SPM(SetDefaultEncoding), false, { -1 } },
{ CFSTR("WebKitStandardFont"), _SPM(STRING), "font.name.serif.", _SPM(SetFontName), false, { -1 } },
{ CFSTR("WebKitDefaultFontSize"), _SPM(INT), "font.size.serif.", _SPM(SetFontSize), false, { -1 } },
{ CFSTR("WebKitFixedFont"), _SPM(STRING), "font.name.fixed.", _SPM(SetFontName), false, { -1 } },
{ CFSTR("WebKitDefaultFixedFontSize"), _SPM(INT), "font.size.fixed.", _SPM(SetFontSize), false, { -1 } },
{ CFSTR("WebKitMinimumFontSize"), _SPM(INT), "font.minimum-size.", _SPM(SetFontSize), false, { -1 } },
{ CFSTR("WebKitDisplayImagesKey"), _SPM(BOOL), "permissions.default.image", _SPM(SetDisplayImages), false, { -1 } },
{ CFSTR("WebKitJavaScriptEnabled"), _SPM(BOOL), "javascript.enabled", _SPM(SetBool), false, { -1 } },
{ CFSTR("WebKitJavaScriptCanOpenWindowsAutomatically"),
_SPM(BOOL), "dom.disable_open_during_load", _SPM(SetBoolInverted), false, { -1 } }
};
nsresult
nsSafariProfileMigrator::SetBool(void* aTransform, nsIPrefBranch* aBranch)
{
PrefTransform* xform = (PrefTransform*)aTransform;
return aBranch->SetBoolPref(xform->targetPrefName, xform->boolValue);
}
nsresult
nsSafariProfileMigrator::SetBoolInverted(void* aTransform, nsIPrefBranch* aBranch)
{
PrefTransform* xform = (PrefTransform*)aTransform;
return aBranch->SetBoolPref(xform->targetPrefName, !xform->boolValue);
}
nsresult
nsSafariProfileMigrator::SetString(void* aTransform, nsIPrefBranch* aBranch)
{
PrefTransform* xform = (PrefTransform*)aTransform;
return aBranch->SetCharPref(xform->targetPrefName, xform->stringValue);
}
nsresult
nsSafariProfileMigrator::SetInt(void* aTransform, nsIPrefBranch* aBranch)
{
PrefTransform* xform = (PrefTransform*)aTransform;
return aBranch->SetIntPref(xform->targetPrefName, !xform->intValue);
}
struct charsetEntry {
const char *webkitLabel;
size_t webkitLabelLength;
const char *mozLabel;
const char *associatedLangGroup;
};
static const charsetEntry gCharsets[] = {
#define CHARSET_ENTRY(charsetLabel, associatedLangGroup) \
{#charsetLabel, sizeof(#charsetLabel) - 1, #charsetLabel, #associatedLangGroup}
#define CHARSET_ENTRY2(webkitLabel, mozLabel, associatedLangGroup) \
{#webkitLabel, sizeof(#webkitLabel) - 1, #mozLabel, #associatedLangGroup}
CHARSET_ENTRY(ISO-8859-1,x-western),
CHARSET_ENTRY2(MACINTOSH,x-mac-roman,x-western),
// Since "x-unicode" in the font dialog means "Other Languages" (that is,
// languages which don't have their own script), we're picking the default
// font group - "Western".
CHARSET_ENTRY(UTF-8,x-western),
CHARSET_ENTRY2(SHIFT_JIS,Shift_JIS,ja),
CHARSET_ENTRY(ISO-2022-JP,ja),
CHARSET_ENTRY(EUC-JP,ja),
CHARSET_ENTRY2(BIG5,Big5,zh-TW),
CHARSET_ENTRY(CP950,zh-TW),
CHARSET_ENTRY(Big5-HKSCS,zh-HK),
CHARSET_ENTRY(ISO-2022-KR,ko),
// XXX: fallback to the generic Korean encoding
CHARSET_ENTRY2(X-MAC-KOREAN,ISO-2022-KR,ko),
CHARSET_ENTRY(CP949,ko),
CHARSET_ENTRY(ISO-8859-6,ar),
CHARSET_ENTRY2(WINDOWS-1256,windows-1256,ar),
CHARSET_ENTRY(ISO-8859-8,he),
CHARSET_ENTRY2(WINDOWS-1255,windows-1255,he),
CHARSET_ENTRY(ISO-8859-7,el),
CHARSET_ENTRY2(WINDOWS-1253,windows-1253,el),
CHARSET_ENTRY(ISO-8859-5,x-cyrillic),
CHARSET_ENTRY2(X-MAC-CYRILLIC,x-mac-cyrillic,x-cyrillic),
CHARSET_ENTRY(KOI8-R,x-cyrillic),
CHARSET_ENTRY2(WINDOWS-1251,windows-1251,x-cyrillic),
CHARSET_ENTRY(CP874,th),
CHARSET_ENTRY2(GB_2312-80,GB2312,zh-CN),
CHARSET_ENTRY(HZ-GB-2312,zh-CN),
CHARSET_ENTRY2(GB18030,gb18030,zh-CN),
CHARSET_ENTRY(ISO-8859-2,x-central-euro),
CHARSET_ENTRY2(X-MAC-CENTRALEURROMAN,x-mac-ce,x-central-euro),
CHARSET_ENTRY2(WINDOWS-1250,windows-1250,x-central-euro),
CHARSET_ENTRY(ISO-8859-4,x-central-euro),
CHARSET_ENTRY(ISO-8859-9,tr),
CHARSET_ENTRY2(WINDOWS-125,windows-1254,tr),
CHARSET_ENTRY2(WINDOWS-1257,windows-1257,x-baltic)
#undef CHARSET_ENTRY
#undef CHARSET_ENTRY2
};
nsresult
nsSafariProfileMigrator::SetDefaultEncoding(void* aTransform, nsIPrefBranch* aBranch)
{
PrefTransform* xform = (PrefTransform*)aTransform;
nsCAutoString associatedLangGroup;
nsDependentCString encoding(xform->stringValue);
PRUint32 encodingLength = encoding.Length();
const char* encodingStr = encoding.get();
PRInt16 charsetIndex = -1;
for (PRUint16 i = 0; (charsetIndex == -1) &&
i < (sizeof(gCharsets) / sizeof(gCharsets[0])); ++i) {
if (gCharsets[i].webkitLabelLength == encodingLength &&
!strcmp(gCharsets[i].webkitLabel, encodingStr))
charsetIndex = (PRInt16)i;
}
if (charsetIndex == -1) // Default to "Western"
charsetIndex = 0;
aBranch->SetCharPref(xform->targetPrefName, gCharsets[charsetIndex].mozLabel);
// We also want to use the default encoding for picking the default language
// in the fonts preferences dialog, and its associated preferences.
aBranch->SetCharPref("font.language.group",
gCharsets[charsetIndex].associatedLangGroup);
aBranch->SetCharPref("migration.associatedLangGroup",
gCharsets[charsetIndex].associatedLangGroup);
return NS_OK;
}
nsresult
nsSafariProfileMigrator::SetDownloadFolder(void* aTransform, nsIPrefBranch* aBranch)
{
PrefTransform* xform = (PrefTransform*)aTransform;
nsCOMPtr<nsILocalFile> downloadFolder;
nsresult rv = NS_NewNativeLocalFile(nsDependentCString(xform->stringValue),
true, getter_AddRefs(downloadFolder));
NS_ENSURE_SUCCESS(rv, rv);
// If the Safari download folder is the desktop, set the folderList pref
// appropriately so that "Desktop" is selected in the list in our Preferences
// UI instead of just the raw path being shown.
nsCOMPtr<nsIProperties> fileLocator(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID));
nsCOMPtr<nsILocalFile> desktopFolder;
fileLocator->Get(NS_OSX_USER_DESKTOP_DIR, NS_GET_IID(nsILocalFile),
getter_AddRefs(desktopFolder));
bool equals;
downloadFolder->Equals(desktopFolder, &equals);
aBranch->SetIntPref("browser.download.folderList", equals ? 0 : 2);
aBranch->SetComplexValue("browser.download.dir",
NS_GET_IID(nsILocalFile), downloadFolder);
return NS_OK;
}
nsresult
nsSafariProfileMigrator::SetDownloadHandlers(void* aTransform, nsIPrefBranch* aBranch)
{
PrefTransform* xform = (PrefTransform*)aTransform;
if (!xform->boolValue) {
// If we're not set to auto-open safe downloads, we need to clear out the
// mime types list which contains default handlers.
nsCOMPtr<nsIProperties> fileLocator(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID));
nsCOMPtr<nsILocalFile> mimeRegistryFile;
fileLocator->Get(NS_APP_USER_MIMETYPES_50_FILE, NS_GET_IID(nsILocalFile),
getter_AddRefs(mimeRegistryFile));
nsCOMPtr<nsIIOService> ioService(do_GetService("@mozilla.org/network/io-service;1"));
nsCOMPtr<nsIProtocolHandler> ph;
ioService->GetProtocolHandler("file", getter_AddRefs(ph));
nsCOMPtr<nsIFileProtocolHandler> fph(do_QueryInterface(ph));
nsCOMPtr<nsIRDFService> rdfService(do_GetService("@mozilla.org/rdf/rdf-service;1"));
nsCOMPtr<nsIRDFDataSource> mimeTypes;
nsCAutoString dsURL;
fph->GetURLSpecFromFile(mimeRegistryFile, dsURL);
rdfService->GetDataSourceBlocking(dsURL.get(), getter_AddRefs(mimeTypes));
nsCOMPtr<nsIRDFResource> overridesListResource;
rdfService->GetResource(NS_LITERAL_CSTRING("urn:mimetypes:root"),
getter_AddRefs(overridesListResource));
nsCOMPtr<nsIRDFContainer> overridesList(do_CreateInstance("@mozilla.org/rdf/container;1"));
overridesList->Init(mimeTypes, overridesListResource);
nsCOMPtr<nsIRDFResource> handlerPropArc, externalApplicationArc;
rdfService->GetResource(NC_URI(handlerProp), getter_AddRefs(handlerPropArc));
rdfService->GetResource(NC_URI(externalApplication),
getter_AddRefs(externalApplicationArc));
PRInt32 count;
overridesList->GetCount(&count);
for (PRInt32 i = count; i >= 1; --i) {
nsCOMPtr<nsIRDFNode> currOverrideNode;
overridesList->RemoveElementAt(i, false, getter_AddRefs(currOverrideNode));
nsCOMPtr<nsIRDFResource> currOverride(do_QueryInterface(currOverrideNode));
nsCOMPtr<nsIRDFNode> handlerPropNode;
mimeTypes->GetTarget(currOverride, handlerPropArc, true,
getter_AddRefs(handlerPropNode));
nsCOMPtr<nsIRDFResource> handlerPropResource(do_QueryInterface(handlerPropNode));
if (handlerPropResource) {
nsCOMPtr<nsIRDFNode> externalApplicationNode;
mimeTypes->GetTarget(handlerPropResource, externalApplicationArc,
true, getter_AddRefs(externalApplicationNode));
nsCOMPtr<nsIRDFResource> externalApplicationResource(do_QueryInterface(externalApplicationNode));
// Strip the resources down so that the datasource is completely flushed.
if (externalApplicationResource)
CleanResource(mimeTypes, externalApplicationResource);
CleanResource(mimeTypes, handlerPropResource);
}
CleanResource(mimeTypes, currOverride);
}
nsCOMPtr<nsIRDFRemoteDataSource> rds(do_QueryInterface(mimeTypes));
if (rds)
rds->Flush();
}
return NS_OK;
}
void
nsSafariProfileMigrator::CleanResource(nsIRDFDataSource* aDataSource,
nsIRDFResource* aResource)
{
nsCOMPtr<nsISimpleEnumerator> arcLabels;
aDataSource->ArcLabelsOut(aResource, getter_AddRefs(arcLabels));
if (!arcLabels)
return;
do {
bool hasMore;
arcLabels->HasMoreElements(&hasMore);
if (!hasMore)
break;
nsCOMPtr<nsIRDFResource> currArc;
arcLabels->GetNext(getter_AddRefs(currArc));
if (currArc) {
nsCOMPtr<nsIRDFNode> currTarget;
aDataSource->GetTarget(aResource, currArc, true,
getter_AddRefs(currTarget));
aDataSource->Unassert(aResource, currArc, currTarget);
}
}
while (1);
}
nsresult
nsSafariProfileMigrator::SetDownloadRetention(void* aTransform,
nsIPrefBranch* aBranch)
{
// Safari stores Download Retention in the opposite order of Firefox, namely:
// Retention Mode: Safari Firefox
// Remove Manually 0 2
// Remove on Exit 1 1
// Remove on DL Complete 2 0
PrefTransform* xform = (PrefTransform*)aTransform;
aBranch->SetIntPref(xform->targetPrefName,
xform->intValue == 0 ? 2 : xform->intValue == 2 ? 0 : 1);
return NS_OK;
}
nsresult
nsSafariProfileMigrator::SetDisplayImages(void* aTransform, nsIPrefBranch* aBranch)
{
// Firefox has an elaborate set of Image preferences. The correlation is:
// Mode: Safari Firefox
// Blocked FALSE 2
// Allowed TRUE 1
// Allowed, originating site only -- 3
PrefTransform* xform = (PrefTransform*)aTransform;
aBranch->SetIntPref(xform->targetPrefName, xform->boolValue ? 1 : 2);
return NS_OK;
}
nsresult
nsSafariProfileMigrator::SetFontName(void* aTransform, nsIPrefBranch* aBranch)
{
nsCString associatedLangGroup;
nsresult rv = aBranch->GetCharPref("migration.associatedLangGroup",
getter_Copies(associatedLangGroup));
if (NS_FAILED(rv))
return NS_OK;
PrefTransform* xform = (PrefTransform*)aTransform;
nsCAutoString prefName(xform->targetPrefName);
prefName.Append(associatedLangGroup);
return aBranch->SetCharPref(prefName.get(), xform->stringValue);
}
nsresult
nsSafariProfileMigrator::SetFontSize(void* aTransform, nsIPrefBranch* aBranch)
{
nsCString associatedLangGroup;
nsresult rv = aBranch->GetCharPref("migration.associatedLangGroup",
getter_Copies(associatedLangGroup));
if (NS_FAILED(rv))
return NS_OK;
PrefTransform* xform = (PrefTransform*)aTransform;
nsCAutoString prefName(xform->targetPrefName);
prefName.Append(associatedLangGroup);
return aBranch->SetIntPref(prefName.get(), xform->intValue);
}
nsresult
nsSafariProfileMigrator::CopyPreferences(bool aReplace)
{
nsCOMPtr<nsIPrefBranch> branch(do_GetService(NS_PREFSERVICE_CONTRACTID));
CFDictionaryRef safariPrefs = CopySafariPrefs();
if (!safariPrefs)
return NS_ERROR_FAILURE;
// Traverse the standard transforms
PrefTransform* transform;
PrefTransform* end = gTransforms +
sizeof(gTransforms) / sizeof(PrefTransform);
for (transform = gTransforms; transform < end; ++transform) {
Boolean hasValue = ::CFDictionaryContainsKey(safariPrefs, transform->keyName);
if (!hasValue)
continue;
transform->prefHasValue = false;
switch (transform->type) {
case _SPM(STRING): {
CFStringRef stringValue = (CFStringRef)
::CFDictionaryGetValue(safariPrefs,
transform->keyName);
char* value = GetNullTerminatedString(stringValue);
if (value) {
transform->stringValue = value;
transform->prefHasValue = true;
}
}
break;
case _SPM(INT): {
CFNumberRef intValue = (CFNumberRef)
::CFDictionaryGetValue(safariPrefs,
transform->keyName);
PRInt32 value = 0;
if (::CFNumberGetValue(intValue, kCFNumberSInt32Type, &value)) {
transform->intValue = value;
transform->prefHasValue = true;
}
}
break;
case _SPM(BOOL): {
CFBooleanRef boolValue = (CFBooleanRef)
::CFDictionaryGetValue(safariPrefs,
transform->keyName);
transform->boolValue = boolValue == kCFBooleanTrue;
transform->prefHasValue = true;
}
break;
default:
break;
}
if (transform->prefHasValue)
transform->prefSetterFunc(transform, branch);
if (transform->type == _SPM(STRING))
FreeNullTerminatedString(transform->stringValue);
}
::CFRelease(safariPrefs);
// Safari stores the Cookie "Accept/Don't Accept/Don't Accept Foreign" cookie
// setting in a separate WebFoundation preferences PList.
nsCOMPtr<nsIProperties> fileLocator(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID));
nsCOMPtr<nsILocalFile> safariWebFoundationPrefsFile;
fileLocator->Get(NS_OSX_USER_PREFERENCES_DIR, NS_GET_IID(nsILocalFile),
getter_AddRefs(safariWebFoundationPrefsFile));
safariWebFoundationPrefsFile->Append(SAFARI_COOKIE_BEHAVIOR_FILE_NAME);
CFDictionaryRef safariWebFoundationPrefs =
static_cast<CFDictionaryRef>(CopyPListFromFile(safariWebFoundationPrefsFile));
if (safariWebFoundationPrefs) {
// Mapping of Safari preference values to Firefox preference values:
//
// Setting Safari Firefox
// Always Accept always 0
// Accept from Originating current page 1
// Never Accept never 2
nsAutoString acceptCookies;
if (GetDictionaryStringValue(safariWebFoundationPrefs,
CFSTR("NSHTTPAcceptCookies"), acceptCookies)) {
PRInt32 cookieValue = 0;
if (acceptCookies.EqualsLiteral("never"))
cookieValue = 2;
else if (acceptCookies.EqualsLiteral("current page"))
cookieValue = 1;
branch->SetIntPref("network.cookie.cookieBehavior", cookieValue);
}
::CFRelease(safariWebFoundationPrefs);
}
return NS_OK;
}
nsresult
nsSafariProfileMigrator::CopyCookies(bool aReplace)
{
nsCOMPtr<nsIProperties> fileLocator(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID));
nsCOMPtr<nsILocalFile> safariCookiesFile;
fileLocator->Get(NS_MAC_USER_LIB_DIR,
NS_GET_IID(nsILocalFile),
getter_AddRefs(safariCookiesFile));
safariCookiesFile->Append(NS_LITERAL_STRING("Cookies"));
safariCookiesFile->Append(SAFARI_COOKIES_FILE_NAME);
CFArrayRef safariCookies = (CFArrayRef)CopyPListFromFile(safariCookiesFile);
if (!safariCookies)
return NS_OK;
nsCOMPtr<nsICookieManager2> cookieManager(do_GetService(NS_COOKIEMANAGER_CONTRACTID));
CFIndex count = ::CFArrayGetCount(safariCookies);
for (PRInt32 i = 0; i < count; ++i) {
CFDictionaryRef entry = (CFDictionaryRef)::CFArrayGetValueAtIndex(safariCookies, i);
CFDateRef date = (CFDateRef)::CFDictionaryGetValue(entry, CFSTR("Expires"));
nsCAutoString domain, path, name, value;
if (date &&
GetDictionaryCStringValue(entry, CFSTR("Domain"), domain,
kCFStringEncodingUTF8) &&
GetDictionaryCStringValue(entry, CFSTR("Path"), path,
kCFStringEncodingUTF8) &&
GetDictionaryCStringValue(entry, CFSTR("Name"), name,
kCFStringEncodingASCII) &&
GetDictionaryCStringValue(entry, CFSTR("Value"), value,
kCFStringEncodingASCII)) {
PRInt64 expiryTime;
LL_D2L(expiryTime, (double)::CFDateGetAbsoluteTime(date));
expiryTime += SAFARI_DATE_OFFSET;
cookieManager->Add(domain, path, name, value,
false, // isSecure
false, // isHttpOnly
false, // isSession
expiryTime);
}
}
::CFRelease(safariCookies);
return NS_OK;
}
NS_IMETHODIMP
nsSafariProfileMigrator::RunBatched(nsISupports* aUserData)
{
PRUint8 batchAction;
nsCOMPtr<nsISupportsPRUint8> strWrapper(do_QueryInterface(aUserData));
NS_ASSERTION(strWrapper, "Unable to create nsISupportsPRUint8 wrapper!");
nsresult rv = strWrapper->GetData(&batchAction);
NS_ENSURE_SUCCESS(rv, rv);
switch (batchAction) {
case BATCH_ACTION_HISTORY:
rv = CopyHistoryBatched(false);
break;
case BATCH_ACTION_HISTORY_REPLACE:
rv = CopyHistoryBatched(true);
break;
case BATCH_ACTION_BOOKMARKS:
rv = CopyBookmarksBatched(false);
break;
case BATCH_ACTION_BOOKMARKS_REPLACE:
rv = CopyBookmarksBatched(true);
break;
}
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
nsresult
nsSafariProfileMigrator::CopyHistory(bool aReplace)
{
nsresult rv;
nsCOMPtr<nsINavHistoryService> history =
do_GetService(NS_NAVHISTORYSERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
PRUint8 batchAction = aReplace ? BATCH_ACTION_HISTORY_REPLACE
: BATCH_ACTION_HISTORY;
nsCOMPtr<nsISupportsPRUint8> supports =
do_CreateInstance(NS_SUPPORTS_PRUINT8_CONTRACTID);
NS_ENSURE_TRUE(supports, NS_ERROR_OUT_OF_MEMORY);
rv = supports->SetData(batchAction);
NS_ENSURE_SUCCESS(rv, rv);
rv = history->RunInBatchMode(this, supports);
NS_ENSURE_SUCCESS(rv, rv);
return rv;
}
nsresult
nsSafariProfileMigrator::CopyHistoryBatched(bool aReplace)
{
nsCOMPtr<nsIProperties> fileLocator(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID));
nsCOMPtr<nsILocalFile> safariHistoryFile;
fileLocator->Get(NS_MAC_USER_LIB_DIR, NS_GET_IID(nsILocalFile),
getter_AddRefs(safariHistoryFile));
safariHistoryFile->Append(NS_LITERAL_STRING("Safari"));
safariHistoryFile->Append(SAFARI_HISTORY_FILE_NAME);
CFDictionaryRef safariHistory =
static_cast<CFDictionaryRef>(CopyPListFromFile(safariHistoryFile));
if (!safariHistory)
return NS_OK;
if (!::CFDictionaryContainsKey(safariHistory, CFSTR("WebHistoryDates"))) {
::CFRelease(safariHistory);
return NS_OK;
}
nsCOMPtr<nsIBrowserHistory> history(do_GetService(NS_GLOBALHISTORY2_CONTRACTID));
CFArrayRef children = (CFArrayRef)
::CFDictionaryGetValue(safariHistory, CFSTR("WebHistoryDates"));
if (children) {
CFIndex count = ::CFArrayGetCount(children);
for (PRInt32 i = 0; i < count; ++i) {
CFDictionaryRef entry = (CFDictionaryRef)::CFArrayGetValueAtIndex(children, i);
CFStringRef lastVisitedDate = (CFStringRef)
::CFDictionaryGetValue(entry, CFSTR("lastVisitedDate"));
nsAutoString url, title;
if (GetDictionaryStringValue(entry, CFSTR(""), url) &&
GetDictionaryStringValue(entry, CFSTR("title"), title) &&
lastVisitedDate) {
double lvd = ::CFStringGetDoubleValue(lastVisitedDate) + SAFARI_DATE_OFFSET;
PRTime lastVisitTime;
PRInt64 temp, million;
LL_D2L(temp, lvd);
LL_I2L(million, PR_USEC_PER_SEC);
LL_MUL(lastVisitTime, temp, million);
nsCOMPtr<nsIURI> uri;
NS_NewURI(getter_AddRefs(uri), url);
if (uri)
history->AddPageWithDetails(uri, title.get(), lastVisitTime);
}
}
}
::CFRelease(safariHistory);
return NS_OK;
}
nsresult
nsSafariProfileMigrator::CopyBookmarks(bool aReplace)
{
nsresult rv;
nsCOMPtr<nsINavBookmarksService> bookmarks =
do_GetService(NS_NAVBOOKMARKSSERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
PRUint8 batchAction = aReplace ? BATCH_ACTION_BOOKMARKS_REPLACE
: BATCH_ACTION_BOOKMARKS;
nsCOMPtr<nsISupportsPRUint8> supports =
do_CreateInstance(NS_SUPPORTS_PRUINT8_CONTRACTID);
NS_ENSURE_TRUE(supports, NS_ERROR_OUT_OF_MEMORY);
rv = supports->SetData(batchAction);
NS_ENSURE_SUCCESS(rv, rv);
rv = bookmarks->RunInBatchMode(this, supports);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
nsresult
nsSafariProfileMigrator::CopyBookmarksBatched(bool aReplace)
{
// If "aReplace" is true, merge into the root level of bookmarks. Otherwise, create
// a folder called "Imported Safari Favorites" and place all the Bookmarks there.
nsresult rv;
nsCOMPtr<nsINavBookmarksService> bms =
do_GetService(NS_NAVBOOKMARKSSERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
PRInt64 bookmarksMenuFolderId;
rv = bms->GetBookmarksMenuFolder(&bookmarksMenuFolderId);
NS_ENSURE_SUCCESS(rv, rv);
PRInt64 folder;
if (!aReplace) {
nsCOMPtr<nsIStringBundleService> bundleService =
do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIStringBundle> bundle;
rv = bundleService->CreateBundle(MIGRATION_BUNDLE, getter_AddRefs(bundle));
NS_ENSURE_SUCCESS(rv, rv);
nsString sourceNameSafari;
rv = bundle->GetStringFromName(NS_LITERAL_STRING("sourceNameSafari").get(),
getter_Copies(sourceNameSafari));
NS_ENSURE_SUCCESS(rv, rv);
const PRUnichar* sourceNameStrings[] = { sourceNameSafari.get() };
nsString importedSafariBookmarksTitle;
rv = bundle->FormatStringFromName(NS_LITERAL_STRING("importedBookmarksFolder").get(),
sourceNameStrings, 1,
getter_Copies(importedSafariBookmarksTitle));
NS_ENSURE_SUCCESS(rv, rv);
rv = bms->CreateFolder(bookmarksMenuFolderId,
NS_ConvertUTF16toUTF8(importedSafariBookmarksTitle),
nsINavBookmarksService::DEFAULT_INDEX, &folder);
NS_ENSURE_SUCCESS(rv, rv);
}
else {
nsCOMPtr<nsIFile> profile;
GetProfilePath(nsnull, profile);
rv = InitializeBookmarks(profile);
NS_ENSURE_SUCCESS(rv, rv);
// In replace mode we are merging at the top level.
folder = bookmarksMenuFolderId;
}
nsCOMPtr<nsIProperties> fileLocator(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID));
nsCOMPtr<nsILocalFile> safariBookmarksFile;
fileLocator->Get(NS_MAC_USER_LIB_DIR, NS_GET_IID(nsILocalFile),
getter_AddRefs(safariBookmarksFile));
safariBookmarksFile->Append(NS_LITERAL_STRING("Safari"));
safariBookmarksFile->Append(SAFARI_BOOKMARKS_FILE_NAME);
CFDictionaryRef safariBookmarks =
static_cast<CFDictionaryRef>(CopyPListFromFile(safariBookmarksFile));
if (!safariBookmarks)
return NS_OK;
// The Safari Bookmarks file looks like this:
// At the top level are all the Folders, Special Folders and Proxies. Proxies
// are references to other data sources such as History, Rendezvous etc.
// We ignore these. Special folders exist for the Bookmarks Toolbar folder
// (called "BookmarksBar" and the Bookmarks Menu (called "BookmarksMenu").
// We put the contents of the "BookmarksBar" folder into our Personal Toolbar
// and merge the contents of the "BookmarksMenu" folder and the other toplevel
// non-special folders under our NC:BookmarksRoot.
if (::CFDictionaryContainsKey(safariBookmarks, CFSTR("Children")) &&
::CFDictionaryContainsKey(safariBookmarks, CFSTR("WebBookmarkFileVersion")) ) {
CFNumberRef intValue =
(CFNumberRef)::CFDictionaryGetValue(safariBookmarks,
CFSTR("WebBookmarkFileVersion"));
PRInt32 value = 0;
if (::CFNumberGetValue(intValue, kCFNumberSInt32Type, &value) && value ==1) {
CFArrayRef children =
(CFArrayRef)::CFDictionaryGetValue(safariBookmarks, CFSTR("Children"));
if (children) {
rv = ParseBookmarksFolder(children, folder, bms, true);
}
}
}
::CFRelease(safariBookmarks);
return rv;
}
nsresult
nsSafariProfileMigrator::ParseBookmarksFolder(CFArrayRef aChildren,
PRInt64 aParentFolder,
nsINavBookmarksService * aBookmarksService,
bool aIsAtRootLevel)
{
nsresult rv = NS_OK;
CFIndex count = ::CFArrayGetCount(aChildren);
for (PRInt32 i = 0; i < count; ++i) {
CFDictionaryRef entry = (CFDictionaryRef)::CFArrayGetValueAtIndex(aChildren, i);
nsAutoString type;
if (!GetDictionaryStringValue(entry, CFSTR("WebBookmarkType"), type))
continue;
if (!type.EqualsLiteral("WebBookmarkTypeList") &&
!type.EqualsLiteral("WebBookmarkTypeLeaf"))
continue;
if (::CFDictionaryContainsKey(entry, CFSTR("Children")) &&
type.EqualsLiteral("WebBookmarkTypeList")) {
nsAutoString title;
if (!GetDictionaryStringValue(entry, CFSTR("Title"), title))
continue;
CFArrayRef children = (CFArrayRef)::CFDictionaryGetValue(entry,
CFSTR("Children"));
// Look for the BookmarksBar Bookmarks and add them into the appropriate
// Personal Toolbar Root
if (title.EqualsLiteral("BookmarksBar") && aIsAtRootLevel) {
PRInt64 toolbarFolder;
aBookmarksService->GetToolbarFolder(&toolbarFolder);
rv |= ParseBookmarksFolder(children,
toolbarFolder,
aBookmarksService,
false);
}
// Look for the BookmarksMenu Bookmarks and flatten them into the top level
else if (title.EqualsLiteral("BookmarksMenu") && aIsAtRootLevel) {
rv |= ParseBookmarksFolder(children,
aParentFolder,
aBookmarksService,
true);
}
else {
// Encountered a Folder, so create one in our Bookmarks DataSource and then
// parse the contents of the Safari one into it...
PRInt64 folder;
rv |= aBookmarksService->CreateFolder(aParentFolder, NS_ConvertUTF16toUTF8(title),
nsINavBookmarksService::DEFAULT_INDEX,
&folder);
rv |= ParseBookmarksFolder(children,
folder,
aBookmarksService,
false);
}
}
else if (type.EqualsLiteral("WebBookmarkTypeLeaf")) {
// Encountered a Bookmark, so add it to the current folder...
CFDictionaryRef URIDictionary = (CFDictionaryRef)
::CFDictionaryGetValue(entry, CFSTR("URIDictionary"));
nsAutoString title;
nsCAutoString url;
if (GetDictionaryStringValue(URIDictionary, CFSTR("title"), title) &&
GetDictionaryCStringValue(entry, CFSTR("URLString"), url, kCFStringEncodingUTF8)) {
nsCOMPtr<nsIURI> uri;
rv = NS_NewURI(getter_AddRefs(uri), url);
if (NS_SUCCEEDED(rv)) {
PRInt64 id;
rv = aBookmarksService->InsertBookmark(aParentFolder, uri,
nsINavBookmarksService::DEFAULT_INDEX,
NS_ConvertUTF16toUTF8(title), &id);
}
}
}
}
return rv;
}
// nsSafariProfileMigrator::HasFormDataToImport()
// if we add support for "~/Library/Safari/Form Values",
// keep in sync with CopyFormData()
// see bug #344284
bool
nsSafariProfileMigrator::HasFormDataToImport()
{
bool hasFormData = false;
// Safari stores this data in an array under the "RecentSearchStrings" key
// in its Preferences file.
CFDictionaryRef safariPrefs = CopySafariPrefs();
if (safariPrefs) {
if (::CFDictionaryContainsKey(safariPrefs, CFSTR("RecentSearchStrings")))
hasFormData = true;
::CFRelease(safariPrefs);
}
return hasFormData;
}
// nsSafariProfileMigrator::CopyFormData()
// if we add support for "~/Library/Safari/Form Values",
// keep in sync with HasFormDataToImport()
// see bug #344284
nsresult
nsSafariProfileMigrator::CopyFormData(bool aReplace)
{
nsresult rv = NS_ERROR_FAILURE;
CFDictionaryRef safariPrefs = CopySafariPrefs();
if (safariPrefs) {
// We lump saved Searches in with Form Data since that's how we store it.
// Safari stores this data in an array under the "RecentSearchStrings" key
// in its Preferences file.
Boolean hasSearchStrings = ::CFDictionaryContainsKey(safariPrefs,
CFSTR("RecentSearchStrings"));
if (hasSearchStrings) {
nsCOMPtr<nsIFormHistory2> formHistory(do_GetService("@mozilla.org/satchel/form-history;1"));
if (formHistory) {
CFArrayRef strings = (CFArrayRef)::CFDictionaryGetValue(safariPrefs,
CFSTR("RecentSearchStrings"));
if (strings) {
CFIndex count = ::CFArrayGetCount(strings);
for (PRInt32 i = 0; i < count; ++i) {
nsAutoString value;
GetArrayStringValue(strings, i, value);
formHistory->AddEntry(NS_LITERAL_STRING("searchbar-history"), value);
}
}
rv = NS_OK;
}
}
else
rv = NS_OK;
::CFRelease(safariPrefs);
}
return rv;
}
// Returns whether or not the active profile has a content style sheet
// (That is chrome/userContent.css)
nsresult
nsSafariProfileMigrator::ProfileHasContentStyleSheet(bool *outExists)
{
NS_ENSURE_ARG(outExists);
// Get the profile's chrome/ directory native path
nsCOMPtr<nsIFile> userChromeDir;
nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_CHROME_DIR,
getter_AddRefs(userChromeDir));
nsCAutoString userChromeDirPath;
rv = userChromeDir->GetNativePath(userChromeDirPath);
NS_ENSURE_SUCCESS(rv, rv);
nsCAutoString path(userChromeDirPath);
path.Append("/userContent.css");
nsCOMPtr<nsILocalFile> file;
rv = NS_NewNativeLocalFile(path, false,
getter_AddRefs(file));
NS_ENSURE_SUCCESS(rv, rv);
file->Exists(outExists);
return NS_OK;
}
nsresult
nsSafariProfileMigrator::GetSafariUserStyleSheet(nsILocalFile** aResult)
{
*aResult = nsnull;
CFDictionaryRef safariPrefs = CopySafariPrefs();
if (!safariPrefs)
return NS_ERROR_FAILURE;
nsresult rv = NS_ERROR_FAILURE;
// Check whether or not a user style sheet has been specified
if (::CFDictionaryContainsKey
(safariPrefs, CFSTR("WebKitUserStyleSheetEnabledPreferenceKey")) &&
::CFDictionaryContainsKey
(safariPrefs, CFSTR("WebKitUserStyleSheetLocationPreferenceKey"))) {
CFBooleanRef hasSheet = (CFBooleanRef)::CFDictionaryGetValue(safariPrefs,
CFSTR("WebKitUserStyleSheetEnabledPreferenceKey"));
if (hasSheet == kCFBooleanTrue) {
nsAutoString path;
// Get its path
if (GetDictionaryStringValue(safariPrefs,
CFSTR("WebKitUserStyleSheetLocation" \
"PreferenceKey"), path)) {
nsCOMPtr<nsILocalFile> file;
rv = NS_NewLocalFile(path, false, getter_AddRefs(file));
if (NS_SUCCEEDED(rv)) {
bool exists = false;
file->Exists(&exists);
if (exists) {
NS_ADDREF(*aResult = file);
rv = NS_OK;
}
else
rv = NS_ERROR_FILE_NOT_FOUND;
}
}
}
}
::CFRelease(safariPrefs);
return rv;
}
nsresult
nsSafariProfileMigrator::CopyOtherData(bool aReplace)
{
// Get the Safari user style sheet and copy it into the active profile's
// chrome folder
nsCOMPtr<nsILocalFile> stylesheetFile;
if (NS_SUCCEEDED(GetSafariUserStyleSheet(getter_AddRefs(stylesheetFile)))) {
nsCOMPtr<nsIFile> userChromeDir;
NS_GetSpecialDirectory(NS_APP_USER_CHROME_DIR,
getter_AddRefs(userChromeDir));
stylesheetFile->CopyTo(userChromeDir, NS_LITERAL_STRING("userContent.css"));
}
return NS_OK;
}
NS_IMETHODIMP
nsSafariProfileMigrator::GetSourceHomePageURL(nsACString& aResult)
{
aResult.Truncate();
// Let's first check if there's a home page key in the com.apple.safari file...
CFDictionaryRef safariPrefs = CopySafariPrefs();
if (safariPrefs) {
bool foundPref = GetDictionaryCStringValue(safariPrefs,
CFSTR(SAFARI_HOME_PAGE_PREF),
aResult, kCFStringEncodingUTF8);
::CFRelease(safariPrefs);
if (foundPref)
return NS_OK;
}
return NS_ERROR_FAILURE;
}