bug 385224: optimize performance of site-specific preferences; r=mconnor,roc

This commit is contained in:
myk@mozilla.org 2007-11-26 00:35:22 -08:00
parent 5e7ee1a7dc
commit 759b2a5934
7 changed files with 87 additions and 398 deletions

View File

@ -1,243 +0,0 @@
/*
#ifdef 0
* ***** 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 *****
#endif
*/
/**
* Listens for site-specific pref-related events and dispatches them
* to setting controllers.
*/
var ContentPrefSink = {
//**************************************************************************//
// Convenience Getters
// Content Pref Service
__cps: null,
get _cps() {
if (!this.__cps)
this.__cps = Cc["@mozilla.org/content-pref/service;1"].
getService(Ci.nsIContentPrefService);
return this.__cps;
},
//**************************************************************************//
// nsISupports
// Note: we can't use the Ci shortcut here because it isn't defined yet.
interfaces: [Components.interfaces.nsIDOMEventListener,
Components.interfaces.nsISupports],
QueryInterface: function ContentPrefSink_QueryInterface(iid) {
if (!this.interfaces.some( function(v) { return iid.equals(v) } ))
throw Cr.NS_ERROR_NO_INTERFACE;
return this;
},
//**************************************************************************//
// Initialization & Destruction
init: function ContentPrefSink_init() {
gBrowser.addEventListener("DOMContentLoaded", this, false);
// XXX Should we also listen for pageshow and/or load?
},
destroy: function ContentPrefSink_destroy() {
gBrowser.removeEventListener("DOMContentLoaded", this, false);
// Delete references to XPCOM components to make sure we don't leak them
// (although we haven't observed leakage in tests). Also delete references
// in _observers and _genericObservers to avoid cycles with those that
// refer to us and don't remove themselves from those observer pools.
for (var i in this) {
try { this[i] = null }
// Ignore "setting a property that has only a getter" exceptions.
catch(ex) {}
}
},
//**************************************************************************//
// Event Handlers
// nsIDOMEventListener
handleEvent: function ContentPrefSink_handleEvent(event) {
// The only events we handle are DOMContentLoaded events.
this._handleDOMContentLoaded(event);
},
handleLocationChanged: function ContentPrefSink_handleLocationChanged(uri) {
if (!uri)
return;
var prefs = this._cps.getPrefs(uri);
for (var name in this._observers) {
var value = prefs.hasKey(name) ? prefs.get(name) : undefined;
for each (var observer in this._observers[name])
if (observer.onLocationChanged) {
try {
observer.onLocationChanged(uri, name, value);
}
catch(ex) {
Components.utils.reportError(ex);
}
}
}
for each (var observer in this._genericObservers)
if (observer.onLocationChanged) {
try {
observer.onLocationChanged(uri, prefs);
}
catch(ex) {
Components.utils.reportError(ex);
}
}
},
_handleDOMContentLoaded: function ContentPrefSink__handleDOMContentLoaded(event) {
var browser = gBrowser.getBrowserForDocument(event.target);
// If the document isn't one of the ones loaded into a top-level browser,
// don't notify observers about it. XXX Might some observers want to know
// about documents loaded into iframes?
if (!browser)
return;
var uri = browser.currentURI;
var prefs = this._cps.getPrefs(uri);
for (var name in this._observers) {
var value = prefs.hasKey(name) ? prefs.get(name) : undefined;
for each (var observer in this._observers[name]) {
if (observer.onDOMContentLoaded) {
try {
observer.onDOMContentLoaded(event, name, value);
}
catch(ex) {
Components.utils.reportError(ex);
}
}
}
}
for each (var observer in this._genericObservers) {
if (observer.onDOMContentLoaded) {
try {
observer.onDOMContentLoaded(event, prefs);
}
catch(ex) {
Components.utils.reportError(ex);
}
}
}
},
//**************************************************************************//
// Sink Observers
_observers: {},
_genericObservers: [],
// Note: this isn't an XPCOM interface (for performance and so we can pass
// nsIVariants), although it resembles nsIObserverService. Sink observers
// are regular JS objects, and they get called directly, not via XPConnect.
/**
* Add an observer.
*
* The observer can be setting-specific or generic, which affects what it
* gets handed when the sink notifies it about an event. A setting-specific
* observer gets handed the value of its pref for the target page, while
* a generic observer gets handed the values of all prefs for the target page.
*
* @param name the name of the setting for which to add an observer,
* or null to add a generic observer
* @param observer the observer to add
*
* @returns if setting-specific, the global preference for the setting
* if generic, null
*/
addObserver: function ContentPrefSink_addObserver(name, observer) {
var observers;
if (name) {
if (!this._observers[name])
this._observers[name] = [];
observers = this._observers[name];
}
else
observers = this._genericObservers;
if (observers.indexOf(observer) == -1)
observers.push(observer);
return name ? this._cps.getPref(null, name) : null;
},
/**
* Remove an observer.
*
* @param name the name of the setting for which to remove
* an observer, or null to remove a generic observer
* @param observer the observer to remove
*/
removeObserver: function ContentPrefSink_removeObserver(name, observer) {
var observers = name ? this._observers[name] : this._genericObservers;
if (observers.indexOf(observer) != -1)
observers.splice(observers.indexOf(observer), 1);
},
_getObservers: function ContentPrefSink__getObservers(name) {
var observers = [];
// Construct the list of observers, putting setting-specific ones before
// generic ones, so observers that initialize individual settings (like
// the page style controller) execute before observers that do something
// with multiple settings and depend on them being initialized first
// (f.e. the content prefs sidebar).
if (name && this._observers[name])
observers = observers.concat(this._observers[name]);
observers = observers.concat(this._genericObservers);
return observers;
}
};

