diff --git a/mozilla/modules/libpref/macbuild/libprefIDL.xml b/mozilla/modules/libpref/macbuild/libprefIDL.xml
index 0da53889069..b9bbf36b543 100644
--- a/mozilla/modules/libpref/macbuild/libprefIDL.xml
+++ b/mozilla/modules/libpref/macbuild/libprefIDL.xml
@@ -752,6 +752,13 @@
Text
+
+ Name
+ nsIRelativeFilePref.idl
+ MacOS
+ Text
+
+
@@ -784,6 +791,11 @@
nsIPrefService.idl
MacOS
+
+ Name
+ nsIRelativeFilePref.idl
+ MacOS
+
@@ -1485,6 +1497,13 @@
Text
+
+ Name
+ nsIRelativeFilePref.idl
+ MacOS
+ Text
+
+
@@ -1517,6 +1536,11 @@
nsIPrefService.idl
MacOS
+
+ Name
+ nsIRelativeFilePref.idl
+ MacOS
+
@@ -1563,6 +1587,12 @@
nsISecurityPref.idl
MacOS
+
+ headers
+ Name
+ nsIRelativeFilePref.idl
+ MacOS
+
diff --git a/mozilla/modules/libpref/public/Makefile.in b/mozilla/modules/libpref/public/Makefile.in
index 5a8f8e5e913..11442f2540e 100644
--- a/mozilla/modules/libpref/public/Makefile.in
+++ b/mozilla/modules/libpref/public/Makefile.in
@@ -35,6 +35,7 @@ XPIDLSRCS = \
nsIPrefLocalizedString.idl \
nsIPrefService.idl \
nsISecurityPref.idl \
+ nsIRelativeFilePref.idl \
$(NULL)
include $(topsrcdir)/config/rules.mk
diff --git a/mozilla/modules/libpref/public/makefile.win b/mozilla/modules/libpref/public/makefile.win
index 78d3e5e20da..3695655fd31 100644
--- a/mozilla/modules/libpref/public/makefile.win
+++ b/mozilla/modules/libpref/public/makefile.win
@@ -30,6 +30,7 @@ XPIDLSRCS = \
.\nsIPrefLocalizedString.idl \
.\nsIPrefService.idl \
.\nsISecurityPref.idl \
+ .\nsIRelativeFilePref.idl \
$(NULL)
include <$(DEPTH)\config\config.mak>
diff --git a/mozilla/modules/libpref/src/nsPrefBranch.cpp b/mozilla/modules/libpref/src/nsPrefBranch.cpp
index 82c8050e08f..9badeef0b78 100644
--- a/mozilla/modules/libpref/src/nsPrefBranch.cpp
+++ b/mozilla/modules/libpref/src/nsPrefBranch.cpp
@@ -41,6 +41,7 @@
#include "nsILocalFile.h"
#include "nsIObserverService.h"
#include "nsISupportsPrimitives.h"
+#include "nsIDirectoryService.h"
#include "nsString.h"
#include "nsReadableUtils.h"
#include "nsXPIDLString.h"
@@ -334,6 +335,44 @@ NS_IMETHODIMP nsPrefBranch::GetComplexValue(const char *aPrefName, const nsIID &
return rv;
}
+ if (aType.Equals(NS_GET_IID(nsIRelativeFilePref))) {
+ nsACString::const_iterator keyBegin, strEnd;
+ utf8String.BeginReading(keyBegin);
+ utf8String.EndReading(strEnd);
+
+ // The pref has the format: [fromKey]a/b/c
+ if (*keyBegin++ != '[')
+ return NS_ERROR_FAILURE;
+ nsACString::const_iterator keyEnd(keyBegin);
+ if (!FindCharInReadable(']', keyEnd, strEnd))
+ return NS_ERROR_FAILURE;
+ nsCAutoString key(Substring(keyBegin, keyEnd));
+
+ nsCOMPtr fromFile;
+ nsCOMPtr directoryService(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv));
+ if (NS_FAILED(rv))
+ return rv;
+ rv = directoryService->Get(key.get(), NS_GET_IID(nsILocalFile), getter_AddRefs(fromFile));
+ if (NS_FAILED(rv))
+ return rv;
+
+ nsCOMPtr theFile;
+ rv = NS_NewLocalFile(nsnull, PR_TRUE, getter_AddRefs(theFile));
+ if (NS_FAILED(rv))
+ return rv;
+ rv = theFile->SetRelativeDescriptor(fromFile, Substring(++keyEnd, strEnd));
+ if (NS_FAILED(rv))
+ return rv;
+ nsCOMPtr relativePref;
+ rv = NS_NewRelativeFilePref(theFile, key, getter_AddRefs(relativePref));
+ if (NS_FAILED(rv))
+ return rv;
+
+ *_retval = relativePref;
+ NS_ADDREF(NS_STATIC_CAST(nsIRelativeFilePref*, *_retval));
+ return NS_OK;
+ }
+
if (aType.Equals(NS_GET_IID(nsISupportsWString))) {
nsCOMPtr theString(do_CreateInstance(NS_SUPPORTS_WSTRING_CONTRACTID, &rv));
@@ -390,6 +429,39 @@ NS_IMETHODIMP nsPrefBranch::SetComplexValue(const char *aPrefName, const nsIID &
return rv;
}
+ if (aType.Equals(NS_GET_IID(nsIRelativeFilePref))) {
+ nsCOMPtr relFilePref = do_QueryInterface(aValue);
+ if (!relFilePref)
+ return NS_NOINTERFACE;
+
+ nsCOMPtr file;
+ relFilePref->GetFile(getter_AddRefs(file));
+ if (!file)
+ return NS_ERROR_FAILURE;
+ nsCAutoString relativeToKey;
+ (void) relFilePref->GetRelativeToKey(relativeToKey);
+
+ nsCOMPtr relativeToFile;
+ nsCOMPtr directoryService(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv));
+ if (NS_FAILED(rv))
+ return rv;
+ rv = directoryService->Get(relativeToKey.get(), NS_GET_IID(nsILocalFile), getter_AddRefs(relativeToFile));
+ if (NS_FAILED(rv))
+ return rv;
+
+ nsCAutoString relDescriptor;
+ rv = file->GetRelativeDescriptor(relativeToFile, relDescriptor);
+ if (NS_FAILED(rv))
+ return rv;
+
+ nsCAutoString descriptorString;
+ descriptorString.Append('[');
+ descriptorString.Append(relativeToKey);
+ descriptorString.Append(']');
+ descriptorString.Append(relDescriptor);
+ return SetCharPref(aPrefName, descriptorString.get());
+ }
+
if (aType.Equals(NS_GET_IID(nsISupportsWString))) {
nsCOMPtr theString = do_QueryInterface(aValue);
@@ -890,6 +962,9 @@ NS_IMETHODIMP nsPrefBranch::SecurityClearUserPref(const char *pref_name)
return _convertRes(PREF_ClearUserPref(getPrefName(pref_name)));
}
+//----------------------------------------------------------------------------
+// nsPrefLocalizedString
+//----------------------------------------------------------------------------
nsPrefLocalizedString::nsPrefLocalizedString()
: mUnicodeString(nsnull)
@@ -927,3 +1002,43 @@ nsresult nsPrefLocalizedString::Init()
return rv;
}
+//----------------------------------------------------------------------------
+// nsRelativeFilePref
+//----------------------------------------------------------------------------
+
+NS_IMPL_THREADSAFE_ISUPPORTS1(nsRelativeFilePref, nsIRelativeFilePref);
+
+nsRelativeFilePref::nsRelativeFilePref()
+{
+ NS_INIT_ISUPPORTS();
+}
+
+nsRelativeFilePref::~nsRelativeFilePref()
+{
+}
+
+NS_IMETHODIMP nsRelativeFilePref::GetFile(nsILocalFile * *aFile)
+{
+ NS_ENSURE_ARG_POINTER(aFile);
+ *aFile = mFile;
+ NS_IF_ADDREF(*aFile);
+ return *aFile ? NS_OK : NS_ERROR_NULL_POINTER;
+}
+
+NS_IMETHODIMP nsRelativeFilePref::SetFile(nsILocalFile * aFile)
+{
+ mFile = aFile;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsRelativeFilePref::GetRelativeToKey(nsACString& aRelativeToKey)
+{
+ aRelativeToKey.Assign(mRelativeToKey);
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsRelativeFilePref::SetRelativeToKey(const nsACString& aRelativeToKey)
+{
+ mRelativeToKey.Assign(aRelativeToKey);
+ return NS_OK;
+}
diff --git a/mozilla/modules/libpref/src/nsPrefBranch.h b/mozilla/modules/libpref/src/nsPrefBranch.h
index a031195b193..1f4b9a3e391 100644
--- a/mozilla/modules/libpref/src/nsPrefBranch.h
+++ b/mozilla/modules/libpref/src/nsPrefBranch.h
@@ -45,6 +45,8 @@
#include "nsISecurityPref.h"
#include "nsISupportsArray.h"
#include "nsISupportsPrimitives.h"
+#include "nsIRelativeFilePref.h"
+#include "nsILocalFile.h"
#include "nsString.h"
#include "nsVoidArray.h"
#include "nsWeakReference.h"
@@ -103,3 +105,18 @@ private:
nsCOMPtr mUnicodeString;
};
+
+class nsRelativeFilePref : public nsIRelativeFilePref
+{
+public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIRELATIVEFILEPREF
+
+ nsRelativeFilePref();
+ virtual ~nsRelativeFilePref();
+
+private:
+ nsCOMPtr mFile;
+ nsCAutoString mRelativeToKey; // An nsCAutoString because length is always very short.
+ // While this makes the object larger, avoids allocation.
+};
diff --git a/mozilla/modules/libpref/src/nsPrefsFactory.cpp b/mozilla/modules/libpref/src/nsPrefsFactory.cpp
index aa58f346033..45aa5038c0d 100644
--- a/mozilla/modules/libpref/src/nsPrefsFactory.cpp
+++ b/mozilla/modules/libpref/src/nsPrefsFactory.cpp
@@ -47,6 +47,7 @@ extern NS_IMETHODIMP nsPrefConstructor(nsISupports *aOuter, REFNSIID aIID, void
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPrefService, Init)
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPrefLocalizedString, Init)
+NS_GENERIC_FACTORY_CONSTRUCTOR(nsRelativeFilePref)
// The list of components we register
static const nsModuleComponentInfo components[] =
@@ -65,6 +66,13 @@ static const nsModuleComponentInfo components[] =
nsPrefLocalizedStringConstructor
},
+ {
+ NS_RELATIVEFILEPREF_CLASSNAME,
+ NS_RELATIVEFILEPREF_CID,
+ NS_RELATIVEFILEPREF_CONTRACTID,
+ nsRelativeFilePrefConstructor
+ },
+
{ // remove this when nsPref goes away
NS_PREF_CLASSNAME,
NS_PREF_CID,