зеркало из https://github.com/mozilla/gecko-dev.git
bug 378549: remember text zoom changes on a site-specific (per-site) basis
r=mconnor
This commit is contained in:
Родитель
b5fc7191b2
Коммит
a9f7d7c3a3
|
@ -0,0 +1,256 @@
|
||||||
|
/*
|
||||||
|
#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.addProgressListener(this, Ci.nsIWebProgress.NOTIFY_STATE_DOCUMENT);
|
||||||
|
gBrowser.addEventListener("DOMContentLoaded", this, false);
|
||||||
|
// XXX Should we also listen for pageshow and/or load?
|
||||||
|
},
|
||||||
|
|
||||||
|
destroy: function ContentPrefSink_destroy() {
|
||||||
|
gBrowser.removeEventListener("DOMContentLoaded", this, false);
|
||||||
|
gBrowser.removeProgressListener(this);
|
||||||
|
|
||||||
|
this._observers = null;
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
//**************************************************************************//
|
||||||
|
// Event Handlers
|
||||||
|
|
||||||
|
// nsIWebProgressListener
|
||||||
|
|
||||||
|
onLocationChange: function ContentPrefSink_onLocationChange(progress, request, uri) {
|
||||||
|
// Catch exceptions until bug 376222 gets fixed so that we don't hork
|
||||||
|
// other progress listeners if our code throws an exception.
|
||||||
|
try {
|
||||||
|
this._handleLocationChanged(uri);
|
||||||
|
}
|
||||||
|
catch(ex) {
|
||||||
|
Components.utils.reportError(ex);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onStateChange: function ContentPrefSink_onStateChange(progress, request, flags, status) {},
|
||||||
|
onProgressChange: function ContentPrefSink_onProgressChange(progress, request, curSelfProgress,
|
||||||
|
maxSelfProgress, curTotalProgress,
|
||||||
|
maxTotalProgress) {},
|
||||||
|
onStatusChange: function ContentPrefSink_onStatusChange(progress, request, status, message) {},
|
||||||
|
onSecurityChange: function ContentPrefSink_onSecurityChange(progress, request, state) {},
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
};
|
|
@ -120,9 +120,9 @@
|
||||||
<command id="Browser:Stop" oncommand="BrowserStop();" disabled="true"/>
|
<command id="Browser:Stop" oncommand="BrowserStop();" disabled="true"/>
|
||||||
<command id="Browser:Reload" oncommand="if (event.shiftKey) BrowserReloadSkipCache(); else BrowserReload()" disabled="true"/>
|
<command id="Browser:Reload" oncommand="if (event.shiftKey) BrowserReloadSkipCache(); else BrowserReload()" disabled="true"/>
|
||||||
<command id="Browser:ReloadSkipCache" oncommand="BrowserReloadSkipCache()" disabled="true"/>
|
<command id="Browser:ReloadSkipCache" oncommand="BrowserReloadSkipCache()" disabled="true"/>
|
||||||
<command id="cmd_textZoomReduce" oncommand="ZoomManager.prototype.getInstance().reduce();"/>
|
<command id="cmd_textZoomReduce" oncommand="TextZoom.reduce()"/>
|
||||||
<command id="cmd_textZoomEnlarge" oncommand="ZoomManager.prototype.getInstance().enlarge();"/>
|
<command id="cmd_textZoomEnlarge" oncommand="TextZoom.enlarge()"/>
|
||||||
<command id="cmd_textZoomReset" oncommand="ZoomManager.prototype.getInstance().reset();"/>
|
<command id="cmd_textZoomReset" oncommand="TextZoom.reset()"/>
|
||||||
<command id="Browser:OpenLocation" oncommand="openLocation();"/>
|
<command id="Browser:OpenLocation" oncommand="openLocation();"/>
|
||||||
|
|
||||||
<command id="Tools:Search" oncommand="BrowserSearch.webSearch();"/>
|
<command id="Tools:Search" oncommand="BrowserSearch.webSearch();"/>
|
||||||
|
|
|
@ -0,0 +1,323 @@
|
||||||
|
/*
|
||||||
|
#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
|
||||||
|
*/
|
||||||
|
|
||||||
|
// From nsMouseScrollEvent::kIsHorizontal
|
||||||
|
const MOUSE_SCROLL_IS_HORIZONTAL = 1 << 2;
|
||||||
|
|
||||||
|
// Not sure where this comes from. It's one of the possible values
|
||||||
|
// for the mousewheel.* preferences.
|
||||||
|
const MOUSE_SCROLL_TEXTSIZE = 3;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controls the "text zoom" setting and its site-specific preferences.
|
||||||
|
*/
|
||||||
|
var TextZoom = {
|
||||||
|
|
||||||
|
//**************************************************************************//
|
||||||
|
// Name & Values
|
||||||
|
|
||||||
|
// The name of the setting. Identifies the setting in the prefs database.
|
||||||
|
name: "browser.content.text-zoom",
|
||||||
|
|
||||||
|
// The global value (if any) for the setting. Retrieved from the prefs
|
||||||
|
// database when this handler gets initialized, then updated as it changes.
|
||||||
|
// If there is no global value, then this should be undefined.
|
||||||
|
globalValue: undefined,
|
||||||
|
|
||||||
|
// From viewZoomOverlay.js
|
||||||
|
minValue: 1,
|
||||||
|
maxValue: 2000,
|
||||||
|
defaultValue: 100,
|
||||||
|
|
||||||
|
|
||||||
|
//**************************************************************************//
|
||||||
|
// Convenience Getters
|
||||||
|
|
||||||
|
__zoomManager: null,
|
||||||
|
get _zoomManager() {
|
||||||
|
if (!this.__zoomManager)
|
||||||
|
this.__zoomManager = ZoomManager.prototype.getInstance();
|
||||||
|
return this.__zoomManager;
|
||||||
|
},
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
},
|
||||||
|
|
||||||
|
// Pref Branch
|
||||||
|
__prefBranch: null,
|
||||||
|
get _prefBranch() {
|
||||||
|
if (!this.__prefBranch)
|
||||||
|
this.__prefBranch = Cc["@mozilla.org/preferences-service;1"].
|
||||||
|
getService(Ci.nsIPrefBranch);
|
||||||
|
return this.__prefBranch;
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
//**************************************************************************//
|
||||||
|
// nsISupports
|
||||||
|
|
||||||
|
// We can't use the Ci shortcut here because it isn't defined yet.
|
||||||
|
interfaces: [Components.interfaces.nsIDOMEventListener,
|
||||||
|
Components.interfaces.nsIContentPrefObserver,
|
||||||
|
Components.interfaces.nsISupports],
|
||||||
|
|
||||||
|
QueryInterface: function TextZoom_QueryInterface(aIID) {
|
||||||
|
if (!this.interfaces.some( function(v) { return aIID.equals(v) } ))
|
||||||
|
throw Cr.NS_ERROR_NO_INTERFACE;
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
//**************************************************************************//
|
||||||
|
// Initialization & Destruction
|
||||||
|
|
||||||
|
init: function TextZoom_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 TextZoom_destroy() {
|
||||||
|
ContentPrefSink.removeObserver(this.name, this);
|
||||||
|
this._cps.removeObserver(this.name, this);
|
||||||
|
window.removeEventListener("DOMMouseScroll", this, false);
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
//**************************************************************************//
|
||||||
|
// Event Handlers
|
||||||
|
|
||||||
|
// nsIDOMEventListener
|
||||||
|
|
||||||
|
handleEvent: function TextZoom_handleEvent(event) {
|
||||||
|
// The only events we handle are DOMMouseScroll events.
|
||||||
|
this._handleMouseScrolled(event);
|
||||||
|
},
|
||||||
|
|
||||||
|
_handleMouseScrolled: function TextZoom__handleMouseScrolled(event) {
|
||||||
|
// Construct the "mousewheel action" pref key corresponding to this event.
|
||||||
|
// Based on nsEventStateManager::GetBasePrefKeyForMouseWheel.
|
||||||
|
var pref = "mousewheel";
|
||||||
|
if (event.scrollFlags & MOUSE_SCROLL_IS_HORIZONTAL)
|
||||||
|
pref += ".horizscroll";
|
||||||
|
|
||||||
|
if (event.shiftKey)
|
||||||
|
pref += ".withshiftkey";
|
||||||
|
else if (event.ctrlKey)
|
||||||
|
pref += ".withcontrolkey";
|
||||||
|
else if (event.altKey)
|
||||||
|
pref += ".withaltkey";
|
||||||
|
else if (event.metaKey)
|
||||||
|
pref += ".withmetakey";
|
||||||
|
else
|
||||||
|
pref += ".withnokey";
|
||||||
|
|
||||||
|
pref += ".action";
|
||||||
|
|
||||||
|
// Don't do anything if this isn't a "change text size" scroll event.
|
||||||
|
if (this._getAppPref(pref, null) != MOUSE_SCROLL_TEXTSIZE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// XXX Lazily cache all the possible action prefs so we don't have to get
|
||||||
|
// them anew from the pref service for every scroll event? We'd have to
|
||||||
|
// make sure to observe them so we can update the cache when they change.
|
||||||
|
|
||||||
|
// We have to call _applySettingToPref in a timeout because we handle
|
||||||
|
// the event before the event state manager has a chance to apply the zoom
|
||||||
|
// during nsEventStateManager::PostHandleEvent.
|
||||||
|
window.setTimeout(function() { TextZoom._applySettingToPref() }, 0);
|
||||||
|
},
|
||||||
|
|
||||||
|
// nsIContentPrefObserver
|
||||||
|
|
||||||
|
onContentPrefSet: function TextZoom_onContentPrefSet(aGroup, aName, aValue) {
|
||||||
|
if (aGroup == this._cps.grouper.group(gBrowser.currentURI))
|
||||||
|
this._applyPrefToSetting(aValue);
|
||||||
|
else if (aGroup == null) {
|
||||||
|
this.globalValue = this._ensureValid(aValue);
|
||||||
|
|
||||||
|
// If the current page doesn't have a site-specific preference,
|
||||||
|
// then its zoom should be set to the new global preference now that
|
||||||
|
// the global preference has changed.
|
||||||
|
if (!this._cps.hasPref(gBrowser.currentURI, this.name))
|
||||||
|
this._applyPrefToSetting();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
onContentPrefRemoved: function TextZoom_onContentPrefRemoved(aGroup, aName) {
|
||||||
|
if (aGroup == this._cps.grouper.group(gBrowser.currentURI))
|
||||||
|
this._applyPrefToSetting();
|
||||||
|
else if (aGroup == null) {
|
||||||
|
this.globalValue = undefined;
|
||||||
|
|
||||||
|
// If the current page doesn't have a site-specific preference,
|
||||||
|
// then its zoom should be set to the default preference now that
|
||||||
|
// the global preference has changed.
|
||||||
|
if (!this._cps.hasPref(gBrowser.currentURI, this.name))
|
||||||
|
this._applyPrefToSetting();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// ContentPrefSink observer
|
||||||
|
|
||||||
|
onLocationChanged: function TextZoom_onLocationChanged(aURI, aName, aValue) {
|
||||||
|
this._applyPrefToSetting(aValue);
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
//**************************************************************************//
|
||||||
|
// Setting & Pref Manipulation
|
||||||
|
|
||||||
|
reduce: function TextZoom_reduce() {
|
||||||
|
this._zoomManager.reduce();
|
||||||
|
this._applySettingToPref();
|
||||||
|
},
|
||||||
|
|
||||||
|
enlarge: function TextZoom_enlarge() {
|
||||||
|
this._zoomManager.enlarge();
|
||||||
|
this._applySettingToPref();
|
||||||
|
},
|
||||||
|
|
||||||
|
reset: function TextZoom_reset() {
|
||||||
|
if (typeof this.globalValue != "undefined")
|
||||||
|
this._zoomManager.textZoom = this.globalValue;
|
||||||
|
else
|
||||||
|
this._zoomManager.reset();
|
||||||
|
|
||||||
|
this._removePref();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the text zoom for the current tab.
|
||||||
|
*
|
||||||
|
* Per DocumentViewerImpl::SetTextZoom 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 SetTextZoom 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.
|
||||||
|
*
|
||||||
|
* 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 TextZoom__applyPrefToSetting(aValue) {
|
||||||
|
// Bug 375918 means this will sometimes throw, so we catch it
|
||||||
|
// and don't do anything in those cases.
|
||||||
|
try {
|
||||||
|
if (typeof aValue != "undefined")
|
||||||
|
this._zoomManager.textZoom = this._ensureValid(aValue);
|
||||||
|
else if (typeof this.globalValue != "undefined")
|
||||||
|
this._zoomManager.textZoom = this.globalValue;
|
||||||
|
else
|
||||||
|
this._zoomManager.reset();
|
||||||
|
}
|
||||||
|
catch(ex) {}
|
||||||
|
},
|
||||||
|
|
||||||
|
_applySettingToPref: function TextZoom__applySettingToPref() {
|
||||||
|
var textZoom = this._zoomManager.textZoom;
|
||||||
|
this._cps.setPref(gBrowser.currentURI, this.name, textZoom);
|
||||||
|
},
|
||||||
|
|
||||||
|
_removePref: function TextZoom__removePref() {
|
||||||
|
this._cps.removePref(gBrowser.currentURI, this.name);
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
//**************************************************************************//
|
||||||
|
// Utilities
|
||||||
|
|
||||||
|
_ensureValid: function TextZoom__ensureValid(aValue) {
|
||||||
|
if (isNaN(aValue))
|
||||||
|
return this.defaultValue;
|
||||||
|
|
||||||
|
if (aValue < this.minValue)
|
||||||
|
return this.minValue;
|
||||||
|
|
||||||
|
if (aValue > this.maxValue)
|
||||||
|
return this.maxValue;
|
||||||
|
|
||||||
|
return aValue;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a value from a 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 TextZoom__getAppPref(aPrefName, aDefaultValue) {
|
||||||
|
try {
|
||||||
|
switch (this._prefBranch.getPrefType(aPrefName)) {
|
||||||
|
case this._prefBranch.PREF_STRING:
|
||||||
|
return this._prefBranch.getCharPref(aPrefName);
|
||||||
|
|
||||||
|
case this._prefBranch.PREF_BOOL:
|
||||||
|
return this._prefBranch.getBoolPref(aPrefName);
|
||||||
|
|
||||||
|
case this._prefBranch.PREF_INT:
|
||||||
|
return this._prefBranch.getIntPref(aPrefName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (ex) { /* return the default value */ }
|
||||||
|
|
||||||
|
return aDefaultValue;
|
||||||
|
}
|
||||||
|
};
|
|
@ -1146,6 +1146,17 @@ function delayedStartup()
|
||||||
// to create its singleton, whose constructor initializes the service.
|
// to create its singleton, whose constructor initializes the service.
|
||||||
Cc["@mozilla.org/microsummary/service;1"].getService(Ci.nsIMicrosummaryService);
|
Cc["@mozilla.org/microsummary/service;1"].getService(Ci.nsIMicrosummaryService);
|
||||||
|
|
||||||
|
// Initialize the content pref event sink and the text 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.
|
||||||
|
try {
|
||||||
|
ContentPrefSink.init();
|
||||||
|
TextZoom.init();
|
||||||
|
}
|
||||||
|
catch(ex) {
|
||||||
|
Components.utils.reportError(ex);
|
||||||
|
}
|
||||||
|
|
||||||
// initialize the session-restore service (in case it's not already running)
|
// initialize the session-restore service (in case it's not already running)
|
||||||
if (document.documentElement.getAttribute("windowtype") == "navigator:browser") {
|
if (document.documentElement.getAttribute("windowtype") == "navigator:browser") {
|
||||||
try {
|
try {
|
||||||
|
@ -1170,6 +1181,14 @@ function delayedStartup()
|
||||||
|
|
||||||
function BrowserShutdown()
|
function BrowserShutdown()
|
||||||
{
|
{
|
||||||
|
try {
|
||||||
|
TextZoom.destroy();
|
||||||
|
ContentPrefSink.destroy();
|
||||||
|
}
|
||||||
|
catch(ex) {
|
||||||
|
Components.utils.reportError(ex);
|
||||||
|
}
|
||||||
|
|
||||||
var os = Components.classes["@mozilla.org/observer-service;1"]
|
var os = Components.classes["@mozilla.org/observer-service;1"]
|
||||||
.getService(Components.interfaces.nsIObserverService);
|
.getService(Components.interfaces.nsIObserverService);
|
||||||
os.removeObserver(gSessionHistoryObserver, "browser:purge-session-history");
|
os.removeObserver(gSessionHistoryObserver, "browser:purge-session-history");
|
||||||
|
@ -5669,6 +5688,9 @@ var FeedHandler = {
|
||||||
#include browser-places.js
|
#include browser-places.js
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include browser-contentPrefSink.js
|
||||||
|
#include browser-textZoom.js
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This object is for augmenting tabs
|
* This object is for augmenting tabs
|
||||||
*/
|
*/
|
||||||
|
|
Загрузка…
Ссылка в новой задаче