# HG changeset patch # Parent c70f8175fd0c72a5a54993bd6519f65597314fa8 # User Gian-Carlo Pascutto Add doorhangers for popup blocker. diff --git a/mobile/chrome/content/browser.js b/mobile/chrome/content/browser.js --- a/mobile/chrome/content/browser.js +++ b/mobile/chrome/content/browser.js @@ -342,19 +342,22 @@ var BrowserEventHandler = { window.addEventListener("mouseup", this, true); window.addEventListener("mousemove", this, true); BrowserApp.deck.addEventListener("MozMagnifyGestureStart", this, true); BrowserApp.deck.addEventListener("MozMagnifyGestureUpdate", this, true); BrowserApp.deck.addEventListener("DOMContentLoaded", this, true); BrowserApp.deck.addEventListener("DOMLinkAdded", this, true); BrowserApp.deck.addEventListener("DOMTitleChanged", this, true); + BrowserApp.deck.addEventListener("DOMUpdatePageReport", gPopupBlockerObserver, false); + dump("Initializing listeners in BrowserEventHandler"); }, handleEvent: function(aEvent) { + dump("handleEvent: " + aEvent.type); switch (aEvent.type) { case "DOMContentLoaded": { let browser = BrowserApp.getBrowserForDocument(aEvent.target); let tabID = BrowserApp.getTabForBrowser(browser).id; let uri = browser.currentURI.spec; dump("Setting Last uri to: " + uri); Services.prefs.setCharPref("browser.last.uri", uri); @@ -689,8 +692,257 @@ var BrowserEventHandler = { } } else if (elem.scrollTop >= (elem.scrollHeight - elem.clientHeight)) { scrollY = false; } return scrollX || scrollY; } }; + +var gPopupBlockerObserver = { + _reportButton: null, + + onReportButtonClick: function (aEvent) + { + if (aEvent.button != 0 || aEvent.target != this._reportButton) + return; + + document.getElementById("blockedPopupOptions") + .openPopup(this._reportButton, "after_end", 0, 2, false, false, aEvent); + }, + + handleEvent: function (aEvent) + { + dump("Handle event for popupblockerobserver"); + if (aEvent.originalTarget != gBrowser.selectedBrowser) + return; + + if (!this._reportButton && gURLBar) + this._reportButton = document.getElementById("page-report-button"); + + if (!gBrowser.pageReport) { + // Hide the icon in the location bar (if the location bar exists) + if (gURLBar) + this._reportButton.hidden = true; + return; + } + + if (gURLBar) + this._reportButton.hidden = false; + + // 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 (gPrefService.getBoolPref("privacy.popups.showBrowserMessage")) { + var brandBundle = document.getElementById("bundle_brand"); + var brandShortName = brandBundle.getString("brandShortName"); + var message; + var popupCount = gBrowser.pageReport.length; +#ifdef XP_WIN + var popupButtonText = gNavigatorBundle.getString("popupWarningButton"); + var popupButtonAccesskey = gNavigatorBundle.getString("popupWarningButton.accesskey"); +#else + var popupButtonText = gNavigatorBundle.getString("popupWarningButtonUnix"); + var popupButtonAccesskey = gNavigatorBundle.getString("popupWarningButtonUnix.accesskey"); +#endif + if (popupCount > 1) + message = gNavigatorBundle.getFormattedString("popupWarningMultiple", [brandShortName, popupCount]); + else + message = gNavigatorBundle.getFormattedString("popupWarning", [brandShortName]); + + var notificationBox = gBrowser.getNotificationBox(); + var notification = notificationBox.getNotificationWithValue("popup-blocked"); + if (notification) { + notification.label = message; + } + else { + var buttons = [{ + label: popupButtonText, + accessKey: popupButtonAccesskey, + popup: "blockedPopupOptions", + callback: null + }]; + + const priority = notificationBox.PRIORITY_WARNING_MEDIUM; + notificationBox.appendNotification(message, "popup-blocked", + "chrome://browser/skin/Info.png", + priority, buttons); + } + } + + // Record the fact that we've reported this blocked popup, so we don't + // show it again. + gBrowser.pageReport.reported = true; + } + }, + + toggleAllowPopupsForSite: function (aEvent) + { + var pm = Services.perms; + var shouldBlock = aEvent.target.getAttribute("block") == "true"; + var perm = shouldBlock ? pm.DENY_ACTION : pm.ALLOW_ACTION; + pm.add(gBrowser.currentURI, "popup", perm); + + gBrowser.getNotificationBox().removeCurrentNotification(); + }, + + 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 " + // menuitems for the common subset of hosts present in the report, this will + // make us frame-safe. + // + // XXXjst - Note that when this is fixed to work with multi-framed sites, + // 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; + var blockedPopupAllowSite = document.getElementById("blockedPopupAllowSite"); + try { + blockedPopupAllowSite.removeAttribute("hidden"); + + var pm = Services.perms; + if (pm.testPermission(uri, "popup") == pm.ALLOW_ACTION) { + // Offer an item to block popups for this site, if a whitelist entry exists + // already for it. + let blockString = gNavigatorBundle.getFormattedString("popupBlock", [uri.host]); + blockedPopupAllowSite.setAttribute("label", blockString); + blockedPopupAllowSite.setAttribute("block", "true"); + } + else { + // Offer an item to allow popups for this site + let allowString = gNavigatorBundle.getFormattedString("popupAllow", [uri.host]); + blockedPopupAllowSite.setAttribute("label", allowString); + blockedPopupAllowSite.removeAttribute("block"); + } + } + catch (e) { + blockedPopupAllowSite.setAttribute("hidden", "true"); + } + + if (gPrivateBrowsingUI.privateBrowsingEnabled) + blockedPopupAllowSite.setAttribute("disabled", "true"); + else + blockedPopupAllowSite.removeAttribute("disabled"); + + var foundUsablePopupURI = false; + var pageReport = gBrowser.pageReport; + if (pageReport) { + for (var i = 0; i < pageReport.length; ++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[i].popupWindowURI) + continue; + var popupURIspec = pageReport[i].popupWindowURI.spec; + + // Sometimes the popup URI that we get back from the pageReport + // 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 + // useful to the user, so we won't create a menu item for it. + if (popupURIspec == "" || popupURIspec == "about:blank" || + popupURIspec == uri.spec) + continue; + + // Because of the short-circuit above, we may end up in a situation + // in which we don't have any usable popup addresses to show in + // the menu, and therefore we shouldn't show the separator. However, + // since we got past the short-circuit, we must've found at least + // one usable popup URI and thus we'll turn on the separator later. + foundUsablePopupURI = true; + + var menuitem = document.createElement("menuitem"); + var label = gNavigatorBundle.getFormattedString("popupShowPopupPrefix", + [popupURIspec]); + menuitem.setAttribute("label", label); + menuitem.setAttribute("popupWindowURI", popupURIspec); + menuitem.setAttribute("popupWindowFeatures", pageReport[i].popupWindowFeatures); + menuitem.setAttribute("popupWindowName", pageReport[i].popupWindowName); + menuitem.setAttribute("oncommand", "gPopupBlockerObserver.showBlockedPopup(event);"); + menuitem.requestingWindow = pageReport[i].requestingWindow; + menuitem.requestingDocument = pageReport[i].requestingDocument; + aEvent.target.appendChild(menuitem); + } + } + + // Show or hide the separator, depending on whether we added any + // showable popup addresses to the menu. + var blockedPopupsSeparator = + document.getElementById("blockedPopupsSeparator"); + if (foundUsablePopupURI) + blockedPopupsSeparator.removeAttribute("hidden"); + else + blockedPopupsSeparator.setAttribute("hidden", true); + + var blockedPopupDontShowMessage = document.getElementById("blockedPopupDontShowMessage"); + var showMessage = gPrefService.getBoolPref("privacy.popups.showBrowserMessage"); + blockedPopupDontShowMessage.setAttribute("checked", !showMessage); + if (aEvent.target.anchorNode.id == "page-report-button") { + aEvent.target.anchorNode.setAttribute("open", "true"); + blockedPopupDontShowMessage.setAttribute("label", gNavigatorBundle.getString("popupWarningDontShowFromLocationbar")); + } else + blockedPopupDontShowMessage.setAttribute("label", gNavigatorBundle.getString("popupWarningDontShowFromMessage")); + }, + + onPopupHiding: function (aEvent) { + if (aEvent.target.anchorNode.id == "page-report-button") + aEvent.target.anchorNode.removeAttribute("open"); + + let item = aEvent.target.lastChild; + while (item && item.getAttribute("observes") != "blockedPopupsSeparator") { + let next = item.previousSibling; + item.parentNode.removeChild(item); + item = next; + } + }, + + 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); + } + }, + + editPopupSettings: function () + { + var host = ""; + try { + host = gBrowser.currentURI.host; + } + catch (e) { } + + var bundlePreferences = document.getElementById("bundle_preferences"); + var params = { blockVisible : false, + sessionVisible : false, + allowVisible : true, + prefilledHost : host, + permissionType : "popup", + windowTitle : bundlePreferences.getString("popuppermissionstitle"), + introText : bundlePreferences.getString("popuppermissionstext") }; + var existingWindow = Services.wm.getMostRecentWindow("Browser:Permissions"); + if (existingWindow) { + existingWindow.initWithParams(params); + existingWindow.focus(); + } + else + window.openDialog("chrome://browser/content/preferences/permissions.xul", + "_blank", "resizable,dialog=no,centerscreen", params); + }, + + dontShowMessage: function () + { + var showMessage = gPrefService.getBoolPref("privacy.popups.showBrowserMessage"); + gPrefService.setBoolPref("privacy.popups.showBrowserMessage", !showMessage); + gBrowser.getNotificationBox().removeCurrentNotification(); + } +};