1 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 /* eslint no-unused-vars: ["error", {args: "none"}] */
8 var EXPORTED_SYMBOLS = ["PopupBlockingChild"];
10 // The maximum number of popup information we'll send to the parent.
11 const MAX_SENT_POPUPS = 15;
13 const { XPCOMUtils } = ChromeUtils.import(
14 "resource://gre/modules/XPCOMUtils.jsm"
17 class PopupBlockingChild extends JSWindowActorChild {
20 this.weakDocStates = new WeakMap();
24 this.contentWindow.addEventListener("pageshow", this);
28 this.contentWindow.removeEventListener("pageshow", this);
32 * Returns the state for the current document referred to via
33 * this.document. If no such state exists, creates it, stores it
37 let state = this.weakDocStates.get(this.document);
42 this.weakDocStates.set(this.document, state);
50 case "UnblockPopup": {
51 let i = msg.data.index;
52 let state = this.docState;
53 let popupData = state.popupData[i];
55 let dwi = popupData.requestingWindow;
57 // If we have a requesting window and the requesting document is
58 // still the current document, open the popup.
59 if (dwi && dwi.document == popupData.requestingDocument) {
61 popupData.popupWindowURISpec,
62 popupData.popupWindowName,
63 popupData.popupWindowFeatures
70 case "GetBlockedPopupList": {
71 let state = this.docState;
72 let length = Math.min(state.popupData.length, MAX_SENT_POPUPS);
76 for (let i = 0; i < length; ++i) {
77 let popup = state.popupData[i];
79 let popupWindowURISpec = popup.popupWindowURISpec;
81 if (this.contentWindow.location.href == popupWindowURISpec) {
82 popupWindowURISpec = "<self>";
84 // Limit 500 chars to be sent because the URI will be cropped
85 // by the UI anyway, and data: URIs can be significantly larger.
86 popupWindowURISpec = popupWindowURISpec.substring(0, 500);
102 switch (event.type) {
103 case "DOMPopupBlocked":
104 this.onPopupBlocked(event);
107 this.onPageShow(event);
113 onPopupBlocked(event) {
114 if (event.target != this.document) {
118 let state = this.docState;
120 // Avoid spamming the parent process with too many blocked popups.
121 if (state.popupData.length >= PopupBlockingChild.maxReportedPopups) {
126 popupWindowURISpec: event.popupWindowURI
127 ? event.popupWindowURI.spec
129 popupWindowFeatures: event.popupWindowFeatures,
130 popupWindowName: event.popupWindowName,
131 requestingWindow: event.requestingWindow,
132 requestingDocument: event.requestingWindow.document,
135 state.popupData.push(popup);
136 this.updateBlockedPopups(true);
140 if (event.target != this.document) {
144 this.updateBlockedPopups(false);
147 updateBlockedPopups(shouldNotify) {
148 this.sendAsyncMessage("UpdateBlockedPopups", {
150 count: this.docState.popupData.length,
155 XPCOMUtils.defineLazyPreferenceGetter(
158 "privacy.popups.maxReported"