bug 378547: site-specific preference service
r=mconnor
This commit is contained in:
50
toolkit/components/contentprefs/Makefile.in
Executable file
50
toolkit/components/contentprefs/Makefile.in
Executable file
@@ -0,0 +1,50 @@
|
||||
# ***** 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 Content Prefs (cpref).
|
||||
#
|
||||
# The Initial Developer of the Original Code is Mozilla.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2006
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Myk Melez <myk@mozilla.org>
|
||||
#
|
||||
# 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 *****
|
||||
|
||||
DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
DIRS = public src
|
||||
|
||||
ifdef ENABLE_TESTS
|
||||
DIRS += tests
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
50
toolkit/components/contentprefs/public/Makefile.in
Executable file
50
toolkit/components/contentprefs/public/Makefile.in
Executable file
@@ -0,0 +1,50 @@
|
||||
# ***** 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 Content Prefs (cpref).
|
||||
#
|
||||
# The Initial Developer of the Original Code is Mozilla.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2006
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Myk Melez <myk@mozilla.org>
|
||||
#
|
||||
# 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 *****
|
||||
|
||||
DEPTH = ../../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = contentprefs
|
||||
XPIDL_MODULE = contentprefs
|
||||
|
||||
XPIDLSRCS = nsIContentPrefService.idl \
|
||||
nsIContentURIGrouper.idl
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
142
toolkit/components/contentprefs/public/nsIContentPrefService.idl
Executable file
142
toolkit/components/contentprefs/public/nsIContentPrefService.idl
Executable file
@@ -0,0 +1,142 @@
|
||||
/* ***** 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 Content Preferences (cpref).
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2006
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Myk Melez <myk@mozilla.org>
|
||||
*
|
||||
* 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 "nsISupports.idl"
|
||||
#include "nsIVariant.idl"
|
||||
#include "nsIURI.idl"
|
||||
#include "nsIPropertyBag2.idl"
|
||||
#include "nsIContentURIGrouper.idl"
|
||||
|
||||
[scriptable, uuid(746c7a02-f6c1-4869-b434-7c8b86e60e61)]
|
||||
interface nsIContentPrefObserver : nsISupports
|
||||
{
|
||||
/**
|
||||
* Called when a content pref is set to a different value.
|
||||
*
|
||||
* @param aGroup the group to which the pref belongs, or null
|
||||
* if it's a global pref (applies to all URIs)
|
||||
* @param aName the name of the pref that was set
|
||||
* @param aValue the new value of the pref
|
||||
*/
|
||||
void onContentPrefSet(in AString aGroup, in AString aName, in nsIVariant aValue);
|
||||
|
||||
/**
|
||||
* Called when a content pref is removed.
|
||||
*
|
||||
* @param aGroup the group to which the pref belongs, or null
|
||||
* if it's a global pref (applies to all URIs)
|
||||
* @param aName the name of the pref that was removed
|
||||
*/
|
||||
void onContentPrefRemoved(in AString aGroup, in AString aName);
|
||||
};
|
||||
|
||||
[scriptable, uuid(5b1f6044-72f8-4920-9043-0c52d0ae4f4c)]
|
||||
interface nsIContentPrefService : nsISupports
|
||||
{
|
||||
/**
|
||||
* Get a pref.
|
||||
*
|
||||
* Besides the regular string, integer, boolean, etc. values, this method
|
||||
* may return null (nsIDataType::VTYPE_EMPTY), which means the pref is set
|
||||
* to NULL in the database, as well as undefined (nsIDataType::VTYPE_VOID),
|
||||
* which means there is no record for this pref in the database.
|
||||
*
|
||||
* @param aURI the URI for which to get the pref, or null to get
|
||||
* the global pref (applies to all URIs)
|
||||
* @param aName the name of the pref to get
|
||||
*
|
||||
* @returns the value of the pref
|
||||
*/
|
||||
nsIVariant getPref(in nsIURI aURI, in AString aName);
|
||||
|
||||
/**
|
||||
* Set a pref.
|
||||
*
|
||||
* @param aURI the URI for which to set the pref, or null to set
|
||||
* the global pref (applies to all URIs)
|
||||
* @param aName the name of the pref to set
|
||||
* @param aValue the new value of the pref
|
||||
*/
|
||||
void setPref(in nsIURI aURI, in AString aName, in nsIVariant aValue);
|
||||
|
||||
/**
|
||||
* Check whether or not a pref exists.
|
||||
*
|
||||
* @param aURI the URI for which to check for the pref
|
||||
* @param aName the name of the pref to check for
|
||||
*/
|
||||
boolean hasPref(in nsIURI aURI, in AString aName);
|
||||
|
||||
/**
|
||||
* Remove a pref.
|
||||
*
|
||||
* @param aURI the URI for which to remove the pref
|
||||
* @param aName the name of the pref to remove
|
||||
*/
|
||||
void removePref(in nsIURI aURI, in AString aName);
|
||||
|
||||
/**
|
||||
* Get the prefs that apply to the given URI.
|
||||
*
|
||||
* @param aURI the URI for which to retrieve prefs
|
||||
*
|
||||
* @returns a property bag of prefs
|
||||
*/
|
||||
nsIPropertyBag2 getPrefs(in nsIURI aURI);
|
||||
|
||||
/**
|
||||
* Add an observer.
|
||||
*
|
||||
* @param aName the setting to observe, or null to add
|
||||
* a generic observer that observes all settings
|
||||
* @param aObserver the observer to add
|
||||
*/
|
||||
void addObserver(in AString aName, in nsIContentPrefObserver aObserver);
|
||||
|
||||
/**
|
||||
* Remove an observer.
|
||||
*
|
||||
* @param aName the setting being observed, or null to remove
|
||||
* a generic observer that observes all settings
|
||||
* @param aObserver the observer to remove
|
||||
*/
|
||||
void removeObserver(in AString aName, in nsIContentPrefObserver aObserver);
|
||||
|
||||
// The component that the service uses to determine the groups to which
|
||||
// URIs belong. By default this is the "hostname grouper", which groups
|
||||
// URIs by full hostname (a.k.a. site).
|
||||
readonly attribute nsIContentURIGrouper grouper;
|
||||
};
|
||||
50
toolkit/components/contentprefs/public/nsIContentURIGrouper.idl
Executable file
50
toolkit/components/contentprefs/public/nsIContentURIGrouper.idl
Executable file
@@ -0,0 +1,50 @@
|
||||
/* ***** 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 Content Preferences (cpref).
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2006
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Myk Melez <myk@mozilla.org>
|
||||
*
|
||||
* 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 "nsIURI.idl"
|
||||
|
||||
[scriptable, uuid(4bb38cb4-c3cb-4d17-9799-1b3132b39723)]
|
||||
interface nsIContentURIGrouper : nsISupports
|
||||
{
|
||||
/**
|
||||
* Determine the group to which the URI belongs.
|
||||
*
|
||||
* @param aURI the URI to group
|
||||
*
|
||||
* @returns the group to which the URI belongs
|
||||
*/
|
||||
AString group(in nsIURI aURI);
|
||||
};
|
||||
48
toolkit/components/contentprefs/src/Makefile.in
Executable file
48
toolkit/components/contentprefs/src/Makefile.in
Executable file
@@ -0,0 +1,48 @@
|
||||
# ***** 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 Content Prefs (cpref).
|
||||
#
|
||||
# The Initial Developer of the Original Code is Mozilla.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2006
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Myk Melez <myk@mozilla.org>
|
||||
#
|
||||
# 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 *****
|
||||
|
||||
DEPTH = ../../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = contentprefs
|
||||
|
||||
EXTRA_COMPONENTS = nsContentPrefService.js
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
965
toolkit/components/contentprefs/src/nsContentPrefService.js
Executable file
965
toolkit/components/contentprefs/src/nsContentPrefService.js
Executable file
@@ -0,0 +1,965 @@
|
||||
/* ***** 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 Content Preferences (cpref).
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2006
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Myk Melez <myk@mozilla.org>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
const Ci = Components.interfaces;
|
||||
const Cc = Components.classes;
|
||||
const Cr = Components.results;
|
||||
const Cu = Components.utils;
|
||||
|
||||
function ContentPrefService() {}
|
||||
|
||||
ContentPrefService.prototype = {
|
||||
//**************************************************************************//
|
||||
// Convenience Getters
|
||||
|
||||
// Observer Service
|
||||
__observerSvc: null,
|
||||
get _observerSvc() {
|
||||
if (!this.__observerSvc)
|
||||
this.__observerSvc = Cc["@mozilla.org/observer-service;1"].
|
||||
getService(Ci.nsIObserverService);
|
||||
return this.__observerSvc;
|
||||
},
|
||||
|
||||
// Console Service
|
||||
__consoleSvc: null,
|
||||
get _consoleSvc() {
|
||||
if (!this.__consoleSvc)
|
||||
this.__consoleSvc = Cc["@mozilla.org/consoleservice;1"].
|
||||
getService(Ci.nsIConsoleService);
|
||||
return this.__consoleSvc;
|
||||
},
|
||||
|
||||
|
||||
//**************************************************************************//
|
||||
// Initialization & Destruction
|
||||
|
||||
_init: function ContentPrefService__init() {
|
||||
// If this throws an exception, it causes the getService call to fail,
|
||||
// but the next time a consumer tries to retrieve the service, we'll try
|
||||
// to initialize the database again, which might work if the failure
|
||||
// was due to a temporary condition (like being out of disk space).
|
||||
this._dbInit();
|
||||
|
||||
// Observe shutdown so we can shut down the database connection.
|
||||
this._observerSvc.addObserver(this, "xpcom-shutdown", false);
|
||||
},
|
||||
|
||||
_destroy: function ContentPrefService__destroy() {
|
||||
this._observerSvc.removeObserver(this, "xpcom-shutdown");
|
||||
|
||||
// mozStorage shuts down the database for us automatically, but this
|
||||
// helps us avoid the appearance of leaking the connection.
|
||||
this._dbConnection = null;
|
||||
},
|
||||
|
||||
|
||||
//**************************************************************************//
|
||||
// nsISupports
|
||||
|
||||
_interfaces: [Ci.nsIContentPrefService, Ci.nsISupports],
|
||||
|
||||
QueryInterface: function ContentPrefService_QueryInterface(aIID) {
|
||||
if (!this._interfaces.some( function(v) { return aIID.equals(v) } ))
|
||||
throw Cr.NS_ERROR_NO_INTERFACE;
|
||||
return this;
|
||||
},
|
||||
|
||||
|
||||
//**************************************************************************//
|
||||
// nsIObserver
|
||||
|
||||
observe: function ContentPrefService_observe(subject, topic, data) {
|
||||
switch (topic) {
|
||||
case "xpcom-shutdown":
|
||||
this._destroy();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
//**************************************************************************//
|
||||
// nsIContentPrefService
|
||||
|
||||
getPref: function ContentPrefService_getPref(aURI, aName) {
|
||||
if (aURI) {
|
||||
var group = this.grouper.group(aURI);
|
||||
return this._selectPref(group, aName);
|
||||
}
|
||||
else
|
||||
return this._selectGlobalPref(aName);
|
||||
},
|
||||
|
||||
setPref: function ContentPrefService_setPref(aURI, aName, aValue) {
|
||||
// If the pref is already set to the value, there's nothing more to do.
|
||||
var currentValue = this.getPref(aURI, aName);
|
||||
if (typeof currentValue != "undefined" && currentValue == aValue)
|
||||
return;
|
||||
|
||||
var settingID = this._selectSettingID(aName) || this._insertSetting(aName);
|
||||
var group, groupID, prefID;
|
||||
if (aURI) {
|
||||
group = this.grouper.group(aURI);
|
||||
groupID = this._selectGroupID(group) || this._insertGroup(group);
|
||||
prefID = this._selectPrefID(groupID, settingID);
|
||||
}
|
||||
else {
|
||||
group = null;
|
||||
groupID = null;
|
||||
prefID = this._selectGlobalPrefID(settingID);
|
||||
}
|
||||
|
||||
// Update the existing record, if any, or create a new one.
|
||||
if (prefID)
|
||||
this._updatePref(prefID, aValue);
|
||||
else
|
||||
this._insertPref(groupID, settingID, aValue);
|
||||
|
||||
for each (var observer in this._getObservers(aName)) {
|
||||
try {
|
||||
observer.onContentPrefSet(group, aName, aValue);
|
||||
}
|
||||
catch(ex) {
|
||||
Cu.reportError(ex);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
hasPref: function ContentPrefService_hasPref(aURI, aName) {
|
||||
// XXX If consumers end up calling this method regularly, then we should
|
||||
// optimize this to query the database directly.
|
||||
return (typeof this.getPref(aURI, aName) != "undefined");
|
||||
},
|
||||
|
||||
removePref: function ContentPrefService_removePref(aURI, aName) {
|
||||
// If there's no old value, then there's nothing to remove.
|
||||
if (!this.hasPref(aURI, aName))
|
||||
return;
|
||||
|
||||
var settingID = this._selectSettingID(aName);
|
||||
var group, groupID, prefID;
|
||||
if (aURI) {
|
||||
group = this.grouper.group(aURI);
|
||||
groupID = this._selectGroupID(group);
|
||||
prefID = this._selectPrefID(groupID, settingID);
|
||||
}
|
||||
else {
|
||||
group = null;
|
||||
groupID = null;
|
||||
prefID = this._selectGlobalPrefID(settingID);
|
||||
}
|
||||
|
||||
this._deletePref(prefID);
|
||||
|
||||
// Get rid of extraneous records that are no longer being used.
|
||||
this._deleteSettingIfUnused(settingID);
|
||||
if (groupID)
|
||||
this._deleteGroupIfUnused(groupID);
|
||||
|
||||
for each (var observer in this._getObservers(aName)) {
|
||||
try {
|
||||
observer.onContentPrefRemoved(group, aName);
|
||||
}
|
||||
catch(ex) {
|
||||
Cu.reportError(ex);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
getPrefs: function ContentPrefService_getPrefs(aURI) {
|
||||
if (aURI) {
|
||||
var group = this.grouper.group(aURI);
|
||||
return this._selectPrefs(group);
|
||||
}
|
||||
else
|
||||
return this._selectGlobalPrefs();
|
||||
},
|
||||
|
||||
// A hash of arrays of observers, indexed by setting name.
|
||||
_observers: {},
|
||||
|
||||
// An array of generic observers, which observe all settings.
|
||||
_genericObservers: [],
|
||||
|
||||
addObserver: function ContentPrefService_addObserver(aName, aObserver) {
|
||||
var observers;
|
||||
if (aName) {
|
||||
if (!this._observers[aName])
|
||||
this._observers[aName] = [];
|
||||
observers = this._observers[aName];
|
||||
}
|
||||
else
|
||||
observers = this._genericObservers;
|
||||
|
||||
if (observers.indexOf(aObserver) == -1)
|
||||
observers.push(aObserver);
|
||||
},
|
||||
|
||||
removeObserver: function ContentPrefService_removeObserver(aName, aObserver) {
|
||||
var observers;
|
||||
if (aName) {
|
||||
if (!this._observers[aName])
|
||||
return;
|
||||
observers = this._observers[aName];
|
||||
}
|
||||
else
|
||||
observers = this._genericObservers;
|
||||
|
||||
if (observers.indexOf(aObserver) != -1)
|
||||
observers.splice(observers.indexOf(aObserver), 1);
|
||||
},
|
||||
|
||||
/**
|
||||
* Construct a list of observers to notify about a change to some setting,
|
||||
* putting setting-specific observers before before generic ones, so observers
|
||||
* that initialize individual settings (like the page style controller)
|
||||
* execute before observers that display multiple settings and depend on them
|
||||
* being initialized first (like the content prefs sidebar).
|
||||
*/
|
||||
_getObservers: function ContentPrefService__getObservers(aName) {
|
||||
var observers = [];
|
||||
|
||||
if (aName && this._observers[aName])
|
||||
observers = observers.concat(this._observers[aName]);
|
||||
observers = observers.concat(this._genericObservers);
|
||||
|
||||
return observers;
|
||||
},
|
||||
|
||||
_grouper: null,
|
||||
get grouper() {
|
||||
if (!this._grouper)
|
||||
this._grouper = Cc["@mozilla.org/content-pref/hostname-grouper;1"].
|
||||
getService(Ci.nsIContentURIGrouper);
|
||||
return this._grouper;
|
||||
},
|
||||
|
||||
|
||||
//**************************************************************************//
|
||||
// Data Retrieval & Modification
|
||||
|
||||
__stmtSelectPref: null,
|
||||
get _stmtSelectPref() {
|
||||
if (!this.__stmtSelectPref)
|
||||
this.__stmtSelectPref = this._dbCreateStatement(
|
||||
"SELECT prefs.value AS value " +
|
||||
"FROM prefs " +
|
||||
"JOIN groups ON prefs.groupID = groups.id " +
|
||||
"JOIN settings ON prefs.settingID = settings.id " +
|
||||
"WHERE groups.name = :group " +
|
||||
"AND settings.name = :setting"
|
||||
);
|
||||
|
||||
return this.__stmtSelectPref;
|
||||
},
|
||||
|
||||
_selectPref: function ContentPrefService__selectPref(aGroup, aSetting) {
|
||||
var value;
|
||||
|
||||
try {
|
||||
this._stmtSelectPref.params.group = aGroup;
|
||||
this._stmtSelectPref.params.setting = aSetting;
|
||||
|
||||
if (this._stmtSelectPref.step())
|
||||
value = this._stmtSelectPref.row["value"];
|
||||
}
|
||||
finally {
|
||||
this._stmtSelectPref.reset();
|
||||
}
|
||||
|
||||
return value;
|
||||
},
|
||||
|
||||
__stmtSelectGlobalPref: null,
|
||||
get _stmtSelectGlobalPref() {
|
||||
if (!this.__stmtSelectGlobalPref)
|
||||
this.__stmtSelectGlobalPref = this._dbCreateStatement(
|
||||
"SELECT prefs.value AS value " +
|
||||
"FROM prefs " +
|
||||
"JOIN settings ON prefs.settingID = settings.id " +
|
||||
"WHERE prefs.groupID IS NULL " +
|
||||
"AND settings.name = :name"
|
||||
);
|
||||
|
||||
return this.__stmtSelectGlobalPref;
|
||||
},
|
||||
|
||||
_selectGlobalPref: function ContentPrefService__selectGlobalPref(aName) {
|
||||
var value;
|
||||
|
||||
try {
|
||||
this._stmtSelectGlobalPref.params.name = aName;
|
||||
|
||||
if (this._stmtSelectGlobalPref.step())
|
||||
value = this._stmtSelectGlobalPref.row["value"];
|
||||
}
|
||||
finally {
|
||||
this._stmtSelectGlobalPref.reset();
|
||||
}
|
||||
|
||||
return value;
|
||||
},
|
||||
|
||||
__stmtSelectGroupID: null,
|
||||
get _stmtSelectGroupID() {
|
||||
if (!this.__stmtSelectGroupID)
|
||||
this.__stmtSelectGroupID = this._dbCreateStatement(
|
||||
"SELECT groups.id AS id " +
|
||||
"FROM groups " +
|
||||
"WHERE groups.name = :name "
|
||||
);
|
||||
|
||||
return this.__stmtSelectGroupID;
|
||||
},
|
||||
|
||||
_selectGroupID: function ContentPrefService__selectGroupID(aName) {
|
||||
var id;
|
||||
|
||||
try {
|
||||
this._stmtSelectGroupID.params.name = aName;
|
||||
|
||||
if (this._stmtSelectGroupID.step())
|
||||
id = this._stmtSelectGroupID.row["id"];
|
||||
}
|
||||
finally {
|
||||
this._stmtSelectGroupID.reset();
|
||||
}
|
||||
|
||||
return id;
|
||||
},
|
||||
|
||||
__stmtInsertGroup: null,
|
||||
get _stmtInsertGroup() {
|
||||
if (!this.__stmtInsertGroup)
|
||||
this.__stmtInsertGroup = this._dbCreateStatement(
|
||||
"INSERT INTO groups (name) VALUES (:name)"
|
||||
);
|
||||
|
||||
return this.__stmtInsertGroup;
|
||||
},
|
||||
|
||||
_insertGroup: function ContentPrefService__insertGroup(aName) {
|
||||
this._stmtInsertGroup.params.name = aName;
|
||||
this._stmtInsertGroup.execute();
|
||||
return this._dbConnection.lastInsertRowID;
|
||||
},
|
||||
|
||||
__stmtSelectSettingID: null,
|
||||
get _stmtSelectSettingID() {
|
||||
if (!this.__stmtSelectSettingID)
|
||||
this.__stmtSelectSettingID = this._dbCreateStatement(
|
||||
"SELECT id FROM settings WHERE name = :name"
|
||||
);
|
||||
|
||||
return this.__stmtSelectSettingID;
|
||||
},
|
||||
|
||||
_selectSettingID: function ContentPrefService__selectSettingID(aName) {
|
||||
var id;
|
||||
|
||||
try {
|
||||
this._stmtSelectSettingID.params.name = aName;
|
||||
|
||||
if (this._stmtSelectSettingID.step())
|
||||
id = this._stmtSelectSettingID.row["id"];
|
||||
}
|
||||
finally {
|
||||
this._stmtSelectSettingID.reset();
|
||||
}
|
||||
|
||||
return id;
|
||||
},
|
||||
|
||||
__stmtInsertSetting: null,
|
||||
get _stmtInsertSetting() {
|
||||
if (!this.__stmtInsertSetting)
|
||||
this.__stmtInsertSetting = this._dbCreateStatement(
|
||||
"INSERT INTO settings (name) VALUES (:name)"
|
||||
);
|
||||
|
||||
return this.__stmtInsertSetting;
|
||||
},
|
||||
|
||||
_insertSetting: function ContentPrefService__insertSetting(aName) {
|
||||
this._stmtInsertSetting.params.name = aName;
|
||||
this._stmtInsertSetting.execute();
|
||||
return this._dbConnection.lastInsertRowID;
|
||||
},
|
||||
|
||||
__stmtSelectPrefID: null,
|
||||
get _stmtSelectPrefID() {
|
||||
if (!this.__stmtSelectPrefID)
|
||||
this.__stmtSelectPrefID = this._dbCreateStatement(
|
||||
"SELECT id FROM prefs WHERE groupID = :groupID AND settingID = :settingID"
|
||||
);
|
||||
|
||||
return this.__stmtSelectPrefID;
|
||||
},
|
||||
|
||||
_selectPrefID: function ContentPrefService__selectPrefID(aGroupID, aSettingID) {
|
||||
var id;
|
||||
|
||||
try {
|
||||
this._stmtSelectPrefID.params.groupID = aGroupID;
|
||||
this._stmtSelectPrefID.params.settingID = aSettingID;
|
||||
|
||||
if (this._stmtSelectPrefID.step())
|
||||
id = this._stmtSelectPrefID.row["id"];
|
||||
}
|
||||
finally {
|
||||
this._stmtSelectPrefID.reset();
|
||||
}
|
||||
|
||||
return id;
|
||||
},
|
||||
|
||||
__stmtSelectGlobalPrefID: null,
|
||||
get _stmtSelectGlobalPrefID() {
|
||||
if (!this.__stmtSelectGlobalPrefID)
|
||||
this.__stmtSelectGlobalPrefID = this._dbCreateStatement(
|
||||
"SELECT id FROM prefs WHERE groupID IS NULL AND settingID = :settingID"
|
||||
);
|
||||
|
||||
return this.__stmtSelectGlobalPrefID;
|
||||
},
|
||||
|
||||
_selectGlobalPrefID: function ContentPrefService__selectGlobalPrefID(aSettingID) {
|
||||
var id;
|
||||
|
||||
try {
|
||||
this._stmtSelectGlobalPrefID.params.settingID = aSettingID;
|
||||
|
||||
if (this._stmtSelectGlobalPrefID.step())
|
||||
id = this._stmtSelectGlobalPrefID.row["id"];
|
||||
}
|
||||
finally {
|
||||
this._stmtSelectGlobalPrefID.reset();
|
||||
}
|
||||
|
||||
return id;
|
||||
},
|
||||
|
||||
__stmtInsertPref: null,
|
||||
get _stmtInsertPref() {
|
||||
if (!this.__stmtInsertPref)
|
||||
this.__stmtInsertPref = this._dbCreateStatement(
|
||||
"INSERT INTO prefs (groupID, settingID, value) " +
|
||||
"VALUES (:groupID, :settingID, :value)"
|
||||
);
|
||||
|
||||
return this.__stmtInsertPref;
|
||||
},
|
||||
|
||||
_insertPref: function ContentPrefService__insertPref(aGroupID, aSettingID, aValue) {
|
||||
this._stmtInsertPref.params.groupID = aGroupID;
|
||||
this._stmtInsertPref.params.settingID = aSettingID;
|
||||
this._stmtInsertPref.params.value = aValue;
|
||||
this._stmtInsertPref.execute();
|
||||
return this._dbConnection.lastInsertRowID;
|
||||
},
|
||||
|
||||
__stmtUpdatePref: null,
|
||||
get _stmtUpdatePref() {
|
||||
if (!this.__stmtUpdatePref)
|
||||
this.__stmtUpdatePref = this._dbCreateStatement(
|
||||
"UPDATE prefs SET value = :value WHERE id = :id"
|
||||
);
|
||||
|
||||
return this.__stmtUpdatePref;
|
||||
},
|
||||
|
||||
_updatePref: function ContentPrefService__updatePref(aPrefID, aValue) {
|
||||
this._stmtUpdatePref.params.id = aPrefID;
|
||||
this._stmtUpdatePref.params.value = aValue;
|
||||
this._stmtUpdatePref.execute();
|
||||
},
|
||||
|
||||
__stmtDeletePref: null,
|
||||
get _stmtDeletePref() {
|
||||
if (!this.__stmtDeletePref)
|
||||
this.__stmtDeletePref = this._dbCreateStatement(
|
||||
"DELETE FROM prefs WHERE id = :id"
|
||||
);
|
||||
|
||||
return this.__stmtDeletePref;
|
||||
},
|
||||
|
||||
_deletePref: function ContentPrefService__deletePref(aPrefID) {
|
||||
this._stmtDeletePref.params.id = aPrefID;
|
||||
this._stmtDeletePref.execute();
|
||||
},
|
||||
|
||||
__stmtDeleteSettingIfUnused: null,
|
||||
get _stmtDeleteSettingIfUnused() {
|
||||
if (!this.__stmtDeleteSettingIfUnused)
|
||||
this.__stmtDeleteSettingIfUnused = this._dbCreateStatement(
|
||||
"DELETE FROM settings WHERE id = :id " +
|
||||
"AND id NOT IN (SELECT DISTINCT settingID FROM prefs)"
|
||||
);
|
||||
|
||||
return this.__stmtDeleteSettingIfUnused;
|
||||
},
|
||||
|
||||
_deleteSettingIfUnused: function ContentPrefService__deleteSettingIfUnused(aSettingID) {
|
||||
this._stmtDeleteSettingIfUnused.params.id = aSettingID;
|
||||
this._stmtDeleteSettingIfUnused.execute();
|
||||
},
|
||||
|
||||
__stmtDeleteGroupIfUnused: null,
|
||||
get _stmtDeleteGroupIfUnused() {
|
||||
if (!this.__stmtDeleteGroupIfUnused)
|
||||
this.__stmtDeleteGroupIfUnused = this._dbCreateStatement(
|
||||
"DELETE FROM groups WHERE id = :id " +
|
||||
"AND id NOT IN (SELECT DISTINCT groupID FROM prefs)"
|
||||
);
|
||||
|
||||
return this.__stmtDeleteGroupIfUnused;
|
||||
},
|
||||
|
||||
_deleteGroupIfUnused: function ContentPrefService__deleteGroupIfUnused(aGroupID) {
|
||||
this._stmtDeleteGroupIfUnused.params.id = aGroupID;
|
||||
this._stmtDeleteGroupIfUnused.execute();
|
||||
},
|
||||
|
||||
__stmtSelectPrefs: null,
|
||||
get _stmtSelectPrefs() {
|
||||
if (!this.__stmtSelectPrefs)
|
||||
this.__stmtSelectPrefs = this._dbCreateStatement(
|
||||
"SELECT settings.name AS name, prefs.value AS value " +
|
||||
"FROM prefs " +
|
||||
"JOIN groups ON prefs.groupID = groups.id " +
|
||||
"JOIN settings ON prefs.settingID = settings.id " +
|
||||
"WHERE groups.name = :group "
|
||||
);
|
||||
|
||||
return this.__stmtSelectPrefs;
|
||||
},
|
||||
|
||||
_selectPrefs: function ContentPrefService__selectPrefs(aGroup) {
|
||||
var prefs = Cc["@mozilla.org/hash-property-bag;1"].
|
||||
createInstance(Ci.nsIWritablePropertyBag);
|
||||
|
||||
try {
|
||||
this._stmtSelectPrefs.params.group = aGroup;
|
||||
|
||||
while (this._stmtSelectPrefs.step())
|
||||
prefs.setProperty(this._stmtSelectPrefs.row["name"],
|
||||
this._stmtSelectPrefs.row["value"]);
|
||||
}
|
||||
finally {
|
||||
this._stmtSelectPrefs.reset();
|
||||
}
|
||||
|
||||
return prefs;
|
||||
},
|
||||
|
||||
__stmtSelectGlobalPrefs: null,
|
||||
get _stmtSelectGlobalPrefs() {
|
||||
if (!this.__stmtSelectGlobalPrefs)
|
||||
this.__stmtSelectGlobalPrefs = this._dbCreateStatement(
|
||||
"SELECT settings.name AS name, prefs.value AS value " +
|
||||
"FROM prefs " +
|
||||
"JOIN settings ON prefs.settingID = settings.id " +
|
||||
"WHERE prefs.groupID IS NULL"
|
||||
);
|
||||
|
||||
return this.__stmtSelectGlobalPrefs;
|
||||
},
|
||||
|
||||
_selectGlobalPrefs: function ContentPrefService__selectGlobalPrefs() {
|
||||
var prefs = Cc["@mozilla.org/hash-property-bag;1"].
|
||||
createInstance(Ci.nsIWritablePropertyBag);
|
||||
|
||||
try {
|
||||
while (this._stmtSelectGlobalPrefs.step())
|
||||
prefs.setProperty(this._stmtSelectGlobalPrefs.row["name"],
|
||||
this._stmtSelectGlobalPrefs.row["value"]);
|
||||
}
|
||||
finally {
|
||||
this._stmtSelectGlobalPrefs.reset();
|
||||
}
|
||||
|
||||
return prefs;
|
||||
},
|
||||
|
||||
|
||||
//**************************************************************************//
|
||||
// Database Creation & Access
|
||||
|
||||
_dbVersion: 2,
|
||||
|
||||
_dbSchema: {
|
||||
groups: "id INTEGER PRIMARY KEY, \
|
||||
name TEXT NOT NULL",
|
||||
|
||||
settings: "id INTEGER PRIMARY KEY, \
|
||||
name TEXT NOT NULL",
|
||||
|
||||
prefs: "id INTEGER PRIMARY KEY, \
|
||||
groupID INTEGER REFERENCES groups(id), \
|
||||
settingID INTEGER NOT NULL REFERENCES settings(id), \
|
||||
value BLOB"
|
||||
},
|
||||
|
||||
_dbConnection: null,
|
||||
|
||||
_dbCreateStatement: function(aSQLString) {
|
||||
try {
|
||||
var statement = this._dbConnection.createStatement(aSQLString);
|
||||
}
|
||||
catch(ex) {
|
||||
Cu.reportError("error creating statement " + aSQLString + ": " +
|
||||
this._dbConnection.lastError + " - " +
|
||||
this._dbConnection.lastErrorString);
|
||||
throw ex;
|
||||
}
|
||||
|
||||
var wrappedStatement = Cc["@mozilla.org/storage/statement-wrapper;1"].
|
||||
createInstance(Ci.mozIStorageStatementWrapper);
|
||||
wrappedStatement.initialize(statement);
|
||||
return wrappedStatement;
|
||||
},
|
||||
|
||||
// _dbInit and the methods it calls (_dbCreate, _dbMigrate, and version-
|
||||
// specific migration methods) must be careful not to call any method
|
||||
// of the service that assumes the database connection has already been
|
||||
// initialized, since it won't be initialized until at the end of _dbInit.
|
||||
|
||||
_dbInit: function ContentPrefService__dbInit() {
|
||||
this._log("initializing database");
|
||||
|
||||
var dirService = Cc["@mozilla.org/file/directory_service;1"].
|
||||
getService(Ci.nsIProperties);
|
||||
var dbFile = dirService.get("ProfD", Ci.nsIFile);
|
||||
dbFile.append("content-prefs.sqlite");
|
||||
|
||||
var dbService = Cc["@mozilla.org/storage/service;1"].
|
||||
getService(Ci.mozIStorageService);
|
||||
|
||||
var dbConnection;
|
||||
|
||||
if (!dbFile.exists()) {
|
||||
this._log("no database file; creating database");
|
||||
dbConnection = this._dbCreate(dbService, dbFile);
|
||||
}
|
||||
else {
|
||||
try {
|
||||
dbConnection = dbService.openDatabase(dbFile);
|
||||
|
||||
// Get the version of the database in the file.
|
||||
var statement, version;
|
||||
try {
|
||||
statement = dbConnection.createStatement("PRAGMA user_version");
|
||||
statement.executeStep();
|
||||
version = statement.getInt32(0);
|
||||
}
|
||||
finally {
|
||||
statement.reset();
|
||||
}
|
||||
|
||||
if (version != this._dbVersion) {
|
||||
this._log("database: v" + version + ", application: v" +
|
||||
this._dbVersion + "; migrating database");
|
||||
this._dbMigrate(dbConnection, version, this._dbVersion);
|
||||
}
|
||||
}
|
||||
catch (ex) {
|
||||
// If the database file is corrupted, I'm not sure whether we should
|
||||
// just delete the corrupted file or back it up. For now I'm just
|
||||
// deleting it, but here's some code that backs it up (but doesn't limit
|
||||
// the number of backups, which is probably necessary, thus I'm not
|
||||
// using this code):
|
||||
//var backup = this._dbFile.clone();
|
||||
//backup.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, PERMS_FILE);
|
||||
//backup.remove(false);
|
||||
//this._dbFile.moveTo(null, backup.leafName);
|
||||
if (ex.result == Cr.NS_ERROR_FILE_CORRUPTED) {
|
||||
this._log("database file corrupted; recreating database");
|
||||
// Remove the corrupted file, then recreate it.
|
||||
dbFile.remove(false);
|
||||
dbConnection = this._dbCreate(dbService, dbFile);
|
||||
}
|
||||
else
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
this._dbConnection = dbConnection;
|
||||
},
|
||||
|
||||
_dbCreate: function ContentPrefService__dbCreate(aDBService, aDBFile) {
|
||||
var dbConnection = aDBService.openDatabase(aDBFile);
|
||||
for (var table in this._dbSchema)
|
||||
dbConnection.createTable(table, this._dbSchema[table]);
|
||||
dbConnection.executeSimpleSQL("PRAGMA user_version = " + this._dbVersion);
|
||||
return dbConnection;
|
||||
},
|
||||
|
||||
_dbMigrate: function ContentPrefService__dbMigrate(aDBConnection, aOldVersion, aNewVersion) {
|
||||
if (this["_dbMigrate" + aOldVersion + "To" + aNewVersion]) {
|
||||
this._log("migrating database from v" + aOldVersion + " to v" + aNewVersion);
|
||||
aDBConnection.beginTransaction();
|
||||
try {
|
||||
this["_dbMigrate" + aOldVersion + "To" + aNewVersion](aDBConnection);
|
||||
aDBConnection.commitTransaction();
|
||||
}
|
||||
catch(ex) {
|
||||
this._log("migration failed: " + ex + "; DB error code " +
|
||||
aDBConnection.lastError + ": " + aDBConnection.lastErrorString +
|
||||
"; rolling back transaction");
|
||||
aDBConnection.rollbackTransaction();
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
else
|
||||
throw("can't migrate database from v" + aOldVersion +
|
||||
" to v" + aNewVersion + ": no migrator function");
|
||||
},
|
||||
|
||||
_dbMigrate0To2: function ContentPrefService___dbMigrate0To2(aDBConnection) {
|
||||
this._log("migrating sites to the groups table");
|
||||
aDBConnection.createTable("groups", this._dbSchema.groups);
|
||||
aDBConnection.executeSimpleSQL(
|
||||
"INSERT INTO groups (id, name) SELECT id, name FROM sites"
|
||||
);
|
||||
|
||||
this._log("migrating keys to the settings table");
|
||||
aDBConnection.createTable("settings", this._dbSchema.settings);
|
||||
aDBConnection.executeSimpleSQL(
|
||||
"INSERT INTO settings (id, name) SELECT id, name FROM keys"
|
||||
);
|
||||
|
||||
this._log("migrating prefs from the old prefs table to the new one");
|
||||
aDBConnection.executeSimpleSQL("ALTER TABLE prefs RENAME TO prefsOld");
|
||||
aDBConnection.createTable("prefs", this._dbSchema.prefs);
|
||||
aDBConnection.executeSimpleSQL(
|
||||
"INSERT INTO prefs (id, groupID, settingID, value) " +
|
||||
"SELECT id, site_id, key_id, value FROM prefsOld"
|
||||
);
|
||||
|
||||
// Drop obsolete tables.
|
||||
this._log("dropping obsolete tables");
|
||||
aDBConnection.executeSimpleSQL("DROP TABLE prefsOld");
|
||||
aDBConnection.executeSimpleSQL("DROP TABLE keys");
|
||||
aDBConnection.executeSimpleSQL("DROP TABLE sites");
|
||||
|
||||
aDBConnection.executeSimpleSQL("PRAGMA user_version = " + this._dbVersion);
|
||||
},
|
||||
|
||||
_dbMigrate1To2: function ContentPrefService___dbMigrate1To2(aDBConnection) {
|
||||
this._log("migrating groups from the old groups table to the new one");
|
||||
aDBConnection.executeSimpleSQL("ALTER TABLE groups RENAME TO groupsOld");
|
||||
aDBConnection.createTable("groups", this._dbSchema.groups);
|
||||
aDBConnection.executeSimpleSQL(
|
||||
"INSERT INTO groups (id, name) " +
|
||||
"SELECT id, name FROM groupsOld"
|
||||
);
|
||||
|
||||
this._log("dropping obsolete tables");
|
||||
aDBConnection.executeSimpleSQL("DROP TABLE groupers");
|
||||
aDBConnection.executeSimpleSQL("DROP TABLE groupsOld");
|
||||
|
||||
aDBConnection.executeSimpleSQL("PRAGMA user_version = " + this._dbVersion);
|
||||
},
|
||||
|
||||
|
||||
//**************************************************************************//
|
||||
// Utilities
|
||||
|
||||
/**
|
||||
* Get an app pref or a default value if the pref doesn't exist.
|
||||
*
|
||||
* @param aPrefName
|
||||
* @param aDefaultValue
|
||||
* @returns the pref's value or the default (if it is missing)
|
||||
*/
|
||||
_getAppPref: function ContentPrefService__getAppPref(aPrefName, aDefaultValue) {
|
||||
try {
|
||||
var prefBranch = Cc["@mozilla.org/preferences-service;1"].
|
||||
getService(Ci.nsIPrefBranch);
|
||||
switch (prefBranch.getPrefType(aPrefName)) {
|
||||
case prefBranch.PREF_STRING:
|
||||
return prefBranch.getCharPref(aPrefName);
|
||||
case prefBranch.PREF_INT:
|
||||
return prefBranch.getIntPref(aPrefName);
|
||||
case prefBranch.PREF_BOOL:
|
||||
return prefBranch.getBoolPref(aPrefName);
|
||||
}
|
||||
}
|
||||
catch (ex) { /* return the default value */ }
|
||||
|
||||
return aDefaultValue;
|
||||
},
|
||||
|
||||
_log: function ContentPrefService__log(aMessage) {
|
||||
if (!this._getAppPref("browser.preferences.content.log", false))
|
||||
return;
|
||||
|
||||
aMessage = "*** ContentPrefService: " + aMessage;
|
||||
dump(aMessage + "\n");
|
||||
this._consoleSvc.logStringMessage(aMessage);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
function HostnameGrouper() {}
|
||||
|
||||
HostnameGrouper.prototype = {
|
||||
|
||||
//**************************************************************************//
|
||||
// nsISupports
|
||||
|
||||
_interfaces: [Ci.nsIContentURIGrouper, Ci.nsISupports],
|
||||
|
||||
QueryInterface: function HostnameGrouper_QueryInterface(aIID) {
|
||||
if (!this._interfaces.some( function(v) { return aIID.equals(v) } ))
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
return this;
|
||||
},
|
||||
|
||||
|
||||
//**************************************************************************//
|
||||
// nsIContentURIGrouper
|
||||
|
||||
group: function HostnameGrouper_group(aURI) {
|
||||
var group;
|
||||
|
||||
try {
|
||||
// Accessing the host property of the URI will throw an exception
|
||||
// if the URI is of a type that doesn't have a host property.
|
||||
// Otherwise, we manually throw an exception if the host is empty,
|
||||
// since the effect is the same (we can't derive a group from it).
|
||||
|
||||
group = aURI.host;
|
||||
if (!group)
|
||||
throw("can't derive group from host; no host in URI");
|
||||
}
|
||||
catch(ex) {
|
||||
// If we don't have a host, then use the entire URI (minus the query,
|
||||
// reference, and hash, if possible) as the group. This means that URIs
|
||||
// like about:mozilla and about:blank will be considered separate groups,
|
||||
// but at least they'll be grouped somehow.
|
||||
|
||||
// This also means that each individual file: URL will be considered
|
||||
// its own group. This seems suboptimal, but so does treating the entire
|
||||
// file: URL space as a single group (especially if folks start setting
|
||||
// group-specific capabilities prefs).
|
||||
|
||||
// XXX Is there something better we can do here?
|
||||
|
||||
try {
|
||||
var url = aURI.QueryInterface(Ci.nsIURL);
|
||||
group = aURI.prePath + url.filePath;
|
||||
}
|
||||
catch(ex) {
|
||||
group = aURI.spec;
|
||||
}
|
||||
}
|
||||
|
||||
return group;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
var gModule = {
|
||||
registerSelf: function(aComponentManager, aFileSpec, aLocation, aType) {
|
||||
aComponentManager = aComponentManager.QueryInterface(Ci.nsIComponentRegistrar);
|
||||
|
||||
for (var key in this._objects) {
|
||||
var obj = this._objects[key];
|
||||
aComponentManager.registerFactoryLocation(obj.CID,
|
||||
obj.className,
|
||||
obj.contractID,
|
||||
aFileSpec,
|
||||
aLocation,
|
||||
aType);
|
||||
}
|
||||
},
|
||||
|
||||
unregisterSelf: function(aComponentManager, aFileSpec, aLocation) {},
|
||||
|
||||
getClassObject: function(aComponentManager, aCID, aIID) {
|
||||
if (!aIID.equals(Components.interfaces.nsIFactory))
|
||||
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
for (var key in this._objects) {
|
||||
if (aCID.equals(this._objects[key].CID))
|
||||
return this._objects[key].factory;
|
||||
}
|
||||
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
},
|
||||
|
||||
_objects: {
|
||||
service: {
|
||||
CID : Components.ID("{e6a3f533-4ffa-4615-8eb4-d4e72d883fa7}"),
|
||||
contractID : "@mozilla.org/content-pref/service;1",
|
||||
className : "Content Pref Service",
|
||||
factory : ContentPrefServiceFactory = {
|
||||
createInstance: function(aOuter, aIID) {
|
||||
if (aOuter != null)
|
||||
throw Components.results.NS_ERROR_NO_AGGREGATION;
|
||||
var service = new ContentPrefService();
|
||||
service._init();
|
||||
return service.QueryInterface(aIID);
|
||||
}
|
||||
}
|
||||
},
|
||||
grouper: {
|
||||
CID : Components.ID("{8df290ae-dcaa-4c11-98a5-2429a4dc97bb}"),
|
||||
contractID : "@mozilla.org/content-pref/hostname-grouper;1",
|
||||
className : "Hostname Grouper",
|
||||
factory : HostnameGrouperFactory = {
|
||||
createInstance: function(aOuter, aIID) {
|
||||
if (aOuter != null)
|
||||
throw Components.results.NS_ERROR_NO_AGGREGATION;
|
||||
var grouper = new HostnameGrouper();
|
||||
return grouper.QueryInterface(aIID);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
canUnload: function(aComponentManager) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
function NSGetModule(aComponentManager, aFileSpec) {
|
||||
return gModule;
|
||||
}
|
||||
52
toolkit/components/contentprefs/tests/Makefile.in
Executable file
52
toolkit/components/contentprefs/tests/Makefile.in
Executable file
@@ -0,0 +1,52 @@
|
||||
#
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Mozilla.org.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2007
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Dietrich Ayala <dietrich@mozilla.com>
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either of 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 *****
|
||||
|
||||
DEPTH = ../../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = test_toolkit_contentprefs
|
||||
|
||||
ifdef MOZ_PHOENIX
|
||||
XPCSHELL_TESTS = unit
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
163
toolkit/components/contentprefs/tests/unit/head_contentPrefs.js
Executable file
163
toolkit/components/contentprefs/tests/unit/head_contentPrefs.js
Executable file
@@ -0,0 +1,163 @@
|
||||
/* ***** 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 Content Preferences (cpref).
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2007
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Myk Melez <myk@mozilla.org>
|
||||
*
|
||||
* 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 ***** */
|
||||
|
||||
// Inspired by the Places infrastructure in head_bookmarks.js
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cr = Components.results;
|
||||
const Cu = Components.utils;
|
||||
|
||||
const CONTENT_PREFS_DB_FILENAME = "content-prefs.sqlite";
|
||||
|
||||
var ContentPrefTest = {
|
||||
//**************************************************************************//
|
||||
// Convenience Getters
|
||||
|
||||
__dirSvc: null,
|
||||
get _dirSvc() {
|
||||
if (!this.__dirSvc)
|
||||
this.__dirSvc = Cc["@mozilla.org/file/directory_service;1"].
|
||||
getService(Ci.nsIProperties);
|
||||
return this.__dirSvc;
|
||||
},
|
||||
|
||||
__consoleSvc: null,
|
||||
get _consoleSvc() {
|
||||
if (!this.__consoleSvc)
|
||||
this.__consoleSvc = Cc["@mozilla.org/consoleservice;1"].
|
||||
getService(Ci.nsIConsoleService);
|
||||
return this.__consoleSvc;
|
||||
},
|
||||
|
||||
__ioSvc: null,
|
||||
get _ioSvc() {
|
||||
if (!this.__ioSvc)
|
||||
this.__ioSvc = Cc["@mozilla.org/network/io-service;1"].
|
||||
getService(Ci.nsIIOService);
|
||||
return this.__ioSvc;
|
||||
},
|
||||
|
||||
|
||||
//**************************************************************************//
|
||||
// nsISupports
|
||||
|
||||
interfaces: [Ci.nsIDirectoryServiceProvider, Ci.nsISupports],
|
||||
|
||||
QueryInterface: function ContentPrefTest_QueryInterface(iid) {
|
||||
if (!this.interfaces.some( function(v) { return iid.equals(v) } ))
|
||||
throw Cr.NS_ERROR_NO_INTERFACE;
|
||||
return this;
|
||||
},
|
||||
|
||||
|
||||
//**************************************************************************//
|
||||
// nsIDirectoryServiceProvider
|
||||
|
||||
getFile: function ContentPrefTest_getFile(property, persistent) {
|
||||
persistent.value = true;
|
||||
|
||||
if (property == "ProfD")
|
||||
return this._dirSvc.get("CurProcD", Ci.nsIFile);
|
||||
|
||||
// This causes extraneous errors to show up in the log when the directory
|
||||
// service asks us first for CurProcD and MozBinD. I wish there was a way
|
||||
// to suppress those errors.
|
||||
throw Cr.NS_ERROR_FAILURE;
|
||||
},
|
||||
|
||||
|
||||
//**************************************************************************//
|
||||
// Utilities
|
||||
|
||||
getURI: function ContentPrefTest_getURI(spec) {
|
||||
return this._ioSvc.newURI(spec, null, null);
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the profile directory, registering ourselves as a provider
|
||||
* of that directory if necessary.
|
||||
*/
|
||||
getProfileDir: function ContentPrefTest_getProfileDir() {
|
||||
var profileDir;
|
||||
|
||||
try {
|
||||
profileDir = this._dirSvc.get("ProfD", Ci.nsIFile);
|
||||
}
|
||||
catch (e) {}
|
||||
|
||||
if (!profileDir) {
|
||||
this._dirSvc.QueryInterface(Ci.nsIDirectoryService).registerProvider(this);
|
||||
profileDir = this._dirSvc.get("ProfD", Ci.nsIFile);
|
||||
}
|
||||
|
||||
return profileDir;
|
||||
},
|
||||
|
||||
/**
|
||||
* Delete the content pref service's persistent datastore. We do this before
|
||||
* and after running tests to make sure we start from scratch each time.
|
||||
*/
|
||||
deleteDatabase: function ContentPrefTest_deleteDatabase() {
|
||||
try {
|
||||
var file = this.getProfileDir()
|
||||
file.append(CONTENT_PREFS_DB_FILENAME);
|
||||
if (file.exists())
|
||||
file.remove(false);
|
||||
}
|
||||
catch(ex) {
|
||||
Cu.reportError(ex);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Log a message to the console and the test log.
|
||||
*/
|
||||
log: function ContentPrefTest_log(message) {
|
||||
message = "*** ContentPrefTest: " + message;
|
||||
this._consoleSvc.logStringMessage(message);
|
||||
print(message);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
ContentPrefTest.deleteDatabase();
|
||||
|
||||
// Turn on logging for the content preferences service so we can troubleshoot
|
||||
// problems with the tests.
|
||||
var prefBranch = Cc["@mozilla.org/preferences-service;1"].
|
||||
getService(Ci.nsIPrefBranch);
|
||||
prefBranch.setBoolPref("browser.preferences.content.log", true);
|
||||
37
toolkit/components/contentprefs/tests/unit/tail_contentPrefs.js
Executable file
37
toolkit/components/contentprefs/tests/unit/tail_contentPrefs.js
Executable file
@@ -0,0 +1,37 @@
|
||||
/* ***** 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 Content Preferences (cpref).
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2007
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Myk Melez <myk@mozilla.org>
|
||||
*
|
||||
* 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 ***** */
|
||||
|
||||
ContentPrefTest.deleteDatabase();
|
||||
244
toolkit/components/contentprefs/tests/unit/test_contentPrefs.js
Executable file
244
toolkit/components/contentprefs/tests/unit/test_contentPrefs.js
Executable file
@@ -0,0 +1,244 @@
|
||||
/* ***** 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 Content Preferences (cpref).
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2007
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Myk Melez <myk@mozilla.org>
|
||||
*
|
||||
* 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 ***** */
|
||||
|
||||
function run_test() {
|
||||
var cps = Cc["@mozilla.org/content-pref/service;1"].
|
||||
getService(Ci.nsIContentPrefService);
|
||||
var uri = ContentPrefTest.getURI("http://www.example.com/");
|
||||
|
||||
//**************************************************************************//
|
||||
// Nonexistent Pref
|
||||
|
||||
do_check_eq(cps.getPref(uri, "test.nonexistent.getPref"), undefined);
|
||||
do_check_eq(cps.setPref(uri, "test.nonexistent.setPref", 5), undefined);
|
||||
do_check_false(cps.hasPref(uri, "test.nonexistent.hasPref"));
|
||||
do_check_eq(cps.removePref(uri, "test.nonexistent.removePref"), undefined);
|
||||
|
||||
|
||||
//**************************************************************************//
|
||||
// Existing Pref
|
||||
|
||||
cps.setPref(uri, "test.existing", 5);
|
||||
|
||||
// getPref should return the pref value
|
||||
do_check_eq(cps.getPref(uri, "test.existing"), 5);
|
||||
|
||||
// setPref should return undefined and change the value of the pref
|
||||
do_check_eq(cps.setPref(uri, "test.existing", 6), undefined);
|
||||
do_check_eq(cps.getPref(uri, "test.existing"), 6);
|
||||
|
||||
// hasPref should return true
|
||||
do_check_true(cps.hasPref(uri, "test.existing"));
|
||||
|
||||
// removePref should return undefined and remove the pref
|
||||
do_check_eq(cps.removePref(uri, "test.existing"), undefined);
|
||||
do_check_false(cps.hasPref(uri, "test.existing"));
|
||||
|
||||
|
||||
//**************************************************************************//
|
||||
// Round-Trip Data Integrity
|
||||
|
||||
// Make sure pref values remain the same from setPref to getPref.
|
||||
|
||||
cps.setPref(uri, "test.data-integrity.integer", 5);
|
||||
do_check_eq(cps.getPref(uri, "test.data-integrity.integer"), 5);
|
||||
|
||||
cps.setPref(uri, "test.data-integrity.float", 5.5);
|
||||
do_check_eq(cps.getPref(uri, "test.data-integrity.float"), 5.5);
|
||||
|
||||
cps.setPref(uri, "test.data-integrity.boolean", true);
|
||||
do_check_eq(cps.getPref(uri, "test.data-integrity.boolean"), true);
|
||||
|
||||
cps.setPref(uri, "test.data-integrity.string", "test");
|
||||
do_check_eq(cps.getPref(uri, "test.data-integrity.string"), "test");
|
||||
|
||||
cps.setPref(uri, "test.data-integrity.null", null);
|
||||
do_check_eq(cps.getPref(uri, "test.data-integrity.null"), null);
|
||||
|
||||
// XXX Test arbitrary binary data.
|
||||
|
||||
// Make sure hasPref and removePref work on all data types.
|
||||
|
||||
do_check_true(cps.hasPref(uri, "test.data-integrity.integer"));
|
||||
do_check_true(cps.hasPref(uri, "test.data-integrity.float"));
|
||||
do_check_true(cps.hasPref(uri, "test.data-integrity.boolean"));
|
||||
do_check_true(cps.hasPref(uri, "test.data-integrity.string"));
|
||||
do_check_true(cps.hasPref(uri, "test.data-integrity.null"));
|
||||
|
||||
do_check_eq(cps.removePref(uri, "test.data-integrity.integer"), undefined);
|
||||
do_check_eq(cps.removePref(uri, "test.data-integrity.float"), undefined);
|
||||
do_check_eq(cps.removePref(uri, "test.data-integrity.boolean"), undefined);
|
||||
do_check_eq(cps.removePref(uri, "test.data-integrity.string"), undefined);
|
||||
do_check_eq(cps.removePref(uri, "test.data-integrity.null"), undefined);
|
||||
|
||||
do_check_false(cps.hasPref(uri, "test.data-integrity.integer"));
|
||||
do_check_false(cps.hasPref(uri, "test.data-integrity.float"));
|
||||
do_check_false(cps.hasPref(uri, "test.data-integrity.boolean"));
|
||||
do_check_false(cps.hasPref(uri, "test.data-integrity.string"));
|
||||
do_check_false(cps.hasPref(uri, "test.data-integrity.null"));
|
||||
|
||||
|
||||
//**************************************************************************//
|
||||
// getPrefs
|
||||
|
||||
cps.setPref(uri, "test.getPrefs.a", 1);
|
||||
cps.setPref(uri, "test.getPrefs.b", 2);
|
||||
cps.setPref(uri, "test.getPrefs.c", 3);
|
||||
|
||||
var prefs = cps.getPrefs(uri);
|
||||
do_check_true(prefs.hasKey("test.getPrefs.a"));
|
||||
do_check_eq(prefs.get("test.getPrefs.a"), 1);
|
||||
do_check_true(prefs.hasKey("test.getPrefs.b"));
|
||||
do_check_eq(prefs.get("test.getPrefs.b"), 2);
|
||||
do_check_true(prefs.hasKey("test.getPrefs.c"));
|
||||
do_check_eq(prefs.get("test.getPrefs.c"), 3);
|
||||
|
||||
|
||||
//**************************************************************************//
|
||||
// Site-Specificity
|
||||
|
||||
// These are all different sites, and setting a pref for one of them
|
||||
// shouldn't set it for the others.
|
||||
var uri1 = ContentPrefTest.getURI("http://www.domain1.com/");
|
||||
var uri2 = ContentPrefTest.getURI("http://foo.domain1.com/");
|
||||
var uri3 = ContentPrefTest.getURI("http://domain1.com/");
|
||||
var uri4 = ContentPrefTest.getURI("http://www.domain2.com/");
|
||||
|
||||
cps.setPref(uri1, "test.site-specificity.uri1", 5);
|
||||
do_check_false(cps.hasPref(uri2, "test.site-specificity.uri1"));
|
||||
do_check_false(cps.hasPref(uri3, "test.site-specificity.uri1"));
|
||||
do_check_false(cps.hasPref(uri4, "test.site-specificity.uri1"));
|
||||
|
||||
cps.setPref(uri2, "test.site-specificity.uri2", 5);
|
||||
do_check_false(cps.hasPref(uri1, "test.site-specificity.uri2"));
|
||||
do_check_false(cps.hasPref(uri3, "test.site-specificity.uri2"));
|
||||
do_check_false(cps.hasPref(uri4, "test.site-specificity.uri2"));
|
||||
|
||||
cps.setPref(uri3, "test.site-specificity.uri3", 5);
|
||||
do_check_false(cps.hasPref(uri1, "test.site-specificity.uri3"));
|
||||
do_check_false(cps.hasPref(uri2, "test.site-specificity.uri3"));
|
||||
do_check_false(cps.hasPref(uri4, "test.site-specificity.uri3"));
|
||||
|
||||
cps.setPref(uri4, "test.site-specificity.uri4", 5);
|
||||
do_check_false(cps.hasPref(uri1, "test.site-specificity.uri4"));
|
||||
do_check_false(cps.hasPref(uri2, "test.site-specificity.uri4"));
|
||||
do_check_false(cps.hasPref(uri3, "test.site-specificity.uri4"));
|
||||
|
||||
|
||||
//**************************************************************************//
|
||||
// Observers
|
||||
|
||||
var specificObserver = {
|
||||
interfaces: [Ci.nsIContentPrefObserver, Ci.nsISupports],
|
||||
|
||||
QueryInterface: function ContentPrefTest_QueryInterface(iid) {
|
||||
if (!this.interfaces.some( function(v) { return iid.equals(v) } ))
|
||||
throw Cr.NS_ERROR_NO_INTERFACE;
|
||||
return this;
|
||||
},
|
||||
|
||||
numTimesSetCalled: 0,
|
||||
onContentPrefSet: function specificObserver_onContentPrefSet(group, name, value) {
|
||||
++this.numTimesSetCalled;
|
||||
do_check_eq(group, "www.example.com");
|
||||
do_check_eq(name, "test.observer.1");
|
||||
do_check_eq(value, "test value");
|
||||
},
|
||||
|
||||
numTimesRemovedCalled: 0,
|
||||
onContentPrefRemoved: function specificObserver_onContentPrefRemoved(group, name) {
|
||||
++this.numTimesRemovedCalled;
|
||||
do_check_eq(group, "www.example.com");
|
||||
do_check_eq(name, "test.observer.1");
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
var genericObserver = {
|
||||
interfaces: [Ci.nsIContentPrefObserver, Ci.nsISupports],
|
||||
|
||||
QueryInterface: function ContentPrefTest_QueryInterface(iid) {
|
||||
if (!this.interfaces.some( function(v) { return iid.equals(v) } ))
|
||||
throw Cr.NS_ERROR_NO_INTERFACE;
|
||||
return this;
|
||||
},
|
||||
|
||||
numTimesSetCalled: 0,
|
||||
onContentPrefSet: function genericObserver_onContentPrefSet(group, name, value) {
|
||||
++this.numTimesSetCalled;
|
||||
do_check_eq(group, "www.example.com");
|
||||
if (name != "test.observer.1" && name != "test.observer.2")
|
||||
do_throw("genericObserver.onContentPrefSet: " +
|
||||
"name not in (test.observer.1, test.observer.2)");
|
||||
do_check_eq(value, "test value");
|
||||
},
|
||||
|
||||
numTimesRemovedCalled: 0,
|
||||
onContentPrefRemoved: function genericObserver_onContentPrefRemoved(group, name) {
|
||||
++this.numTimesRemovedCalled;
|
||||
do_check_eq(group, "www.example.com");
|
||||
if (name != "test.observer.1" && name != "test.observer.2")
|
||||
do_throw("genericObserver.onContentPrefSet: " +
|
||||
"name not in (test.observer.1, test.observer.2)");
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// Make sure we can add observers, observers get notified about changes,
|
||||
// specific observers only get notified about changes to the specific setting,
|
||||
// and generic observers get notified about changes to all settings.
|
||||
cps.addObserver("test.observer.1", specificObserver);
|
||||
cps.addObserver(null, genericObserver);
|
||||
cps.setPref(uri, "test.observer.1", "test value");
|
||||
cps.setPref(uri, "test.observer.2", "test value");
|
||||
cps.removePref(uri, "test.observer.1");
|
||||
cps.removePref(uri, "test.observer.2");
|
||||
do_check_eq(specificObserver.numTimesSetCalled, 1);
|
||||
do_check_eq(genericObserver.numTimesSetCalled, 2);
|
||||
do_check_eq(specificObserver.numTimesRemovedCalled, 1);
|
||||
do_check_eq(genericObserver.numTimesRemovedCalled, 2);
|
||||
|
||||
// Make sure we can remove observers and they don't get notified
|
||||
// about changes anymore.
|
||||
cps.removeObserver("test.observer.1", specificObserver);
|
||||
cps.removeObserver(null, genericObserver);
|
||||
cps.setPref(uri, "test.observer.1", "test value");
|
||||
cps.removePref(uri, "test.observer.1", "test value");
|
||||
do_check_eq(specificObserver.numTimesSetCalled, 1);
|
||||
do_check_eq(genericObserver.numTimesSetCalled, 2);
|
||||
do_check_eq(specificObserver.numTimesRemovedCalled, 1);
|
||||
do_check_eq(genericObserver.numTimesRemovedCalled, 2);
|
||||
}
|
||||
Reference in New Issue
Block a user