Bug 933462 - [e10s] Pop-up blocking notifications (r=felipe)

This commit is contained in:
Bill McCloskey 2014-03-20 16:31:20 -07:00
parent a11a1c2c36
commit ca5cff8b5b
4 changed files with 154 additions and 82 deletions

View File

@ -433,7 +433,7 @@ var gPopupBlockerObserver = {
if (!this._reportButton && gURLBar)
this._reportButton = document.getElementById("page-report-button");
if (!gBrowser.pageReport) {
if (!gBrowser.selectedBrowser.blockedPopups) {
// Hide the icon in the location bar (if the location bar exists)
if (gURLBar)
this._reportButton.hidden = true;
@ -446,11 +446,11 @@ var gPopupBlockerObserver = {
// Only show the notification again if we've not already shown it. Since
// notifications are per-browser, we don't need to worry about re-adding
// it.
if (!gBrowser.pageReport.reported) {
if (!gBrowser.selectedBrowser.blockedPopups.reported) {
if (gPrefService.getBoolPref("privacy.popups.showBrowserMessage")) {
var brandBundle = document.getElementById("bundle_brand");
var brandShortName = brandBundle.getString("brandShortName");
var popupCount = gBrowser.pageReport.length;
var popupCount = gBrowser.selectedBrowser.blockedPopups.length;
#ifdef XP_WIN
var popupButtonText = gNavigatorBundle.getString("popupWarningButton");
var popupButtonAccesskey = gNavigatorBundle.getString("popupWarningButton.accesskey");
@ -485,7 +485,7 @@ var gPopupBlockerObserver = {
// Record the fact that we've reported this blocked popup, so we don't
// show it again.
gBrowser.pageReport.reported = true;
gBrowser.selectedBrowser.blockedPopups.reported = true;
}
},
@ -502,7 +502,7 @@ var gPopupBlockerObserver = {
fillPopupList: function (aEvent)
{
// XXXben - rather than using |currentURI| here, which breaks down on multi-framed sites
// we should really walk the pageReport and create a list of "allow for <host>"
// we should really walk the blockedPopups and create a list of "allow for <host>"
// menuitems for the common subset of hosts present in the report, this will
// make us frame-safe.
//
@ -510,7 +510,8 @@ var gPopupBlockerObserver = {
// also back out the fix for bug 343772 where
// nsGlobalWindow::CheckOpenAllow() was changed to also
// check if the top window's location is whitelisted.
var uri = gBrowser.currentURI;
let browser = gBrowser.selectedBrowser;
var uri = browser.currentURI;
var blockedPopupAllowSite = document.getElementById("blockedPopupAllowSite");
try {
blockedPopupAllowSite.removeAttribute("hidden");
@ -540,16 +541,18 @@ var gPopupBlockerObserver = {
blockedPopupAllowSite.removeAttribute("disabled");
var foundUsablePopupURI = false;
var pageReports = gBrowser.pageReport;
if (pageReports) {
for (let pageReport of pageReports) {
var blockedPopups = browser.blockedPopups;
if (blockedPopups) {
for (let i = 0; i < blockedPopups.length; i++) {
let blockedPopup = blockedPopups[i];
// popupWindowURI will be null if the file picker popup is blocked.
// xxxdz this should make the option say "Show file picker" and do it (Bug 590306)
if (!pageReport.popupWindowURI)
if (!blockedPopup.popupWindowURI)
continue;
var popupURIspec = pageReport.popupWindowURI.spec;
var popupURIspec = blockedPopup.popupWindowURI;
// Sometimes the popup URI that we get back from the pageReport
// Sometimes the popup URI that we get back from the blockedPopup
// isn't useful (for instance, netscape.com's popup URI ends up
// being "http://www.netscape.com", which isn't really the URI of
// the popup they're trying to show). This isn't going to be
@ -570,11 +573,11 @@ var gPopupBlockerObserver = {
[popupURIspec]);
menuitem.setAttribute("label", label);
menuitem.setAttribute("popupWindowURI", popupURIspec);
menuitem.setAttribute("popupWindowFeatures", pageReport.popupWindowFeatures);
menuitem.setAttribute("popupWindowName", pageReport.popupWindowName);
menuitem.setAttribute("popupWindowFeatures", blockedPopup.popupWindowFeatures);
menuitem.setAttribute("popupWindowName", blockedPopup.popupWindowName);
menuitem.setAttribute("oncommand", "gPopupBlockerObserver.showBlockedPopup(event);");
menuitem.requestingWindow = pageReport.requestingWindow;
menuitem.requestingDocument = pageReport.requestingDocument;
menuitem.setAttribute("popupReportIndex", i);
menuitem.popupReportBrowser = browser;
aEvent.target.appendChild(menuitem);
}
}
@ -613,17 +616,9 @@ var gPopupBlockerObserver = {
showBlockedPopup: function (aEvent)
{
var target = aEvent.target;
var popupWindowURI = target.getAttribute("popupWindowURI");
var features = target.getAttribute("popupWindowFeatures");
var name = target.getAttribute("popupWindowName");
var dwi = target.requestingWindow;
// If we have a requesting window and the requesting document is
// still the current document, open the popup.
if (dwi && dwi.document == target.requestingDocument) {
dwi.open(popupWindowURI, name, features);
}
var popupReportIndex = target.getAttribute("popupReportIndex");
let browser = target.popupReportBrowser;
browser.unblockPopup(popupReportIndex);
},
editPopupSettings: function ()

View File

@ -996,11 +996,11 @@
oldBrowser.docShellIsActive = false;
}
var updatePageReport = false;
var updateBlockedPopups = false;
if (!oldBrowser ||
(oldBrowser.pageReport && !newBrowser.pageReport) ||
(!oldBrowser.pageReport && newBrowser.pageReport))
updatePageReport = true;
(oldBrowser.blockedPopups && !newBrowser.blockedPopups) ||
(!oldBrowser.blockedPopups && newBrowser.blockedPopups))
updateBlockedPopups = true;
newBrowser.setAttribute("type", "content-primary");
newBrowser.docShellIsActive =
@ -1020,8 +1020,8 @@
this._appendStatusPanel();
if (updatePageReport)
this.mCurrentBrowser.updatePageReport();
if (updateBlockedPopups)
this.mCurrentBrowser.updateBlockedPopups(false);
// Update the URL bar.
var loc = this.mCurrentBrowser.currentURI;
@ -2795,10 +2795,6 @@
]]></body>
</method>
<property name="pageReport"
onget="return this.mCurrentBrowser.pageReport;"
readonly="true"/>
<property name="currentURI"
onget="return this.mCurrentBrowser.currentURI;"
readonly="true"/>

View File

@ -238,3 +238,105 @@ let ClickEventHandler = {
},
};
ClickEventHandler.init();
let PopupBlocking = {
popupData: null,
popupDataInternal: null,
init: function() {
addEventListener("DOMPopupBlocked", this, true);
addEventListener("pageshow", this, true);
addEventListener("pagehide", this, true);
addMessageListener("PopupBlocking:UnblockPopup", this);
},
receiveMessage: function(msg) {
switch (msg.name) {
case "PopupBlocking:UnblockPopup": {
let i = msg.data.index;
if (this.popupData && this.popupData[i]) {
let data = this.popupData[i];
let internals = this.popupDataInternal[i];
let dwi = internals.requestingWindow;
// If we have a requesting window and the requesting document is
// still the current document, open the popup.
if (dwi && dwi.document == internals.requestingDocument) {
dwi.open(data.popupWindowURI, data.popupWindowName, data.popupWindowFeatures);
}
}
break;
}
}
},
handleEvent: function(ev) {
switch (ev.type) {
case "DOMPopupBlocked":
return this.onPopupBlocked(ev);
case "pageshow":
return this.onPageShow(ev);
case "pagehide":
return this.onPageHide(ev);
}
},
onPopupBlocked: function(ev) {
if (!this.popupData) {
this.popupData = new Array();
this.popupDataInternal = new Array();
}
let obj = {
popupWindowURI: ev.popupWindowURI.spec,
popupWindowFeatures: ev.popupWindowFeatures,
popupWindowName: ev.popupWindowName
};
let internals = {
requestingWindow: ev.requestingWindow,
requestingDocument: ev.requestingWindow.document,
};
this.popupData.push(obj);
this.popupDataInternal.push(internals);
this.updateBlockedPopups(true);
},
onPageShow: function(ev) {
if (this.popupData) {
let i = 0;
while (i < this.popupData.length) {
// Filter out irrelevant reports.
if (this.popupDataInternal[i].requestingWindow &&
(this.popupDataInternal[i].requestingWindow.document ==
this.popupDataInternal[i].requestingDocument)) {
i++;
} else {
this.popupData.splice(i, 1);
this.popupDataInternal.splice(i, 1);
}
}
if (this.popupData.length == 0) {
this.popupData = null;
this.popupDataInternal = null;
}
this.updateBlockedPopups(false);
}
},
onPageHide: function(ev) {
if (this.popupData) {
this.popupData = null;
this.popupDataInternal = null;
this.updateBlockedPopups(false);
}
},
updateBlockedPopups: function(freshPopup) {
sendAsyncMessage("PopupBlocking:UpdateBlockedPopups",
{blockedPopups: this.popupData, freshPopup: freshPopup});
},
};
PopupBlocking.init();

View File

@ -562,22 +562,6 @@
<body>
<![CDATA[
this.attachFormFill();
if (this.pageReport) {
var i = 0;
while (i < this.pageReport.length) {
// Filter out irrelevant reports.
if (this.pageReport[i].requestingWindow &&
(this.pageReport[i].requestingWindow.document ==
this.pageReport[i].requestingDocument))
i++;
else
this.pageReport.splice(i, 1);
}
if (this.pageReport.length == 0) {
this.pageReport = null;
this.updatePageReport();
}
}
]]>
</body>
</method>
@ -586,10 +570,6 @@
<parameter name="aEvent"/>
<body>
<![CDATA[
if (this.pageReport) {
this.pageReport = null;
this.updatePageReport();
}
// Delete the feeds cache if we're hiding the topmost page
// (as opposed to one of its iframes).
if (this.feeds && aEvent.target == this.contentDocument)
@ -604,9 +584,16 @@
</body>
</method>
<method name="updatePageReport">
<method name="updateBlockedPopups">
<parameter name="aBlockedPopups"/>
<parameter name="aFreshPopup"/>
<body>
<![CDATA[
this.blockedPopups = aBlockedPopups;
if (aFreshPopup) {
this.blockedPopups.reported = false;
}
var event = document.createEvent("Events");
event.initEvent("DOMUpdatePageReport", true, true);
this.dispatchEvent(event);
@ -614,30 +601,20 @@
</body>
</method>
<method name="onPopupBlocked">
<parameter name="evt"/>
<body>
<![CDATA[
if (!this.pageReport) {
this.pageReport = new Array();
}
var obj = { requestingWindow: evt.requestingWindow,
// Record the current document in the requesting window
// before it can change.
requestingDocument: evt.requestingWindow.document,
popupWindowURI: evt.popupWindowURI,
popupWindowFeatures: evt.popupWindowFeatures,
popupWindowName: evt.popupWindowName };
this.pageReport.push(obj);
this.pageReport.reported = false;
this.updatePageReport();
]]>
</body>
<method name="unblockPopup">
<parameter name="aPopupIndex"/>
<body><![CDATA[
this.messageManager.sendAsyncMessage("PopupBlocking:UnblockPopup",
{index: aPopupIndex});
]]></body>
</method>
<field name="pageReport">null</field>
<field name="blockedPopups">null</field>
<!-- Obsolete name for blockedPopups. Used by metro and android. -->
<property name="pageReport"
onget="return this.blockedPopups;"
readonly="true"/>
<property name="securityUI">
<getter>
@ -784,9 +761,9 @@
// Listen for first load for lazy attachment to form fill controller
this.addEventListener("pageshow", this.onPageShow, true);
this.addEventListener("pagehide", this.onPageHide, true);
this.addEventListener("DOMPopupBlocked", this.onPopupBlocked, true);
if (this.messageManager) {
this.messageManager.addMessageListener("PopupBlocking:UpdateBlockedPopups", this);
this.messageManager.addMessageListener("Autoscroll:Start", this);
this.messageManager.addMessageListener("Autoscroll:Cancel", this);
this.messageManager.loadFrameScript("chrome://global/content/browser-content.js", true);
@ -831,7 +808,6 @@
this.removeEventListener("pageshow", this.onPageShow, true);
this.removeEventListener("pagehide", this.onPageHide, true);
this.removeEventListener("DOMPopupBlocked", this.onPopupBlocked, true);
if (this._autoScrollNeedsCleanup) {
// we polluted the global scope, so clean it up
@ -850,6 +826,9 @@
<body><![CDATA[
let data = aMessage.data;
switch (aMessage.name) {
case "PopupBlocking:UpdateBlockedPopups":
this.updateBlockedPopups(data.blockedPopups, data.freshPopup);
break;
case "Autoscroll:Start": {
if (!this.autoscrollEnabled) {
return false;