View File

@ -57,17 +57,23 @@ var FullZoom = {
// The name of the setting. Identifies the setting in the prefs database.
name: "browser.content.full-zoom",
// The global value (if any) for the setting. Retrieved from the prefs
// database when this handler gets initialized, then updated as it changes.
// The global value (if any) for the setting. Lazily loaded from the service
// when first requested, then updated by the pref change listener as it changes.
// If there is no global value, then this should be undefined.
globalValue: undefined,
get globalValue FullZoom_get_globalValue() {
var globalValue = this._cps.getPref(null, this.name);
if (typeof globalValue != "undefined")
globalValue = this._ensureValid(globalValue);
delete this.globalValue;
return this.globalValue = globalValue;
},
//**************************************************************************//
// Convenience Getters
// Content Pref Service
get _cps() {
get _cps FullZoom_get__cps() {
delete this._cps;
return this._cps = Cc["@mozilla.org/content-pref/service;1"].
getService(Ci.nsIContentPrefService);
@ -82,7 +88,7 @@ var FullZoom = {
Components.interfaces.nsIContentPrefObserver,
Components.interfaces.nsISupports],
QueryInterface: function (aIID) {
QueryInterface: function FullZoom_QueryInterface(aIID) {
if (!this.interfaces.some(function (v) aIID.equals(v)))
throw Cr.NS_ERROR_NO_INTERFACE;
return this;
@ -92,33 +98,18 @@ var FullZoom = {
//**************************************************************************//
// Initialization & Destruction
init: function () {
init: function FullZoom_init() {
// Listen for scrollwheel events so we can save scrollwheel-based changes.
window.addEventListener("DOMMouseScroll", this, false);
// Register ourselves with the service so we know when our pref changes.
this._cps.addObserver(this.name, this);
// Register ourselves with the sink so we know when the location changes.
var globalValue = ContentPrefSink.addObserver(this.name, this);
this.globalValue = this._ensureValid(globalValue);
// Set the initial value of the setting.
this._applyPrefToSetting();
},
destroy: function () {
ContentPrefSink.removeObserver(this.name, this);
destroy: function FullZoom_destroy() {
this._cps.removeObserver(this.name, this);
window.removeEventListener("DOMMouseScroll", this, false);
// Delete references to XPCOM components to make sure we don't leak them
// (although we haven't observed leakage in tests).
for (var i in this) {
try { this[i] = null }
// Ignore "setting a property that has only a getter" exceptions.
catch(ex) {}
}
delete this._cps;
},
@ -127,7 +118,7 @@ var FullZoom = {
// nsIDOMEventListener
handleEvent: function (event) {
handleEvent: function FullZoom_handleEvent(event) {
switch (event.type) {
case "DOMMouseScroll":
this._handleMouseScrolled(event);
@ -135,7 +126,7 @@ var FullZoom = {
}
},
_handleMouseScrolled: function (event) {
_handleMouseScrolled: function FullZoom__handleMouseScrolled(event) {
// Construct the "mousewheel action" pref key corresponding to this event.
// Based on nsEventStateManager::GetBasePrefKeyForMouseWheel.
var pref = "mousewheel";
@ -175,7 +166,7 @@ var FullZoom = {
// nsIContentPrefObserver
onContentPrefSet: function (aGroup, aName, aValue) {
onContentPrefSet: function FullZoom_onContentPrefSet(aGroup, aName, aValue) {
if (aGroup == this._cps.grouper.group(gBrowser.currentURI))
this._applyPrefToSetting(aValue);
else if (aGroup == null) {
@ -189,7 +180,7 @@ var FullZoom = {
}
},
onContentPrefRemoved: function (aGroup, aName) {
onContentPrefRemoved: function FullZoom_onContentPrefRemoved(aGroup, aName) {
if (aGroup == this._cps.grouper.group(gBrowser.currentURI))
this._applyPrefToSetting();
else if (aGroup == null) {
@ -203,27 +194,29 @@ var FullZoom = {
}
},
// ContentPrefSink observer
// location change observer
onLocationChanged: function (aURI, aName, aValue) {
this._applyPrefToSetting(aValue);
onLocationChange: function FullZoom_onLocationChange(aURI) {
if (!aURI)
return;
this._applyPrefToSetting(this._cps.getPref(aURI, this.name));
},
//**************************************************************************//
// Setting & Pref Manipulation
reduce: function () {
reduce: function FullZoom_reduce() {
ZoomManager.reduce();
this._applySettingToPref();
},
enlarge: function () {
enlarge: function FullZoom_enlarge() {
ZoomManager.enlarge();
this._applySettingToPref();
},
reset: function () {
reset: function FullZoom_reset() {
if (typeof this.globalValue != "undefined")
ZoomManager.fullZoom = this.globalValue;
else
@ -232,7 +225,7 @@ var FullZoom = {
this._removePref();
},
setSettingValue: function () {
setSettingValue: function FullZoom_setSettingValue() {
var value = this._cps.getPref(gBrowser.currentURI, this.name);
this._applyPrefToSetting(value);
},
@ -240,38 +233,38 @@ var FullZoom = {
/**
* Set the zoom level for the current tab.
*
* Per DocumentViewerImpl::SetFullZoom in nsDocumentViewer.cpp, it looks
* like we can set the zoom to its current value without significant impact
* on performance, as the setting is only applied if it differs from the
* current setting.
*
* And perhaps we should always set the zoom even if it were to incur
* a performance penalty, since SetFullZoom claims that child documents
* may have a different zoom under unusual circumstances, and it implies
* that those child zooms should get updated when the parent zoom gets set.
* Per nsPresContext::setFullZoom, we can set the zoom to its current value
* without significant impact on performance, as the setting is only applied
* if it differs from the current setting. In fact getting the zoom and then
* checking ourselves if it differs costs more.
*
* And perhaps we should always set the zoom even if it was more expensive,
* since DocumentViewerImpl::SetTextZoom claims that child documents can have
* a different text zoom (although it would be unusual), and it implies that
* those child text zooms should get updated when the parent zoom gets set,
* and perhaps the same is true for full zoom
* (although DocumentViewerImpl::SetFullZoom doesn't mention it).
*
* So when we apply new zoom values to the browser, we simply set the zoom.
* We don't check first to see if the new value is the same as the current
* one.
**/
_applyPrefToSetting: function (aValue) {
_applyPrefToSetting: function FullZoom__applyPrefToSetting(aValue) {
if (gInPrintPreviewMode)
return;
// Bug 375918 means this will sometimes throw, so we catch it
// and don't do anything in those cases.
try {
if (typeof aValue != "undefined")
ZoomManager.fullZoom = this._ensureValid(aValue);
else if (typeof this.globalValue != "undefined")
ZoomManager.fullZoom = this.globalValue;
else
ZoomManager.reset();
ZoomManager.fullZoom = 1;
}
catch(ex) {}
},
_applySettingToPref: function () {
_applySettingToPref: function FullZoom__applySettingToPref() {
if (gInPrintPreviewMode)
return;
@ -279,7 +272,7 @@ var FullZoom = {
this._cps.setPref(gBrowser.currentURI, this.name, fullZoom);
},
_removePref: function () {
_removePref: function FullZoom__removePref() {
this._cps.removePref(gBrowser.currentURI, this.name);
},
@ -287,7 +280,7 @@ var FullZoom = {
//**************************************************************************//
// Utilities
_ensureValid: function (aValue) {
_ensureValid: function FullZoom__ensureValid(aValue) {
if (isNaN(aValue))
return 1;

View File

@ -1120,11 +1120,10 @@ function delayedStartup()
Components.utils.reportError("Failed to init microsummary service:\n" + ex);
}
// Initialize the content pref event sink and the text zoom setting.
// Initialize the full zoom setting.
// We do this before the session restore service gets initialized so we can
// apply text zoom settings to tabs restored by the session restore service.
// apply full zoom settings to tabs restored by the session restore service.
try {
ContentPrefSink.init();
FullZoom.init();
}
catch(ex) {
@ -1175,7 +1174,6 @@ function BrowserShutdown()
{
try {
FullZoom.destroy();
ContentPrefSink.destroy();
}
catch(ex) {
Components.utils.reportError(ex);
@ -3726,7 +3724,7 @@ nsBrowserStatusHandler.prototype =
// Catch exceptions until bug 376222 gets fixed so we don't hork
// other progress listeners if this call throws an exception.
try {
ContentPrefSink.handleLocationChanged(aLocationURI);
FullZoom.onLocationChange(aLocationURI);
}
catch(ex) {
Components.utils.reportError(ex);
@ -5445,7 +5443,6 @@ var FeedHandler = {
#include browser-places.js
#include browser-contentPrefSink.js
#include browser-textZoom.js
HistoryMenu.toggleRecentlyClosedTabs = function PHM_toggleRecentlyClosedTabs() {

View File

@ -1151,19 +1151,17 @@ nsPresContext::GetDefaultFontExternal(PRUint8 aFontID) const
void
nsPresContext::SetFullZoom(float aZoom)
{
float oldWidth = mVisibleArea.width / float(mCurAppUnitsPerDevPixel);
float oldHeight = mVisibleArea.height / float(mCurAppUnitsPerDevPixel);
if (!mShell) {
if (!mShell || mFullZoom == aZoom) {
return;
}
float oldWidth = mVisibleArea.width / float(mCurAppUnitsPerDevPixel);
float oldHeight = mVisibleArea.height / float(mCurAppUnitsPerDevPixel);
if (mDeviceContext->SetPixelScale(aZoom)) {
mDeviceContext->FlushFontCache();
}
if (mFullZoom != aZoom) {
mFullZoom = aZoom;
GetViewManager()->SetWindowDimensions(oldWidth * AppUnitsPerDevPixel(), oldHeight * AppUnitsPerDevPixel());
ClearStyleDataAndReflow();
}
mFullZoom = aZoom;
GetViewManager()->SetWindowDimensions(oldWidth * AppUnitsPerDevPixel(), oldHeight * AppUnitsPerDevPixel());
ClearStyleDataAndReflow();
mCurAppUnitsPerDevPixel = AppUnitsPerDevPixel();
}

View File

@ -67,7 +67,7 @@ ContentPrefService.prototype = {
// Observer Service
__observerSvc: null,
get _observerSvc() {
get _observerSvc ContentPrefService_get__observerSvc() {
if (!this.__observerSvc)
this.__observerSvc = Cc["@mozilla.org/observer-service;1"].
getService(Ci.nsIObserverService);
@ -76,7 +76,7 @@ ContentPrefService.prototype = {
// Console Service
__consoleSvc: null,
get _consoleSvc() {
get _consoleSvc ContentPrefService_get__consoleSvc() {
if (!this.__consoleSvc)
this.__consoleSvc = Cc["@mozilla.org/consoleservice;1"].
getService(Ci.nsIConsoleService);
@ -263,7 +263,7 @@ ContentPrefService.prototype = {
},
_grouper: null,
get grouper() {
get grouper ContentPrefService_get_grouper() {
if (!this._grouper)
this._grouper = Cc["@mozilla.org/content-pref/hostname-grouper;1"].
getService(Ci.nsIContentURIGrouper);
@ -275,7 +275,7 @@ ContentPrefService.prototype = {
// Data Retrieval & Modification
__stmtSelectPref: null,
get _stmtSelectPref() {
get _stmtSelectPref ContentPrefService_get__stmtSelectPref() {
if (!this.__stmtSelectPref)
this.__stmtSelectPref = this._dbCreateStatement(
"SELECT prefs.value AS value " +
@ -307,7 +307,7 @@ ContentPrefService.prototype = {
},
__stmtSelectGlobalPref: null,
get _stmtSelectGlobalPref() {
get _stmtSelectGlobalPref ContentPrefService_get__stmtSelectGlobalPref() {
if (!this.__stmtSelectGlobalPref)
this.__stmtSelectGlobalPref = this._dbCreateStatement(
"SELECT prefs.value AS value " +
@ -337,7 +337,7 @@ ContentPrefService.prototype = {
},
__stmtSelectGroupID: null,
get _stmtSelectGroupID() {
get _stmtSelectGroupID ContentPrefService_get__stmtSelectGroupID() {
if (!this.__stmtSelectGroupID)
this.__stmtSelectGroupID = this._dbCreateStatement(
"SELECT groups.id AS id " +
@ -365,7 +365,7 @@ ContentPrefService.prototype = {
},
__stmtInsertGroup: null,
get _stmtInsertGroup() {
get _stmtInsertGroup ContentPrefService_get__stmtInsertGroup() {
if (!this.__stmtInsertGroup)
this.__stmtInsertGroup = this._dbCreateStatement(
"INSERT INTO groups (name) VALUES (:name)"
@ -381,7 +381,7 @@ ContentPrefService.prototype = {
},
__stmtSelectSettingID: null,
get _stmtSelectSettingID() {
get _stmtSelectSettingID ContentPrefService_get__stmtSelectSettingID() {
if (!this.__stmtSelectSettingID)
this.__stmtSelectSettingID = this._dbCreateStatement(
"SELECT id FROM settings WHERE name = :name"
@ -407,7 +407,7 @@ ContentPrefService.prototype = {
},
__stmtInsertSetting: null,
get _stmtInsertSetting() {
get _stmtInsertSetting ContentPrefService_get__stmtInsertSetting() {
if (!this.__stmtInsertSetting)
this.__stmtInsertSetting = this._dbCreateStatement(
"INSERT INTO settings (name) VALUES (:name)"
@ -423,7 +423,7 @@ ContentPrefService.prototype = {
},
__stmtSelectPrefID: null,
get _stmtSelectPrefID() {
get _stmtSelectPrefID ContentPrefService_get__stmtSelectPrefID() {
if (!this.__stmtSelectPrefID)
this.__stmtSelectPrefID = this._dbCreateStatement(
"SELECT id FROM prefs WHERE groupID = :groupID AND settingID = :settingID"
@ -450,7 +450,7 @@ ContentPrefService.prototype = {
},
__stmtSelectGlobalPrefID: null,
get _stmtSelectGlobalPrefID() {
get _stmtSelectGlobalPrefID ContentPrefService_get__stmtSelectGlobalPrefID() {
if (!this.__stmtSelectGlobalPrefID)
this.__stmtSelectGlobalPrefID = this._dbCreateStatement(
"SELECT id FROM prefs WHERE groupID IS NULL AND settingID = :settingID"
@ -476,7 +476,7 @@ ContentPrefService.prototype = {
},
__stmtInsertPref: null,
get _stmtInsertPref() {
get _stmtInsertPref ContentPrefService_get__stmtInsertPref() {
if (!this.__stmtInsertPref)
this.__stmtInsertPref = this._dbCreateStatement(
"INSERT INTO prefs (groupID, settingID, value) " +
@ -495,7 +495,7 @@ ContentPrefService.prototype = {
},
__stmtUpdatePref: null,
get _stmtUpdatePref() {
get _stmtUpdatePref ContentPrefService_get__stmtUpdatePref() {
if (!this.__stmtUpdatePref)
this.__stmtUpdatePref = this._dbCreateStatement(
"UPDATE prefs SET value = :value WHERE id = :id"
@ -511,7 +511,7 @@ ContentPrefService.prototype = {
},
__stmtDeletePref: null,
get _stmtDeletePref() {
get _stmtDeletePref ContentPrefService_get__stmtDeletePref() {
if (!this.__stmtDeletePref)
this.__stmtDeletePref = this._dbCreateStatement(
"DELETE FROM prefs WHERE id = :id"
@ -526,7 +526,7 @@ ContentPrefService.prototype = {
},
__stmtDeleteSettingIfUnused: null,
get _stmtDeleteSettingIfUnused() {
get _stmtDeleteSettingIfUnused ContentPrefService_get__stmtDeleteSettingIfUnused() {
if (!this.__stmtDeleteSettingIfUnused)
this.__stmtDeleteSettingIfUnused = this._dbCreateStatement(
"DELETE FROM settings WHERE id = :id " +
@ -542,7 +542,7 @@ ContentPrefService.prototype = {
},
__stmtDeleteGroupIfUnused: null,
get _stmtDeleteGroupIfUnused() {
get _stmtDeleteGroupIfUnused ContentPrefService_get__stmtDeleteGroupIfUnused() {
if (!this.__stmtDeleteGroupIfUnused)
this.__stmtDeleteGroupIfUnused = this._dbCreateStatement(
"DELETE FROM groups WHERE id = :id " +
@ -558,7 +558,7 @@ ContentPrefService.prototype = {
},
__stmtSelectPrefs: null,
get _stmtSelectPrefs() {
get _stmtSelectPrefs ContentPrefService_get__stmtSelectPrefs() {
if (!this.__stmtSelectPrefs)
this.__stmtSelectPrefs = this._dbCreateStatement(
"SELECT settings.name AS name, prefs.value AS value " +
@ -590,7 +590,7 @@ ContentPrefService.prototype = {
},
__stmtSelectGlobalPrefs: null,
get _stmtSelectGlobalPrefs() {
get _stmtSelectGlobalPrefs ContentPrefService_get__stmtSelectGlobalPrefs() {
if (!this.__stmtSelectGlobalPrefs)
this.__stmtSelectGlobalPrefs = this._dbCreateStatement(
"SELECT settings.name AS name, prefs.value AS value " +
@ -639,7 +639,7 @@ ContentPrefService.prototype = {
_dbConnection: null,
_dbCreateStatement: function(aSQLString) {
_dbCreateStatement: function ContentPrefService__dbCreateStatement(aSQLString) {
try {
var statement = this._dbConnection.createStatement(aSQLString);
}
@ -662,8 +662,6 @@ ContentPrefService.prototype = {
// 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);
@ -674,10 +672,8 @@ ContentPrefService.prototype = {
var dbConnection;
if (!dbFile.exists()) {
this._log("no database file; creating database");
if (!dbFile.exists())
dbConnection = this._dbCreate(dbService, dbFile);
}
else {
try {
dbConnection = dbService.openDatabase(dbFile);
@ -685,11 +681,8 @@ ContentPrefService.prototype = {
// Get the version of the database in the file.
var version = dbConnection.schemaVersion;
if (version != this._dbVersion) {
this._log("database: v" + version + ", application: v" +
this._dbVersion + "; migrating database");
if (version != this._dbVersion)
this._dbMigrate(dbConnection, version, this._dbVersion);
}
}
catch (ex) {
// If the database file is corrupted, I'm not sure whether we should
@ -702,7 +695,6 @@ ContentPrefService.prototype = {
//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);
@ -725,16 +717,12 @@ ContentPrefService.prototype = {
_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;
}
@ -745,19 +733,16 @@ ContentPrefService.prototype = {
},
_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(
@ -766,7 +751,6 @@ ContentPrefService.prototype = {
);
// Drop obsolete tables.
this._log("dropping obsolete tables");
aDBConnection.executeSimpleSQL("DROP TABLE prefsOld");
aDBConnection.executeSimpleSQL("DROP TABLE keys");
aDBConnection.executeSimpleSQL("DROP TABLE sites");
@ -775,7 +759,6 @@ ContentPrefService.prototype = {
},
_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(
@ -783,51 +766,10 @@ ContentPrefService.prototype = {
"SELECT id, name FROM groupsOld"
);
this._log("dropping obsolete tables");
aDBConnection.executeSimpleSQL("DROP TABLE groupers");
aDBConnection.executeSimpleSQL("DROP TABLE groupsOld");
aDBConnection.schemaVersion = 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);
}
};
@ -891,6 +833,6 @@ HostnameGrouper.prototype = {
// XPCOM Plumbing
var components = [ContentPrefService, HostnameGrouper];
function NSGetModule(compMgr, fileSpec) {
var NSGetModule = function ContentPrefService_NSGetModule(compMgr, fileSpec) {
return XPCOMUtils.generateModule(components);
}

View File

@ -46,33 +46,33 @@
**/
var ZoomManager = {
get _prefBranch() {
get _prefBranch ZoomManager_get__prefBranch() {
return Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefBranch);
},
get MIN() {
get MIN ZoomManager_get_MIN() {
delete this.MIN;
return this.MIN = this._prefBranch.getIntPref("fullZoom.minPercent") / 100;
},
get MAX() {
get MAX ZoomManager_get_MAX() {
delete this.MAX;
return this.MAX = this._prefBranch.getIntPref("fullZoom.maxPercent") / 100;
},
get fullZoom() {
get fullZoom ZoomManager_get_fullZoom() {
return getBrowser().markupDocumentViewer.fullZoom;
},
set fullZoom(aVal) {
set fullZoom ZoomManager_set_fullZoom(aVal) {
if (aVal < this.MIN || aVal > this.MAX)
throw Components.results.NS_ERROR_INVALID_ARG;
return (getBrowser().markupDocumentViewer.fullZoom = aVal);
},
get fullZoomValues() {
get fullZoomValues ZoomManager_get_fullZoomValues() {
var fullZoomValues = this._prefBranch.getCharPref("toolkit.zoomManager.fullZoomValues")
.split(",").map(parseFloat);
fullZoomValues.sort();
@ -87,23 +87,23 @@ var ZoomManager = {
return this.fullZoomValues = fullZoomValues;
},
enlarge: function () {
enlarge: function ZoomManager_enlarge() {
var i = this.fullZoomValues.indexOf(this.snap(this.fullZoom)) + 1;
if (i < this.fullZoomValues.length)
this.fullZoom = this.fullZoomValues[i];
},
reduce: function () {
reduce: function ZoomManager_reduce() {
var i = this.fullZoomValues.indexOf(this.snap(this.fullZoom)) - 1;
if (i >= 0)
this.fullZoom = this.fullZoomValues[i];
},
reset: function () {
reset: function ZoomManager_reset() {
this.fullZoom = 1;
},
snap: function (aVal) {
snap: function ZoomManager_snap(aVal) {
var values = this.fullZoomValues;
for (var i = 0; i < values.length; i++) {
if (values[i] >= aVal) {

View File

@ -223,8 +223,10 @@
onget="return Components.classes['@mozilla.org/preferences-service;1'].getService(Components.interfaces.nsIPrefService);"
readonly="true"/>
<field name="_docShell">null</field>
<property name="docShell"
onget="return this.boxObject.QueryInterface(Components.interfaces.nsIContainerBoxObject).docShell;"
onget="return this._docShell || (this._docShell = this.boxObject.QueryInterface(Components.interfaces.nsIContainerBoxObject).docShell);"
readonly="true"/>
<property name="webNavigation"