summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--application/palemoon/base/content/browser-fullZoom.js210
1 files changed, 93 insertions, 117 deletions
diff --git a/application/palemoon/base/content/browser-fullZoom.js b/application/palemoon/base/content/browser-fullZoom.js
index 0837bf7c2..890cd8440 100644
--- a/application/palemoon/base/content/browser-fullZoom.js
+++ b/application/palemoon/base/content/browser-fullZoom.js
@@ -1,14 +1,6 @@
-/*
-#ifdef 0
- * This Source Code Form is subject to the terms of the Mozilla Public
+/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
-#endif
- */
-
-// One of the possible values for the mousewheel.* preferences.
-// From nsEventStateManager.cpp.
-const MOUSE_SCROLL_ZOOM = 3;
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* Controls the "full zoom" setting and its site-specific preferences.
@@ -36,7 +28,6 @@ var FullZoom = {
return this._siteSpecificPref;
},
- //**************************************************************************//
// nsISupports
QueryInterface: XPCOMUtils.generateQI([Ci.nsIDOMEventListener,
@@ -45,12 +36,10 @@ var FullZoom = {
Ci.nsISupportsWeakReference,
Ci.nsISupports]),
- //**************************************************************************//
// Initialization & Destruction
init: function FullZoom_init() {
- // Listen for scrollwheel events so we can save scrollwheel-based changes.
- window.addEventListener("DOMMouseScroll", this, false);
+ gBrowser.addEventListener("ZoomChangeUsingMouseWheel", this);
// Register ourselves with the service so we know when our pref changes.
this._cps2 = Cc["@mozilla.org/content-pref/service;1"].
@@ -74,76 +63,30 @@ var FullZoom = {
}
// This should be nulled after initialization.
- this._initialLocations.clear();
this._initialLocations = null;
},
destroy: function FullZoom_destroy() {
gPrefService.removeObserver("browser.zoom.", this);
this._cps2.removeObserverForName(this.name, this);
- window.removeEventListener("DOMMouseScroll", this, false);
+ gBrowser.removeEventListener("ZoomChangeUsingMouseWheel", this);
},
- //**************************************************************************//
// Event Handlers
// nsIDOMEventListener
handleEvent: function FullZoom_handleEvent(event) {
switch (event.type) {
- case "DOMMouseScroll":
- this._handleMouseScrolled(event);
+ case "ZoomChangeUsingMouseWheel":
+ let browser = this._getTargetedBrowser(event);
+ this._ignorePendingZoomAccesses(browser);
+ this._applyZoomToPref(browser);
break;
}
},
- _handleMouseScrolled: function FullZoom__handleMouseScrolled(event) {
- // Construct the "mousewheel action" pref key corresponding to this event.
- // Based on nsEventStateManager::WheelPrefs::GetBasePrefName().
- var pref = "mousewheel.";
-
- var pressedModifierCount = event.shiftKey + event.ctrlKey + event.altKey +
- event.metaKey + event.getModifierState("OS");
- if (pressedModifierCount != 1) {
- pref += "default.";
- } else if (event.shiftKey) {
- pref += "with_shift.";
- } else if (event.ctrlKey) {
- pref += "with_control.";
- } else if (event.altKey) {
- pref += "with_alt.";
- } else if (event.metaKey) {
- pref += "with_meta.";
- } else {
- pref += "with_win.";
- }
-
- pref += "action";
-
- // Don't do anything if this isn't a "zoom" scroll event.
- var isZoomEvent = false;
- try {
- isZoomEvent = (gPrefService.getIntPref(pref) == MOUSE_SCROLL_ZOOM);
- } catch (e) {}
- if (!isZoomEvent)
- 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 _applyZoomToPref in a timeout because we handle the
- // event before the event state manager has a chance to apply the zoom
- // during nsEventStateManager::PostHandleEvent.
- let browser = gBrowser.selectedBrowser;
- let token = this._getBrowserToken(browser);
- window.setTimeout(function () {
- if (token.isCurrent)
- this._applyZoomToPref(browser);
- }.bind(this), 0);
- },
-
// nsIObserver
observe: function (aSubject, aTopic, aData) {
@@ -165,12 +108,12 @@ var FullZoom = {
// nsIContentPrefObserver
- onContentPrefSet: function FullZoom_onContentPrefSet(aGroup, aName, aValue) {
- this._onContentPrefChanged(aGroup, aValue);
+ onContentPrefSet: function FullZoom_onContentPrefSet(aGroup, aName, aValue, aIsPrivate) {
+ this._onContentPrefChanged(aGroup, aValue, aIsPrivate);
},
- onContentPrefRemoved: function FullZoom_onContentPrefRemoved(aGroup, aName) {
- this._onContentPrefChanged(aGroup, undefined);
+ onContentPrefRemoved: function FullZoom_onContentPrefRemoved(aGroup, aName, aIsPrivate) {
+ this._onContentPrefChanged(aGroup, undefined, aIsPrivate);
},
/**
@@ -181,7 +124,7 @@ var FullZoom = {
* @param aValue The new value of the changed preference. Pass undefined to
* indicate the preference's removal.
*/
- _onContentPrefChanged: function FullZoom__onContentPrefChanged(aGroup, aValue) {
+ _onContentPrefChanged: function FullZoom__onContentPrefChanged(aGroup, aValue, aIsPrivate) {
if (this._isNextContentPrefChangeInternal) {
// Ignore changes that FullZoom itself makes. This works because the
// content pref service calls callbacks before notifying observers, and it
@@ -194,9 +137,10 @@ var FullZoom = {
if (!browser.currentURI)
return;
+ let ctxt = this._loadContextFromBrowser(browser);
let domain = this._cps2.extractDomain(browser.currentURI.spec);
if (aGroup) {
- if (aGroup == domain)
+ if (aGroup == domain && ctxt.usePrivateBrowsing == aIsPrivate)
this._applyPrefToZoom(aValue, browser);
return;
}
@@ -208,10 +152,9 @@ var FullZoom = {
// zoom should be set to the new global preference now that the global
// preference has changed.
let hasPref = false;
- let ctxt = this._loadContextFromBrowser(browser);
let token = this._getBrowserToken(browser);
this._cps2.getByDomainAndName(browser.currentURI.spec, this.name, ctxt, {
- handleResult: function () hasPref = true,
+ handleResult: function () { hasPref = true; },
handleCompletion: function () {
if (!hasPref && token.isCurrent)
this._applyPrefToZoom(undefined, browser);
@@ -234,6 +177,7 @@ var FullZoom = {
*/
onLocationChange: function FullZoom_onLocationChange(aURI, aIsTabSwitch, aBrowser) {
let browser = aBrowser || gBrowser.selectedBrowser;
+
// If we haven't been initialized yet but receive an onLocationChange
// notification then let's store and replay it upon initialization.
if (this._initialLocations) {
@@ -247,14 +191,14 @@ var FullZoom = {
this._ignorePendingZoomAccesses(browser);
if (!aURI || (aIsTabSwitch && !this.siteSpecific)) {
- this._notifyOnLocationChange();
+ this._notifyOnLocationChange(browser);
return;
}
// Avoid the cps roundtrip and apply the default/global pref.
if (aURI.spec == "about:blank") {
this._applyPrefToZoom(undefined, browser,
- this._notifyOnLocationChange.bind(this));
+ this._notifyOnLocationChange.bind(this, browser));
return;
}
@@ -262,7 +206,7 @@ var FullZoom = {
if (!aIsTabSwitch && browser.isSyntheticDocument) {
ZoomManager.setZoomForBrowser(browser, 1);
// _ignorePendingZoomAccesses already called above, so no need here.
- this._notifyOnLocationChange();
+ this._notifyOnLocationChange(browser);
return;
}
@@ -271,7 +215,7 @@ var FullZoom = {
let pref = this._cps2.getCachedByDomainAndName(aURI.spec, this.name, ctxt);
if (pref) {
this._applyPrefToZoom(pref.value, browser,
- this._notifyOnLocationChange.bind(this));
+ this._notifyOnLocationChange.bind(this, browser));
return;
}
@@ -279,14 +223,14 @@ var FullZoom = {
let value = undefined;
let token = this._getBrowserToken(browser);
this._cps2.getByDomainAndName(aURI.spec, this.name, ctxt, {
- handleResult: function (resultPref) value = resultPref.value,
+ handleResult: function (resultPref) { value = resultPref.value; },
handleCompletion: function () {
if (!token.isCurrent) {
- this._notifyOnLocationChange();
+ this._notifyOnLocationChange(browser);
return;
}
this._applyPrefToZoom(value, browser,
- this._notifyOnLocationChange.bind(this));
+ this._notifyOnLocationChange.bind(this, browser));
}.bind(this)
});
},
@@ -299,7 +243,6 @@ var FullZoom = {
menuItem.setAttribute("checked", !ZoomManager.useFullZoom);
},
- //**************************************************************************//
// Setting & Pref Manipulation
/**
@@ -323,19 +266,32 @@ var FullZoom = {
},
/**
- * Sets the zoom level of the page in the current browser to the global zoom
+ * Sets the zoom level for the given browser to the given floating
+ * point value, where 1 is the default zoom level.
+ */
+ setZoom: function (value, browser = gBrowser.selectedBrowser) {
+ ZoomManager.setZoomForBrowser(browser, value);
+ this._ignorePendingZoomAccesses(browser);
+ this._applyZoomToPref(browser);
+ },
+
+ /**
+ * Sets the zoom level of the page in the given browser to the global zoom
* level.
+ *
+ * @return A promise which resolves when the zoom reset has been applied.
*/
- reset: function FullZoom_reset() {
- let browser = gBrowser.selectedBrowser;
+ reset: function FullZoom_reset(browser = gBrowser.selectedBrowser) {
let token = this._getBrowserToken(browser);
- this._getGlobalValue(browser, function (value) {
+ let result = this._getGlobalValue(browser).then(value => {
if (token.isCurrent) {
ZoomManager.setZoomForBrowser(browser, value === undefined ? 1 : value);
this._ignorePendingZoomAccesses(browser);
+ Services.obs.notifyObservers(browser, "browser-fullZoom:zoomReset", "");
}
});
this._removePref(browser);
+ return result;
},
/**
@@ -383,7 +339,7 @@ var FullZoom = {
}
let token = this._getBrowserToken(aBrowser);
- this._getGlobalValue(aBrowser, function (value) {
+ this._getGlobalValue(aBrowser).then(value => {
if (token.isCurrent) {
ZoomManager.setZoomForBrowser(aBrowser, value === undefined ? 1 : value);
this._ignorePendingZoomAccesses(aBrowser);
@@ -399,6 +355,7 @@ var FullZoom = {
* @param browser The zoom of this browser will be saved. Required.
*/
_applyZoomToPref: function FullZoom__applyZoomToPref(browser) {
+ Services.obs.notifyObservers(browser, "browser-fullZoom:zoomChange", "");
if (!this.siteSpecific ||
gInPrintPreviewMode ||
browser.isSyntheticDocument)
@@ -419,6 +376,7 @@ var FullZoom = {
* @param browser The zoom of this browser will be removed. Required.
*/
_removePref: function FullZoom__removePref(browser) {
+ Services.obs.notifyObservers(browser, "browser-fullZoom:zoomReset", "");
if (browser.isSyntheticDocument)
return;
let ctxt = this._loadContextFromBrowser(browser);
@@ -429,7 +387,6 @@ var FullZoom = {
});
},
- //**************************************************************************//
// Utilities
/**
@@ -462,6 +419,30 @@ var FullZoom = {
},
/**
+ * Returns the browser that the supplied zoom event is associated with.
+ * @param event The ZoomChangeUsingMouseWheel event.
+ * @return The associated browser element, if one exists, otherwise null.
+ */
+ _getTargetedBrowser: function FullZoom__getTargetedBrowser(event) {
+ let target = event.originalTarget;
+
+ // With remote content browsers, the event's target is the browser
+ // we're looking for.
+ const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
+ if (target instanceof window.XULElement &&
+ target.localName == "browser" &&
+ target.namespaceURI == XUL_NS)
+ return target;
+
+ // With in-process content browsers, the event's target is the content
+ // document.
+ if (target.nodeType == Node.DOCUMENT_NODE)
+ return gBrowser.getBrowserForDocument(target);
+
+ throw new Error("Unexpected ZoomChangeUsingMouseWheel event source");
+ },
+
+ /**
* Increments the zoom change token for the given browser so that pending
* async operations know that it may be unsafe to access they zoom when they
* finish.
@@ -491,54 +472,49 @@ var FullZoom = {
/**
* Gets the global browser.content.full-zoom content preference.
*
- * WARNING: callback may be called synchronously or asynchronously. The
- * reason is that it's usually desirable to avoid turns of the event loop
- * where possible, since they can lead to visible, jarring jumps in zoom
- * level. It's not always possible to avoid them, though. As a convenience,
- * then, this method takes a callback and returns nothing.
- *
- * @param browser The content browser pertaining to the zoom.
- * @param callback Synchronously or asynchronously called when done. It's
- * bound to this object (FullZoom) and called as:
- * callback(prefValue)
+ * @param browser The browser pertaining to the zoom.
+ * @returns Promise<prefValue>
+ * Resolves to the preference value when done.
*/
- _getGlobalValue: function FullZoom__getGlobalValue(browser, callback) {
+ _getGlobalValue: function FullZoom__getGlobalValue(browser) {
// * !("_globalValue" in this) => global value not yet cached.
// * this._globalValue === undefined => global value known not to exist.
// * Otherwise, this._globalValue is a number, the global value.
- if ("_globalValue" in this) {
- callback.call(this, this._globalValue, true);
- return;
- }
- let value = undefined;
- this._cps2.getGlobal(this.name, this._loadContextFromBrowser(browser), {
- handleResult: function (pref) value = pref.value,
- handleCompletion: function (reason) {
- this._globalValue = this._ensureValid(value);
- callback.call(this, this._globalValue);
- }.bind(this)
+ return new Promise(resolve => {
+ if ("_globalValue" in this) {
+ resolve(this._globalValue);
+ return;
+ }
+ let value = undefined;
+ this._cps2.getGlobal(this.name, this._loadContextFromBrowser(browser), {
+ handleResult: function (pref) { value = pref.value; },
+ handleCompletion: (reason) => {
+ this._globalValue = this._ensureValid(value);
+ resolve(this._globalValue);
+ }
+ });
});
},
/**
- * Gets the load context from the given content browser.
+ * Gets the load context from the given Browser.
*
* @param Browser The Browser whose load context will be returned.
- * @return The nsILoadContext of the given Browser.
+ * @return The nsILoadContext of the given Browser.
*/
_loadContextFromBrowser: function FullZoom__loadContextFromBrowser(browser) {
return browser.loadContext;
},
/**
- * Asynchronously broadcasts a "browser-fullZoom:locationChange" notification
- * so that tests can select tabs, load pages, etc. and be notified when the
- * zoom levels on those pages change. The notification is always asynchronous
- * so that observers are guaranteed a consistent behavior.
+ * Asynchronously broadcasts "browser-fullZoom:location-change" so that
+ * listeners can be notified when the zoom levels on those pages change.
+ * The notification is always asynchronous so that observers are guaranteed a
+ * consistent behavior.
*/
- _notifyOnLocationChange: function FullZoom__notifyOnLocationChange() {
+ _notifyOnLocationChange: function FullZoom__notifyOnLocationChange(browser) {
this._executeSoon(function () {
- Services.obs.notifyObservers(null, "browser-fullZoom:locationChange", "");
+ Services.obs.notifyObservers(browser, "browser-fullZoom:location-change", "");
});
},