Bug 723002 - Determine privacy status from provided nsILoadContext in ContentPrefService. r=ehsan

This commit is contained in:
Josh Matthews 2012-06-30 07:50:07 -07:00
parent 6d71829f1b
commit fcf5f9bfe7
29 changed files with 309 additions and 167 deletions

View File

@ -10,6 +10,15 @@
// From nsEventStateManager.cpp.
const MOUSE_SCROLL_ZOOM = 3;
Cu.import('resource://gre/modules/ContentPrefInstance.jsm');
function getContentPrefs(aWindow) {
let context = aWindow ? aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsILoadContext) : null;
return new ContentPrefInstance(context);
}
/**
* Controls the "full zoom" setting and its site-specific preferences.
*/
@ -21,7 +30,7 @@ var FullZoom = {
// when first requested, then updated by the pref change listener as it changes.
// If there is no global value, then this should be undefined.
get globalValue() {
var globalValue = Services.contentPrefs.getPref(null, this.name);
var globalValue = getContentPrefs(gBrowser.contentDocument.defaultView).getPref(null, this.name);
if (typeof globalValue != "undefined")
globalValue = this._ensureValid(globalValue);
delete this.globalValue;
@ -55,7 +64,7 @@ var FullZoom = {
window.addEventListener("DOMMouseScroll", this, false);
// Register ourselves with the service so we know when our pref changes.
Services.contentPrefs.addObserver(this.name, this);
getContentPrefs().addObserver(this.name, this);
this._siteSpecificPref =
gPrefService.getBoolPref("browser.zoom.siteSpecific");
@ -68,7 +77,7 @@ var FullZoom = {
destroy: function FullZoom_destroy() {
gPrefService.removeObserver("browser.zoom.", this);
Services.contentPrefs.removeObserver(this.name, this);
getContentPrefs().removeObserver(this.name, this);
window.removeEventListener("DOMMouseScroll", this, false);
},
@ -149,7 +158,8 @@ var FullZoom = {
// nsIContentPrefObserver
onContentPrefSet: function FullZoom_onContentPrefSet(aGroup, aName, aValue) {
if (aGroup == Services.contentPrefs.grouper.group(gBrowser.currentURI))
let contentPrefs = getContentPrefs(gBrowser.contentDocument.defaultView);
if (aGroup == contentPrefs.grouper.group(gBrowser.currentURI))
this._applyPrefToSetting(aValue);
else if (aGroup == null) {
this.globalValue = this._ensureValid(aValue);
@ -157,13 +167,14 @@ var FullZoom = {
// If the current page doesn't have a site-specific preference,
// then its zoom should be set to the new global preference now that
// the global preference has changed.
if (!Services.contentPrefs.hasPref(gBrowser.currentURI, this.name))
if (!contentPrefs.hasPref(gBrowser.currentURI, this.name))
this._applyPrefToSetting();
}
},
onContentPrefRemoved: function FullZoom_onContentPrefRemoved(aGroup, aName) {
if (aGroup == Services.contentPrefs.grouper.group(gBrowser.currentURI))
let contentPrefs = getContentPrefs(gBrowser.contentDocument.defaultView);
if (aGroup == contentPrefs.grouper.group(gBrowser.currentURI))
this._applyPrefToSetting();
else if (aGroup == null) {
this.globalValue = undefined;
@ -171,7 +182,7 @@ var FullZoom = {
// If the current page doesn't have a site-specific preference,
// then its zoom should be set to the default preference now that
// the global preference has changed.
if (!Services.contentPrefs.hasPref(gBrowser.currentURI, this.name))
if (!contentPrefs.hasPref(gBrowser.currentURI, this.name))
this._applyPrefToSetting();
}
},
@ -207,12 +218,13 @@ var FullZoom = {
return;
}
if (Services.contentPrefs.hasCachedPref(aURI, this.name)) {
let zoomValue = Services.contentPrefs.getPref(aURI, this.name);
let contentPrefs = getContentPrefs(gBrowser.contentDocument.defaultView);
if (contentPrefs.hasCachedPref(aURI, this.name)) {
let zoomValue = contentPrefs.getPref(aURI, this.name);
this._applyPrefToSetting(zoomValue, browser);
} else {
var self = this;
Services.contentPrefs.getPref(aURI, this.name, function (aResult) {
contentPrefs.getPref(aURI, this.name, function (aResult) {
// Check that we're still where we expect to be in case this took a while.
// Null check currentURI, since the window may have been destroyed before
// we were called.
@ -297,12 +309,12 @@ var FullZoom = {
return;
var zoomLevel = ZoomManager.zoom;
Services.contentPrefs.setPref(gBrowser.currentURI, this.name, zoomLevel);
getContentPrefs(gBrowser.contentDocument.defaultView).setPref(gBrowser.currentURI, this.name, zoomLevel);
},
_removePref: function FullZoom__removePref() {
if (!(content.document.mozSyntheticDocument))
Services.contentPrefs.removePref(gBrowser.currentURI, this.name);
getContentPrefs(gBrowser.contentDocument.defaultView).removePref(gBrowser.currentURI, this.name);
},

View File

@ -356,7 +356,7 @@ Sanitizer.prototype = {
// Clear site-specific settings like page-zoom level
var cps = Components.classes["@mozilla.org/content-pref/service;1"]
.getService(Components.interfaces.nsIContentPrefService);
cps.removeGroupedPrefs();
cps.removeGroupedPrefs(null);
// Clear "Never remember passwords for this site", which is not handled by
// the permission manager

View File

@ -114,7 +114,7 @@ function runTest() {
{ // check clearHistory removes all data
clearHistory();
is(gDownloadLastDir.file, null, "clearHistory removes all data");
is(Services.contentPrefs.hasPref(uri1, "browser.download.lastDir"), false, "LastDir preference should be absent");
is(Services.contentPrefs.hasPref(uri1, "browser.download.lastDir", null), false, "LastDir preference should be absent");
is(gDownloadLastDir.getFile(uri1), null, "uri1 should point to null");
is(gDownloadLastDir.getFile(uri2), null, "uri2 should point to null");
is(gDownloadLastDir.getFile(uri3), null, "uri3 should point to null");

View File

@ -275,7 +275,7 @@ nsHTMLInputElement::nsFilePickerShownCallback::Done(int16_t aResult)
if (!prefSaved) {
// Store the last used directory using the content pref service
nsHTMLInputElement::gUploadLastDir->StoreLastUsedDirectory(
mInput->OwnerDoc()->GetDocumentURI(), localFile);
mInput->OwnerDoc(), localFile);
prefSaved = true;
}
}
@ -293,7 +293,7 @@ nsHTMLInputElement::nsFilePickerShownCallback::Done(int16_t aResult)
newFiles.AppendObject(domFile);
// Store the last used directory using the content pref service
nsHTMLInputElement::gUploadLastDir->StoreLastUsedDirectory(
mInput->OwnerDoc()->GetDocumentURI(), localFile);
mInput->OwnerDoc(), localFile);
}
}
}
@ -410,7 +410,7 @@ nsHTMLInputElement::AsyncClickHandler::Run()
} else {
// Attempt to retrieve the last used directory from the content pref service
nsCOMPtr<nsIFile> localFile;
nsHTMLInputElement::gUploadLastDir->FetchLastUsedDirectory(doc->GetDocumentURI(),
nsHTMLInputElement::gUploadLastDir->FetchLastUsedDirectory(doc,
getter_AddRefs(localFile));
if (!localFile) {
// Default to "desktop" directory for each platform
@ -448,10 +448,17 @@ nsHTMLInputElement::DestroyUploadLastDir() {
}
nsresult
UploadLastDir::FetchLastUsedDirectory(nsIURI* aURI, nsIFile** aFile)
UploadLastDir::FetchLastUsedDirectory(nsIDocument* aDoc, nsIFile** aFile)
{
NS_PRECONDITION(aURI, "aURI is null");
NS_PRECONDITION(aDoc, "aDoc is null");
NS_PRECONDITION(aFile, "aFile is null");
nsIURI* docURI = aDoc->GetDocumentURI();
NS_PRECONDITION(docURI, "docURI is null");
nsCOMPtr<nsISupports> container = aDoc->GetContainer();
nsCOMPtr<nsILoadContext> loadContext = do_QueryInterface(container);
// Attempt to get the CPS, if it's not present we'll just return
nsCOMPtr<nsIContentPrefService> contentPrefService =
do_GetService(NS_CONTENT_PREF_SERVICE_CONTRACTID);
@ -460,13 +467,13 @@ UploadLastDir::FetchLastUsedDirectory(nsIURI* aURI, nsIFile** aFile)
nsCOMPtr<nsIWritableVariant> uri = do_CreateInstance(NS_VARIANT_CONTRACTID);
if (!uri)
return NS_ERROR_OUT_OF_MEMORY;
uri->SetAsISupports(aURI);
uri->SetAsISupports(docURI);
// Get the last used directory, if it is stored
bool hasPref;
if (NS_SUCCEEDED(contentPrefService->HasPref(uri, CPS_PREF_NAME, &hasPref)) && hasPref) {
if (NS_SUCCEEDED(contentPrefService->HasPref(uri, CPS_PREF_NAME, loadContext, &hasPref)) && hasPref) {
nsCOMPtr<nsIVariant> pref;
contentPrefService->GetPref(uri, CPS_PREF_NAME, nullptr, getter_AddRefs(pref));
contentPrefService->GetPref(uri, CPS_PREF_NAME, loadContext, nullptr, getter_AddRefs(pref));
nsString prefStr;
pref->GetAsAString(prefStr);
@ -480,10 +487,14 @@ UploadLastDir::FetchLastUsedDirectory(nsIURI* aURI, nsIFile** aFile)
}
nsresult
UploadLastDir::StoreLastUsedDirectory(nsIURI* aURI, nsIFile* aFile)
UploadLastDir::StoreLastUsedDirectory(nsIDocument* aDoc, nsIFile* aFile)
{
NS_PRECONDITION(aURI, "aURI is null");
NS_PRECONDITION(aDoc, "aDoc is null");
NS_PRECONDITION(aFile, "aFile is null");
nsCOMPtr<nsIURI> docURI = aDoc->GetDocumentURI();
NS_PRECONDITION(docURI, "docURI is null");
nsCOMPtr<nsIFile> parentFile;
aFile->GetParent(getter_AddRefs(parentFile));
if (!parentFile) {
@ -498,7 +509,7 @@ UploadLastDir::StoreLastUsedDirectory(nsIURI* aURI, nsIFile* aFile)
nsCOMPtr<nsIWritableVariant> uri = do_CreateInstance(NS_VARIANT_CONTRACTID);
if (!uri)
return NS_ERROR_OUT_OF_MEMORY;
uri->SetAsISupports(aURI);
uri->SetAsISupports(docURI);
// Find the parent of aFile, and store it
nsString unicodePath;
@ -509,7 +520,10 @@ UploadLastDir::StoreLastUsedDirectory(nsIURI* aURI, nsIFile* aFile)
if (!prefValue)
return NS_ERROR_OUT_OF_MEMORY;
prefValue->SetAsAString(unicodePath);
return contentPrefService->SetPref(uri, CPS_PREF_NAME, prefValue);
nsCOMPtr<nsISupports> container = aDoc->GetContainer();
nsCOMPtr<nsILoadContext> loadContext = do_QueryInterface(container);
return contentPrefService->SetPref(uri, CPS_PREF_NAME, prefValue, loadContext);
}
NS_IMETHODIMP
@ -519,7 +533,7 @@ UploadLastDir::Observe(nsISupports *aSubject, char const *aTopic, PRUnichar cons
nsCOMPtr<nsIContentPrefService> contentPrefService =
do_GetService(NS_CONTENT_PREF_SERVICE_CONTRACTID);
if (contentPrefService)
contentPrefService->RemovePrefsByName(CPS_PREF_NAME);
contentPrefService->RemovePrefsByName(CPS_PREF_NAME, nullptr);
}
return NS_OK;
}

View File

@ -35,10 +35,10 @@ public:
* Fetch the last used directory for this location from the content
* pref service, if it is available.
*
* @param aURI URI of the current page
* @param aDoc current document
* @param aFile path to the last used directory
*/
nsresult FetchLastUsedDirectory(nsIURI* aURI, nsIFile** aFile);
nsresult FetchLastUsedDirectory(nsIDocument* aDoc, nsIFile** aFile);
/**
* Store the last used directory for this location using the
@ -47,7 +47,7 @@ public:
* @param aFile file chosen by the user - the path to the parent of this
* file will be stored
*/
nsresult StoreLastUsedDirectory(nsIURI* aURI, nsIFile* aFile);
nsresult StoreLastUsedDirectory(nsIDocument* aDoc, nsIFile* aFile);
};
class nsHTMLInputElement : public nsGenericHTMLFormElement,

View File

@ -7,6 +7,7 @@
interface nsIVariant;
interface nsIPropertyBag2;
interface nsIContentURIGrouper;
interface nsILoadContext;
interface mozIStorageConnection;
[scriptable, uuid(746c7a02-f6c1-4869-b434-7c8b86e60e61)]
@ -38,7 +39,7 @@ interface nsIContentPrefCallback : nsISupports
void onResult(in nsIVariant aResult);
};
[scriptable, uuid(0014e2b4-1bab-4946-9211-7d28fc8df4d7)]
[scriptable, uuid(e3f772f3-023f-4b32-b074-36cf0fd5d414)]
interface nsIContentPrefService : nsISupports
{
/**
@ -57,6 +58,11 @@ interface nsIContentPrefService : nsISupports
* (typically in the format of a hostname), or null
* to get the global pref (applies to all sites)
* @param aName the name of the pref to get
* @param aPrivacyContext
* a context from which to determine the privacy status
* of the pref (ie. whether to search in memory or in
* permanent storage for it), obtained from a relevant
* window or channel.
* @param aCallback an optional nsIContentPrefCallback to receive the
* result. If desired, JavaScript callers can instead
* provide a function to call upon completion
@ -66,6 +72,7 @@ interface nsIContentPrefService : nsISupports
* @throws NS_ERROR_ILLEGAL_VALUE if aName is null or an empty string
*/
nsIVariant getPref(in nsIVariant aGroup, in AString aName,
in nsILoadContext aPrivacyContext,
[optional] in nsIContentPrefCallback aCallback);
/**
@ -80,10 +87,15 @@ interface nsIContentPrefService : nsISupports
* to set the global pref (applies to all sites)
* @param aName the name of the pref to set
* @param aValue the new value of the pref
* @param aPrivacyContext
* a context from which to determine the privacy status
* of the pref (ie. whether to store it in memory or in
* permanent storage), obtained from a relevant
* window or channel.
* @throws NS_ERROR_ILLEGAL_VALUE if aGroup is not a string, nsIURI, or null
* @throws NS_ERROR_ILLEGAL_VALUE if aName is null or an empty string
*/
void setPref(in nsIVariant aGroup, in AString aName, in nsIVariant aValue);
void setPref(in nsIVariant aGroup, in AString aName, in nsIVariant aValue, in nsILoadContext aPrivacyContext);
/**
* Check whether or not a pref exists.
@ -93,10 +105,15 @@ interface nsIContentPrefService : nsISupports
* (typically in the format of a hostname), or null
* to check for the global pref (applies to all sites)
* @param aName the name of the pref to check for
* @param aPrivacyContext
* a context from which to determine the privacy status
* of the pref (ie. whether to search in memory or in
* permanent storage for it), obtained from a relevant
* window or channel.
* @throws NS_ERROR_ILLEGAL_VALUE if aGroup is not a string, nsIURI, or null
* @throws NS_ERROR_ILLEGAL_VALUE if aName is null or an empty string
*/
boolean hasPref(in nsIVariant aGroup, in AString aName);
boolean hasPref(in nsIVariant aGroup, in AString aName, in nsILoadContext aContext);
/**
* Check whether or not the value of a pref (or its non-existance) is cached.
@ -106,10 +123,15 @@ interface nsIContentPrefService : nsISupports
* (typically in the format of a hostname), or null
* to check for the global pref (applies to all sites)
* @param aName the name of the pref to check for
* @param aPrivacyContext
* a context from which to determine the privacy status
* of the pref (ie. whether to search in memory or in
* permanent storage for it), obtained from a relevant
* window or channel.
* @throws NS_ERROR_ILLEGAL_VALUE if aGroup is not a string, nsIURI, or null
* @throws NS_ERROR_ILLEGAL_VALUE if aName is null or an empty string
*/
boolean hasCachedPref(in nsIVariant aGroup, in AString aName);
boolean hasCachedPref(in nsIVariant aGroup, in AString aName, in nsILoadContext aContext);
/**
* Remove a pref.
@ -119,24 +141,40 @@ interface nsIContentPrefService : nsISupports
* (typically in the format of a hostname), or null
* to remove the global pref (applies to all sites)
* @param aName the name of the pref to remove
* @param aPrivacyContext
* a context from which to determine the privacy status
* of the pref (ie. whether to search in memory or in
* permanent storage for it), obtained from a relevant
* window or channel.
* @throws NS_ERROR_ILLEGAL_VALUE if aGroup is not a string, nsIURI, or null
* @throws NS_ERROR_ILLEGAL_VALUE if aName is null or an empty string
*/
void removePref(in nsIVariant aGroup, in AString aName);
void removePref(in nsIVariant aGroup, in AString aName, in nsILoadContext aContext);
/**
* Remove all grouped prefs. Useful for removing references to the sites
* the user has visited when the user clears their private data.
*
* @param aPrivacyContext
* a context from which to determine the privacy status
* of the pref (ie. whether to remove prefs in memory or
* in permanent storage), obtained from a relevant
* window or channel.
*/
void removeGroupedPrefs();
void removeGroupedPrefs(in nsILoadContext aContext);
/**
* Remove all prefs with the given name.
*
* @param aName the setting name for which to remove prefs
* @param aPrivacyContext
* a context from which to determine the privacy status
* of the prefs (ie. whether to remove prefs in memory or
* in permanent storage), obtained from a relevant
* window or channel.
* @throws NS_ERROR_ILLEGAL_VALUE if aName is null or an empty string
*/
void removePrefsByName(in AString aName);
void removePrefsByName(in AString aName, in nsILoadContext aContext);
/**
* Get the prefs that apply to the given site.
@ -145,21 +183,31 @@ interface nsIContentPrefService : nsISupports
* from which the hostname will be used, a string
* (typically in the format of a hostname), or null
* to get the global prefs (apply to all sites)
* @param aPrivacyContext
* a context from which to determine the privacy status
* of the pref (ie. whether to search for prefs in memory
* or in permanent storage), obtained from a relevant
* window or channel.
*
* @returns a property bag of prefs
* @throws NS_ERROR_ILLEGAL_VALUE if aGroup is not a string, nsIURI, or null
*/
nsIPropertyBag2 getPrefs(in nsIVariant aGroup);
nsIPropertyBag2 getPrefs(in nsIVariant aGroup, in nsILoadContext aContext);
/**
* Get the prefs with the given name.
*
* @param aName the setting name for which to retrieve prefs
* @param aPrivacyContext
* a context from which to determine the privacy status
* of the pref (ie. whether to search for prefs in memory
* or in permanent storage), obtained from a relevant
* window or channel.
*
* @returns a property bag of prefs
* @throws NS_ERROR_ILLEGAL_VALUE if aName is null or an empty string
*/
nsIPropertyBag2 getPrefsByName(in AString aName);
nsIPropertyBag2 getPrefsByName(in AString aName, in nsILoadContext aContext);
/**
* Add an observer.

View File

@ -25,6 +25,7 @@
#include "nsIDocument.h" // for nsIDocument
#include "nsIEditor.h" // for nsIEditor
#include "nsIHTMLEditor.h" // for nsIHTMLEditor
#include "nsILoadContext.h"
#include "nsISelection.h" // for nsISelection
#include "nsISpellChecker.h" // for nsISpellChecker, etc
#include "nsISupportsBase.h" // for nsISupports
@ -108,6 +109,21 @@ LastDictionary::GetDocumentURI(nsIEditor* aEditor, nsIURI * *aURI)
return NS_OK;
}
static already_AddRefed<nsILoadContext>
GetLoadContext(nsIEditor* aEditor)
{
nsCOMPtr<nsIDOMDocument> domDoc;
aEditor->GetDocument(getter_AddRefs(domDoc));
NS_ENSURE_TRUE(domDoc, nullptr);
nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
NS_ENSURE_TRUE(doc, nullptr);
nsCOMPtr<nsISupports> container = doc->GetContainer();
nsCOMPtr<nsILoadContext> loadContext = do_QueryInterface(container);
return loadContext.forget();
}
NS_IMETHODIMP
LastDictionary::FetchLastDictionary(nsIEditor* aEditor, nsAString& aDictionary)
{
@ -127,10 +143,11 @@ LastDictionary::FetchLastDictionary(nsIEditor* aEditor, nsAString& aDictionary)
NS_ENSURE_TRUE(uri, NS_ERROR_OUT_OF_MEMORY);
uri->SetAsISupports(docUri);
nsCOMPtr<nsILoadContext> loadContext = GetLoadContext(aEditor);
bool hasPref;
if (NS_SUCCEEDED(contentPrefService->HasPref(uri, CPS_PREF_NAME, &hasPref)) && hasPref) {
if (NS_SUCCEEDED(contentPrefService->HasPref(uri, CPS_PREF_NAME, loadContext, &hasPref)) && hasPref) {
nsCOMPtr<nsIVariant> pref;
contentPrefService->GetPref(uri, CPS_PREF_NAME, nullptr, getter_AddRefs(pref));
contentPrefService->GetPref(uri, CPS_PREF_NAME, loadContext, nullptr, getter_AddRefs(pref));
pref->GetAsAString(aDictionary);
} else {
aDictionary.Truncate();
@ -162,7 +179,8 @@ LastDictionary::StoreCurrentDictionary(nsIEditor* aEditor, const nsAString& aDic
do_GetService(NS_CONTENT_PREF_SERVICE_CONTRACTID);
NS_ENSURE_TRUE(contentPrefService, NS_ERROR_NOT_INITIALIZED);
return contentPrefService->SetPref(uri, CPS_PREF_NAME, prefValue);
nsCOMPtr<nsILoadContext> loadContext = GetLoadContext(aEditor);
return contentPrefService->SetPref(uri, CPS_PREF_NAME, prefValue, loadContext);
}
NS_IMETHODIMP
@ -184,7 +202,8 @@ LastDictionary::ClearCurrentDictionary(nsIEditor* aEditor)
do_GetService(NS_CONTENT_PREF_SERVICE_CONTRACTID);
NS_ENSURE_TRUE(contentPrefService, NS_ERROR_NOT_INITIALIZED);
return contentPrefService->RemovePref(uri, CPS_PREF_NAME);
nsCOMPtr<nsILoadContext> loadContext = GetLoadContext(aEditor);
return contentPrefService->RemovePref(uri, CPS_PREF_NAME, loadContext);
}
LastDictionary* nsEditorSpellCheck::gDictionaryStore = nullptr;

View File

@ -5834,11 +5834,13 @@ var PermissionsHelper = {
case "Permissions:Clear":
// An array of the indices of the permissions we want to clear
let permissionsToClear = JSON.parse(aData);
let privacyContext = BrowserApp.selectedBrowser.docShell
.QueryInterface(Ci.nsILoadContext);
for (let i = 0; i < permissionsToClear.length; i++) {
let indexToClear = permissionsToClear[i];
let permissionType = this._currentPermissions[indexToClear]["type"];
this.clearPermission(uri, permissionType);
this.clearPermission(uri, permissionType, privacyContext);
}
break;
}
@ -5883,7 +5885,7 @@ var PermissionsHelper = {
* The permission type string stored in permission manager.
* e.g. "geolocation", "indexedDB", "popup"
*/
clearPermission: function clearPermission(aURI, aType) {
clearPermission: function clearPermission(aURI, aType, aContext) {
// Password saving isn't a nsIPermissionManager permission type, so handle
// it seperately.
if (aType == "password") {
@ -5897,7 +5899,7 @@ var PermissionsHelper = {
} else {
Services.perms.remove(aURI.host, aType);
// Clear content prefs set in ContentPermissionPrompt.js
Services.contentPrefs.removePref(aURI, aType + ".request.remember");
Services.contentPrefs.removePref(aURI, aType + ".request.remember", aContext);
}
}
};

View File

@ -101,7 +101,7 @@ Sanitizer.prototype = {
Services.perms.removeAll();
// Clear site-specific settings like page-zoom level
Services.contentPrefs.removeGroupedPrefs();
Services.contentPrefs.removeGroupedPrefs(null);
// Clear "Never remember passwords for this site", which is not handled by
// the permission manager

View File

@ -26,6 +26,8 @@ function Preferences(args) {
this._defaultBranch = args.defaultBranch;
if (args.site)
this._site = args.site;
if (args.privacyContext)
this._privacyContext = args.privacyContext;
}
else if (args)
this._prefBranch = args;
@ -76,7 +78,7 @@ Preferences.prototype = {
},
_siteGet: function(prefName, defaultValue) {
let value = this._contentPrefSvc.getPref(this._site, this._prefBranch + prefName);
let value = this._contentPrefSvc.getPref(this._site, this._prefBranch + prefName, this._privacyContext);
return typeof value != "undefined" ? value : defaultValue;
},
@ -160,7 +162,7 @@ Preferences.prototype = {
},
_siteSet: function(prefName, prefValue) {
this._contentPrefSvc.setPref(this._site, this._prefBranch + prefName, prefValue);
this._contentPrefSvc.setPref(this._site, this._prefBranch + prefName, prefValue, this._privacyContext);
},
/**
@ -192,7 +194,7 @@ Preferences.prototype = {
},
_siteHas: function(prefName) {
return this._contentPrefSvc.hasPref(this._site, this._prefBranch + prefName);
return this._contentPrefSvc.hasPref(this._site, this._prefBranch + prefName, this._privacyContext);
},
/**
@ -253,7 +255,7 @@ Preferences.prototype = {
},
_siteReset: function(prefName) {
return this._contentPrefSvc.removePref(this._site, this._prefBranch + prefName);
return this._contentPrefSvc.removePref(this._site, this._prefBranch + prefName, this._privacyContext);
},
/**
@ -387,10 +389,10 @@ Preferences.prototype = {
*/
_prefBranch: "",
site: function(site) {
site: function(site, privacyContext) {
if (!(site instanceof Ci.nsIURI))
site = this._ioSvc.newURI("http://" + site, null, null);
return new Preferences({ branch: this._prefBranch, site: site });
return new Preferences({ branch: this._prefBranch, site: site, privacyContext: privacyContext });
},
/**

View File

@ -358,7 +358,7 @@ add_test(function test_lock_prefs() {
*/
add_test(function test_site_prefs() {
let prefs = Preferences.site("www.example.com");
let prefs = Preferences.site("www.example.com", null);
prefs.set("test_site_prefs.integer", 1);
do_check_eq(prefs.get("test_site_prefs.integer"), 1);

View File

@ -0,0 +1,74 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
'use strict';
const Cc = Components.classes;
const Ci = Components.interfaces;
var EXPORTED_SYMBOLS = ['ContentPrefInstance'];
// This is a wrapper for nsIContentPrefService that alleviates the need to pass
// an nsILoadContext argument to every method. Pass the context to the constructor
// instead and continue on your way in blissful ignorance.
function ContentPrefInstance(aContext) {
this._contentPrefSvc = Cc["@mozilla.org/content-pref/service;1"].
getService(Ci.nsIContentPrefService);
this._context = aContext;
}
ContentPrefInstance.prototype = {
getPref: function ContentPrefInstance_init(aName, aGroup, aCallback) {
return this._contentPrefSvc.getPref(aName, aGroup, this._context, aCallback);
},
setPref: function ContentPrefInstance_setPref(aGroup, aName, aValue) {
return this._contentPrefSvc.setPref(aGroup, aName, aValue, this._context);
},
hasPref: function ContentPrefInstance_hasPref(aGroup, aName) {
return this._contentPrefSvc.hasPref(aGroup, aName, this._context);
},
hasCachedPref: function ContentPrefInstance_hasCachedPref(aGroup, aName) {
return this._contentPrefSvc.hasCachedPref(aGroup, aName, this._context);
},
removePref: function ContentPrefInstance_removePref(aGroup, aName) {
return this._contentPrefSvc.removePref(aGroup, aName, this._context);
},
removeGroupedPrefs: function ContentPrefInstance_removeGroupedPrefs() {
return this._contentPrefSvc.removeGroupedPrefs(this._context);
},
removePrefsByName: function ContentPrefInstance_removePrefsByName(aName) {
return this._contentPrefSvc.removePrefsByName(aName, this._context);
},
getPrefs: function ContentPrefInstance_getPrefs(aGroup) {
return this._contentPrefSvc.getPrefs(aGroup, this._context);
},
getPrefsByName: function ContentPrefInstance_getPrefsByName(aName) {
return this._contentPrefSvc.getPrefsByName(aName, this._context);
},
addObserver: function ContentPrefInstance_addObserver(aName, aObserver) {
return this._contentPrefSvc.addObserver(aName, aObserver);
},
removeObserver: function ContentPrefInstance_removeObserver(aName, aObserver) {
return this._contentPrefSvc.removeObserver(aName, aObserver);
},
get grouper() {
return this._contentPrefSvc.grouper;
},
get DBConnection() {
return this._contentPrefSvc.DBConnection;
}
};

View File

@ -13,6 +13,8 @@ MODULE = contentprefs
EXTRA_COMPONENTS = nsContentPrefService.js nsContentPrefService.manifest
EXTRA_JS_MODULES = ContentPrefInstance.jsm
TEST_DIRS += tests
include $(topsrcdir)/config/rules.mk

View File

@ -100,15 +100,7 @@ function ContentPrefService() {
// was due to a temporary condition (like being out of disk space).
this._dbInit();
// detect if we are in private browsing mode
this._inPrivateBrowsing = false;
// The Private Browsing service might not be available.
if (["@mozilla.org/privatebrowsing;1"] in Cc) {
var pbs = Cc["@mozilla.org/privatebrowsing;1"].
getService(Ci.nsIPrivateBrowsingService);
this._inPrivateBrowsing = pbs.privateBrowsingEnabled;
}
this._observerSvc.addObserver(this, "private-browsing", false);
this._observerSvc.addObserver(this, "last-pb-context-exited", false);
// Observe shutdown so we can shut down the database connection.
this._observerSvc.addObserver(this, "xpcom-shutdown", false);
@ -165,7 +157,7 @@ ContentPrefService.prototype = {
//**************************************************************************//
// XPCOM Plumbing
classID: Components.ID("{e6a3f533-4ffa-4615-8eb4-d4e72d883fa7}"),
classID: Components.ID("{e3f772f3-023f-4b32-b074-36cf0fd5d414}"),
QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPrefService,
Ci.nsIMessageListener]),
@ -206,7 +198,7 @@ ContentPrefService.prototype = {
_destroy: function ContentPrefService__destroy() {
this._observerSvc.removeObserver(this, "xpcom-shutdown");
this._observerSvc.removeObserver(this, "private-browsing");
this._observerSvc.removeObserver(this, "last-pb-context-exited");
// Finalize statements which may have been used asynchronously.
// FIXME(696499): put them in an object cache like other components.
@ -293,16 +285,8 @@ ContentPrefService.prototype = {
case "xpcom-shutdown":
this._destroy();
break;
case "private-browsing":
switch (data) {
case "enter":
this._inPrivateBrowsing = true;
break;
case "exit":
this._inPrivateBrowsing = false;
this._privModeStorage.invalidate();
break;
}
case "last-pb-context-exited":
this._privModeStorage.invalidate();
break;
}
},
@ -394,14 +378,14 @@ ContentPrefService.prototype = {
//**************************************************************************//
// nsIContentPrefService
getPref: function ContentPrefService_getPref(aGroup, aName, aCallback) {
getPref: function ContentPrefService_getPref(aGroup, aName, aContext, aCallback) {
if (!aName)
throw Components.Exception("aName cannot be null or an empty string",
Cr.NS_ERROR_ILLEGAL_VALUE);
var group = this._parseGroupParam(aGroup);
if (this._inPrivateBrowsing) {
if (aContext && aContext.usePrivateBrowsing) {
let [haspref, value] = this._privModeStorage.getPref(aName, group);
if (haspref) {
if (aCallback) {
@ -419,9 +403,9 @@ ContentPrefService.prototype = {
return this._selectPref(group, aName, aCallback);
},
setPref: function ContentPrefService_setPref(aGroup, aName, aValue) {
setPref: function ContentPrefService_setPref(aGroup, aName, aValue, aContext) {
// If the pref is already set to the value, there's nothing more to do.
var currentValue = this.getPref(aGroup, aName);
var currentValue = this.getPref(aGroup, aName, aContext);
if (typeof currentValue != "undefined") {
if (currentValue == aValue)
return;
@ -429,7 +413,7 @@ ContentPrefService.prototype = {
var group = this._parseGroupParam(aGroup);
if (this._inPrivateBrowsing) {
if (aContext && aContext.usePrivateBrowsing) {
this._privModeStorage.setPref(aName, aValue, group);
this._notifyPrefSet(group, aName, aValue);
return;
@ -457,31 +441,31 @@ ContentPrefService.prototype = {
this._notifyPrefSet(group, aName, aValue);
},
hasPref: function ContentPrefService_hasPref(aGroup, aName) {
hasPref: function ContentPrefService_hasPref(aGroup, aName, aContext) {
// XXX If consumers end up calling this method regularly, then we should
// optimize this to query the database directly.
return (typeof this.getPref(aGroup, aName) != "undefined");
return (typeof this.getPref(aGroup, aName, aContext) != "undefined");
},
hasCachedPref: function ContentPrefService_hasCachedPref(aGroup, aName) {
hasCachedPref: function ContentPrefService_hasCachedPref(aGroup, aName, aContext) {
if (!aName)
throw Components.Exception("aName cannot be null or an empty string",
Cr.NS_ERROR_ILLEGAL_VALUE);
let group = this._parseGroupParam(aGroup);
let storage = this._inPrivateBrowsing? this._privModeStorage: this._cache;
let storage = aContext && aContext.usePrivateBrowsing ? this._privModeStorage: this._cache;
let [cached,] = storage.getPref(aName, group);
return cached;
},
removePref: function ContentPrefService_removePref(aGroup, aName) {
removePref: function ContentPrefService_removePref(aGroup, aName, aContext) {
// If there's no old value, then there's nothing to remove.
if (!this.hasPref(aGroup, aName))
if (!this.hasPref(aGroup, aName, aContext))
return;
var group = this._parseGroupParam(aGroup);
if (this._inPrivateBrowsing) {
if (aContext && aContext.usePrivateBrowsing) {
this._privModeStorage.removePref(aName, group);
this._notifyPrefRemoved(group, aName);
return;
@ -509,9 +493,9 @@ ContentPrefService.prototype = {
this._notifyPrefRemoved(group, aName);
},
removeGroupedPrefs: function ContentPrefService_removeGroupedPrefs() {
removeGroupedPrefs: function ContentPrefService_removeGroupedPrefs(aContext) {
// will not delete global preferences
if (this._inPrivateBrowsing) {
if (aContext && aContext.usePrivateBrowsing) {
// keep only global prefs
this._privModeStorage.invalidate(true);
}
@ -532,12 +516,12 @@ ContentPrefService.prototype = {
}
},
removePrefsByName: function ContentPrefService_removePrefsByName(aName) {
removePrefsByName: function ContentPrefService_removePrefsByName(aName, aContext) {
if (!aName)
throw Components.Exception("aName cannot be null or an empty string",
Cr.NS_ERROR_ILLEGAL_VALUE);
if (this._inPrivateBrowsing) {
if (aContext && aContext.usePrivateBrowsing) {
let groupNames = this._privModeStorage.groupsForName(aName);
for (var i = 0; i < groupNames.length; i++) {
let groupName = groupNames[i];
@ -582,15 +566,15 @@ ContentPrefService.prototype = {
this._cache.removePref(aName, groupNames[i]);
if (groupNames[i]) // ie. not null, which will be last (and i == groupIDs.length)
this._deleteGroupIfUnused(groupIDs[i]);
if (!this._inPrivateBrowsing) {
if (!aContext || !aContext.usePrivateBrowsing) {
this._notifyPrefRemoved(groupNames[i], aName);
}
}
},
getPrefs: function ContentPrefService_getPrefs(aGroup) {
getPrefs: function ContentPrefService_getPrefs(aGroup, aContext) {
var group = this._parseGroupParam(aGroup);
if (this._inPrivateBrowsing) {
if (aContext && aContext.usePrivateBrowsing) {
let prefs = Cc["@mozilla.org/hash-property-bag;1"].
createInstance(Ci.nsIWritablePropertyBag);
let [hasbranch,properties] = this._privModeStorage.getPrefs(group);
@ -605,12 +589,12 @@ ContentPrefService.prototype = {
return this._selectPrefs(group);
},
getPrefsByName: function ContentPrefService_getPrefsByName(aName) {
getPrefsByName: function ContentPrefService_getPrefsByName(aName, aContext) {
if (!aName)
throw Components.Exception("aName cannot be null or an empty string",
Cr.NS_ERROR_ILLEGAL_VALUE);
if (this._inPrivateBrowsing) {
if (aContext && aContext.usePrivateBrowsing) {
let prefs = Cc["@mozilla.org/hash-property-bag;1"].
createInstance(Ci.nsIWritablePropertyBag);
let groupNames = this._privModeStorage.groupsForName(aName);
@ -625,9 +609,6 @@ ContentPrefService.prototype = {
return this._selectPrefsByName(aName);
},
// boolean to indicate if we are in private browsing mode
_inPrivateBrowsing: false,
// A hash of arrays of observers, indexed by setting name.
_observers: {},

View File

@ -1,5 +1,5 @@
component {e6a3f533-4ffa-4615-8eb4-d4e72d883fa7} nsContentPrefService.js
contract @mozilla.org/content-pref/service;1 {e6a3f533-4ffa-4615-8eb4-d4e72d883fa7}
component {e3f772f3-023f-4b32-b074-36cf0fd5d414} nsContentPrefService.js
contract @mozilla.org/content-pref/service;1 {e3f772f3-023f-4b32-b074-36cf0fd5d414}
component {8df290ae-dcaa-4c11-98a5-2429a4dc97bb} nsContentPrefService.js
contract @mozilla.org/content-pref/hostname-grouper;1 {8df290ae-dcaa-4c11-98a5-2429a4dc97bb}
category wakeup-request nsContentPrefService @mozilla.org/content-pref/service;1,nsIContentPrefService,getService,ContentPref:getPref,ContentPref:setPref

View File

@ -9,6 +9,9 @@ const Ci = Components.interfaces;
const Cr = Components.results;
const Cu = Components.utils;
Cu.import('resource://gre/modules/Services.jsm');
Cu.import('resource://gre/modules/ContentPrefInstance.jsm');
const CONTENT_PREFS_DB_FILENAME = "content-prefs.sqlite";
const CONTENT_PREFS_BACKUP_DB_FILENAME = "content-prefs.sqlite.corrupt";
@ -133,6 +136,15 @@ var ContentPrefTest = {
};
let gInPrivateBrowsing = false;
function enterPBMode() {
gInPrivateBrowsing = true;
}
function exitPBMode() {
gInPrivateBrowsing = false;
Services.obs.notifyObservers(null, "last-pb-context-exited", null);
}
ContentPrefTest.deleteDatabase();
function inChildProcess() {

View File

@ -2,37 +2,15 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
var _PBSvc = null;
function get_PBSvc() {
if (_PBSvc)
return _PBSvc;
try {
_PBSvc = Cc["@mozilla.org/privatebrowsing;1"].
getService(Ci.nsIPrivateBrowsingService);
return _PBSvc;
} catch (e) {}
return null;
}
var _CMSvc = null;
function get_ContentPrefs() {
if (_CMSvc)
return _CMSvc;
return Cc["@mozilla.org/content-pref/service;1"].
createInstance(Ci.nsIContentPrefService);
}
function run_test() {
var pb = get_PBSvc();
if (pb) { // Private Browsing might not be available
var prefBranch = Cc["@mozilla.org/preferences-service;1"].
getService(Ci.nsIPrefBranch);
prefBranch.setBoolPref("browser.privatebrowsing.keep_current_session", true);
let loadContext = { get usePrivateBrowsing() { return gInPrivateBrowsing; } };
ContentPrefTest.deleteDatabase();
var cp = get_ContentPrefs();
var cp = new ContentPrefInstance(loadContext);
do_check_neq(cp, null, "Retrieving the content prefs service failed");
try {
@ -45,7 +23,7 @@ function run_test() {
// make sure Zoom-A is retrievable
do_check_eq(cp.getPref(uri1, pref_name), zoomA);
// enter private browsing mode
pb.privateBrowsingEnabled = true;
enterPBMode();
// make sure Zoom-A is retrievable
do_check_eq(cp.getPref(uri1, pref_name), zoomA);
// save Zoom-B
@ -57,7 +35,7 @@ function run_test() {
// make sure Zoom-A has changed
do_check_eq(cp.getPref(uri1, pref_name), zoomA_new);
// exit private browsing mode
pb.privateBrowsingEnabled = false;
exitPBMode();
// make sure Zoom-A change has not persisted
do_check_eq(cp.getPref(uri1, pref_name), zoomA);
// make sure Zoom-B change has not persisted
@ -67,5 +45,4 @@ function run_test() {
}
prefBranch.clearUserPref("browser.privatebrowsing.keep_current_session");
}
}

View File

@ -3,8 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
function run_test() {
var cps = Cc["@mozilla.org/content-pref/service;1"].
getService(Ci.nsIContentPrefService);
var cps = new ContentPrefInstance(null);
var uri = ContentPrefTest.getURI("http://www.example.com/");

View File

@ -15,19 +15,13 @@ var prefObserver = {
};
function run_test() {
var pbs;
try {
pbs = Cc["@mozilla.org/privatebrowsing;1"].getService(Ci.nsIPrivateBrowsingService);
} catch(e) {
// Private Browsing might not be available
return;
}
Cc["@mozilla.org/preferences-service;1"].
getService(Ci.nsIPrefBranch).
setBoolPref("browser.privatebrowsing.keep_current_session", true);
let loadContext = { get usePrivateBrowsing() { return gInPrivateBrowsing; } };
var cps = Cc["@mozilla.org/content-pref/service;1"].getService(Ci.nsIContentPrefService);
var cps = new ContentPrefInstance(loadContext);
cps.removeGroupedPrefs();
var uri = ContentPrefTest.getURI("http://www.example.com/");
@ -41,7 +35,7 @@ function run_test() {
cps.addObserver("value", prefObserver);
cps.addObserver("value-global", prefObserver);
pbs.privateBrowsingEnabled = true;
enterPBMode();
// test setPref
num = prefObserver.setCalledNum;

View File

@ -103,8 +103,7 @@ function run_test() {
// Now get the content pref service for real for use by the rest of the tests.
var cps = Cc["@mozilla.org/content-pref/service;1"].
getService(Ci.nsIContentPrefService);
let cps = new ContentPrefInstance(null);
var uri = ContentPrefTest.getURI("http://www.example.com/");

View File

@ -3,8 +3,7 @@
* http://creativecommons.org/publicdomain/zero/1.0/
*/
let cps = Cc["@mozilla.org/content-pref/service;1"].
getService(Ci.nsIContentPrefService);
let cps = new ContentPrefInstance(null);
function run_test() {
testCacheWorks("test1.example.com", "test-pref1");

View File

@ -1,8 +1,7 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
var cps = Cc["@mozilla.org/content-pref/service;1"].
getService(Ci.nsIContentPrefService);
var cps = new ContentPrefInstance(null);
var uri = ContentPrefTest.getURI("http://www.example.com/");
function run_test() {

View File

@ -4,8 +4,7 @@
function run_test() {
var cps = Cc["@mozilla.org/content-pref/service;1"].
getService(Ci.nsIContentPrefService);
var cps = new ContentPrefInstance(null);
// Make sure disk synchronization checking is turned off by default.
var statement = cps.DBConnection.createStatement("PRAGMA synchronous");

View File

@ -2,8 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
var cps = Cc["@mozilla.org/content-pref/service;1"].
getService(Ci.nsIContentPrefService);
var cps = new ContentPrefInstance(null);
function run_test() {
var uri1 = ContentPrefTest.getURI("http://www.domain1.com/");

View File

@ -20,18 +20,18 @@ function run_test() {
catch(e) { }
// Can set&get whitelisted values
cps.setPref("group", "browser.upload.lastDir", "childValue");
do_check_eq(cps.getPref("group", "browser.upload.lastDir"), "childValue");
cps.setPref("group", "browser.upload.lastDir", "childValue", null);
do_check_eq(cps.getPref("group", "browser.upload.lastDir", null), "childValue");
// Test sending URI
var ioSvc = Cc["@mozilla.org/network/io-service;1"].
getService(Ci.nsIIOService);
var uri = ioSvc.newURI("http://mozilla.org", null, null);
cps.setPref(uri, "browser.upload.lastDir", "childValue2");
do_check_eq(cps.getPref(uri, "browser.upload.lastDir"), "childValue2");
cps.setPref(uri, "browser.upload.lastDir", "childValue2", null);
do_check_eq(cps.getPref(uri, "browser.upload.lastDir", null), "childValue2");
// Previous value
do_check_eq(cps.getPref("group", "browser.upload.lastDir"), "childValue");
do_check_eq(cps.getPref("group", "browser.upload.lastDir", null), "childValue");
// Tell parent to finish and clean up
cps.wrappedJSObject.messageManager.sendSyncMessage('ContentPref:QUIT');

View File

@ -21,13 +21,13 @@ function run_test() {
// Cannot set general values
messageHandler.receiveMessage({ name: "ContentPref:setPref",
json: { group: 'group2', name: 'name', value: 'someValue' } });
do_check_eq(cps.getPref('group', 'name'), undefined);
do_check_eq(cps.getPref('group', 'name', null), undefined);
// Can set whitelisted values
do_check_true(messageHandler.receiveMessage({ name: "ContentPref:setPref",
json: { group: 'group2', name: 'browser.upload.lastDir',
value: 'someValue' } }).succeeded);
do_check_eq(cps.getPref('group2', 'browser.upload.lastDir'), 'someValue');
do_check_eq(cps.getPref('group2', 'browser.upload.lastDir', null), 'someValue');
// Prepare for child tests

View File

@ -197,10 +197,10 @@ var ForgetAboutSite = {
// Now, for each name we got back, remove all of its prefs.
for (let i = 0; i < names.length; i++) {
let uri = names[i];
let enumerator = cp.getPrefs(uri).enumerator;
let enumerator = cp.getPrefs(uri, null).enumerator;
while (enumerator.hasMoreElements()) {
let pref = enumerator.getNext().QueryInterface(Ci.nsIProperty);
cp.removePref(uri, pref.name);
cp.removePref(uri, pref.name, null);
}
}
}

View File

@ -288,7 +288,7 @@ function add_preference(aURI)
check_preference_exists(aURI, false);
let cp = Cc["@mozilla.org/content-pref/service;1"].
getService(Ci.nsIContentPrefService);
cp.setPref(aURI, PREFERENCE_NAME, "foo");
cp.setPref(aURI, PREFERENCE_NAME, "foo", null);
check_preference_exists(aURI, true);
}
@ -305,7 +305,7 @@ function check_preference_exists(aURI, aExists)
let cp = Cc["@mozilla.org/content-pref/service;1"].
getService(Ci.nsIContentPrefService);
let checker = aExists ? do_check_true : do_check_false;
checker(cp.hasPref(aURI, PREFERENCE_NAME));
checker(cp.hasPref(aURI, PREFERENCE_NAME, null));
}
////////////////////////////////////////////////////////////////////////////////
@ -515,7 +515,7 @@ function test_content_preferecnes_not_cleared_with_uri_contains_domain()
// Reset state
let cp = Cc["@mozilla.org/content-pref/service;1"].
getService(Ci.nsIContentPrefService);
cp.removePref(TEST_URI, PREFERENCE_NAME);
cp.removePref(TEST_URI, PREFERENCE_NAME, null);
check_preference_exists(TEST_URI, false);
}

View File

@ -50,7 +50,10 @@ let observer = {
gDownloadLastDirFile = null;
if (Services.prefs.prefHasUserValue(LAST_DIR_PREF))
Services.prefs.clearUserPref(LAST_DIR_PREF);
Services.contentPrefs.removePrefsByName(LAST_DIR_PREF);
// Ensure that purging session history causes both the session-only PB cache
// and persistent prefs to be cleared.
Services.contentPrefs.removePrefsByName(LAST_DIR_PREF, {usePrivateBrowsing: false});
Services.contentPrefs.removePrefsByName(LAST_DIR_PREF, {usePrivateBrowsing: true});
break;
}
}
@ -97,7 +100,11 @@ DownloadLastDir.prototype = {
},
getFile: function (aURI) {
if (aURI && isContentPrefEnabled()) {
let lastDir = Services.contentPrefs.getPref(aURI, LAST_DIR_PREF);
let loadContext = this.window
.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIWebNavigation)
.QueryInterface(Components.interfaces.nsILoadContext);
let lastDir = Services.contentPrefs.getPref(aURI, LAST_DIR_PREF, loadContext);
if (lastDir) {
var lastDirFile = Components.classes["@mozilla.org/file/local;1"]
.createInstance(Components.interfaces.nsIFile);
@ -118,10 +125,14 @@ DownloadLastDir.prototype = {
},
setFile: function (aURI, aFile) {
if (aURI && isContentPrefEnabled()) {
let loadContext = this.window
.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIWebNavigation)
.QueryInterface(Components.interfaces.nsILoadContext);
if (aFile instanceof Components.interfaces.nsIFile)
Services.contentPrefs.setPref(aURI, LAST_DIR_PREF, aFile.path);
Services.contentPrefs.setPref(aURI, LAST_DIR_PREF, aFile.path, loadContext);
else
Services.contentPrefs.removePref(aURI, LAST_DIR_PREF);
Services.contentPrefs.removePref(aURI, LAST_DIR_PREF, loadContext);
}
if (this.isPrivate()) {
if (aFile instanceof Components.interfaces.nsIFile)