Bug 1055464 - Add RefreshBlocker to tab-content, and a listener in tabbrowser.xml. r=Mossop
--- a/browser/base/content/tab-content.js
+++ b/browser/base/content/tab-content.js
@@ -683,12 +683,81 @@ var DOMFullscreenHandler = {
sendAsyncMessage("DOMFullscreen:Painted");
break;
}
}
}
};
DOMFullscreenHandler.init();
+var RefreshBlocker = {
+ init() {
+ this._filter = Cc["@mozilla.org/appshell/component/browser-status-filter;1"]
+ .createInstance(Ci.nsIWebProgress);
+ this._filter.addProgressListener(this, Ci.nsIWebProgress.NOTIFY_REFRESH);
+
+ let webProgress = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIWebProgress);
+ webProgress.addProgressListener(this._filter, Ci.nsIWebProgress.NOTIFY_REFRESH);
+
+ addMessageListener("RefreshBlocker:Refresh", this);
+ },
+
+ uninit() {
+ let webProgress = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIWebProgress);
+ webProgress.removeProgressListener(this._filter);
+
+ this._filter.removeProgressListener(this);
+ this._filter = null;
+
+ removeMessageListener("RefreshBlocker:Refresh", this);
+ },
+
+ onRefreshAttempted(aWebProgress, aURI, aDelay, aSameURI) {
+ if (Services.prefs.getBoolPref("accessibility.blockautorefresh")) {
+ let win = aWebProgress.DOMWindow;
+ let outerWindowID = win.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIDOMWindowUtils)
+ .outerWindowID;
+
+ sendAsyncMessage("RefreshBlocker:Blocked", {
+ URI: aURI.spec,
+ originCharset: aURI.originCharset,
+ delay: aDelay,
+ sameURI: aSameURI,
+ outerWindowID,
+ });
+
+ return false;
+ }
+
+ return true;
+ },
+
+ receiveMessage(message) {
+ let data = message.data;
+
+ if (message.name == "RefreshBlocker:Refresh") {
+ let win = Services.wm.getOuterWindowWithId(data.outerWindowID);
+ let refreshURI = win.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIDocShell)
+ .QueryInterface(Ci.nsIRefreshURI);
+
+ let URI = BrowserUtils.makeURI(data.URI, data.originCharset, null);
+
+ refreshURI.forceRefreshURI(URI, data.delay, true);
+ }
+ },
+
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener2,
+ Ci.nsIWebProgressListener,
+ Ci.nsISupportsWeakReference,
+ Ci.nsISupports]),
+};
+
+RefreshBlocker.init();
+
ExtensionContent.init(this);
addEventListener("unload", () => {
ExtensionContent.uninit(this);
+ RefreshBlocker.uninit();
});
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -4025,17 +4025,17 @@
break;
}
]]></body>
</method>
<method name="receiveMessage">
<parameter name="aMessage"/>
<body><![CDATA[
- let json = aMessage.json;
+ let data = aMessage.data;
let browser = aMessage.target;
switch (aMessage.name) {
case "DOMTitleChanged": {
let tab = this.getTabForBrowser(browser);
if (!tab || tab.hasAttribute("pending"))
return undefined;
let titleChanged = this.setTabTitle(tab);
@@ -4057,42 +4057,42 @@
if (tab) {
// Skip running PermitUnload since it already happened in
// the content process.
this.removeTab(tab, {skipPermitUnload: true});
}
break;
}
case "contextmenu": {
- let spellInfo = aMessage.data.spellInfo;
+ let spellInfo = data.spellInfo;
if (spellInfo)
spellInfo.target = aMessage.target.messageManager;
- let documentURIObject = makeURI(aMessage.data.docLocation,
- aMessage.data.charSet,
- makeURI(aMessage.data.baseURI));
+ let documentURIObject = makeURI(data.docLocation,
+ data.charSet,
+ makeURI(data.baseURI));
gContextMenuContentData = { isRemote: true,
event: aMessage.objects.event,
popupNode: aMessage.objects.popupNode,
browser: browser,
- editFlags: aMessage.data.editFlags,
+ editFlags: data.editFlags,
spellInfo: spellInfo,
- principal: aMessage.data.principal,
- customMenuItems: aMessage.data.customMenuItems,
- addonInfo: aMessage.data.addonInfo,
+ principal: data.principal,
+ customMenuItems: data.customMenuItems,
+ addonInfo: data.addonInfo,
documentURIObject: documentURIObject,
- docLocation: aMessage.data.docLocation,
- charSet: aMessage.data.charSet,
- referrer: aMessage.data.referrer,
- referrerPolicy: aMessage.data.referrerPolicy,
- contentType: aMessage.data.contentType,
- contentDisposition: aMessage.data.contentDisposition,
- frameOuterWindowID: aMessage.data.frameOuterWindowID,
- selectionInfo: aMessage.data.selectionInfo,
- disableSetDesktopBackground: aMessage.data.disableSetDesktopBg,
- loginFillInfo: aMessage.data.loginFillInfo,
+ docLocation: data.docLocation,
+ charSet: data.charSet,
+ referrer: data.referrer,
+ referrerPolicy: data.referrerPolicy,
+ contentType: data.contentType,
+ contentDisposition: data.contentDisposition,
+ frameOuterWindowID: data.frameOuterWindowID,
+ selectionInfo: data.selectionInfo,
+ disableSetDesktopBackground: data.disableSetDesktopBg,
+ loginFillInfo: data.loginFillInfo,
};
let popup = browser.ownerDocument.getElementById("contentAreaContextMenu");
let event = gContextMenuContentData.event;
popup.openPopupAtScreen(event.screenX, event.screenY, true);
break;
}
case "DOMServiceWorkerFocusClient":
case "DOMWebNotificationClicked": {
@@ -4113,33 +4113,44 @@
break;
}
case "Findbar:Keypress": {
let tab = this.getTabForBrowser(browser);
// If the find bar for this tab is not yet alive, only initialize
// it if there's a possibility FindAsYouType will be used.
// There's no point in doing it for most random keypresses.
if (!this.isFindBarInitialized(tab) &&
- aMessage.data.shouldFastFind) {
+ data.shouldFastFind) {
let shouldFastFind = this._findAsYouType;
if (!shouldFastFind) {
// Please keep in sync with toolkit/content/widgets/findbar.xml
const FAYT_LINKS_KEY = "'";
const FAYT_TEXT_KEY = "/";
- let charCode = aMessage.data.fakeEvent.charCode;
+ let charCode = data.fakeEvent.charCode;
let key = charCode ? String.fromCharCode(charCode) : null;
shouldFastFind = key == FAYT_LINKS_KEY || key == FAYT_TEXT_KEY;
}
if (shouldFastFind) {
// Make sure we return the result.
return this.getFindBar(tab).receiveMessage(aMessage);
}
}
break;
}
+ case "RefreshBlocker:Blocked": {
+ let event = new CustomEvent("RefreshBlocked", {
+ bubbles: true,
+ cancelable: false,
+ detail: data,
+ });
+
+ browser.dispatchEvent(event);
+
+ break;
+ }
}
]]></body>
</method>
<method name="observe">
<parameter name="aSubject"/>
<parameter name="aTopic"/>
@@ -4239,16 +4250,17 @@
// which does asynchronous tab switching.
this.mPanelContainer.classList.add("tabbrowser-tabpanels");
} else {
this._outerWindowIDBrowserMap.set(this.mCurrentBrowser.outerWindowID,
this.mCurrentBrowser);
}
messageManager.addMessageListener("DOMWebNotificationClicked", this);
messageManager.addMessageListener("DOMServiceWorkerFocusClient", this);
+ messageManager.addMessageListener("RefreshBlocker:Blocked", this);
// To correctly handle keypresses for potential FindAsYouType, while
// the tab's find bar is not yet initialized.
this._findAsYouType = Services.prefs.getBoolPref("accessibility.typeaheadfind");
Services.prefs.addObserver("accessibility.typeaheadfind", this, false);
messageManager.addMessageListener("Findbar:Keypress", this);
]]>
</constructor>