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.importESModule(
14 "resource://gre/modules/XPCOMUtils.sys.mjs"
17 class PopupBlockingChild extends JSWindowActorChild {
20 this.weakDocStates = new WeakMap();
24 * Returns the state for the current document referred to via
25 * this.document. If no such state exists, creates it, stores it
29 let state = this.weakDocStates.get(this.document);
34 this.weakDocStates.set(this.document, state);
42 case "UnblockPopup": {
43 let i = msg.data.index;
44 let state = this.docState;
45 let popupData = state.popupData[i];
47 let dwi = popupData.requestingWindow;
49 // If we have a requesting window and the requesting document is
50 // still the current document, open the popup.
51 if (dwi && dwi.document == popupData.requestingDocument) {
53 popupData.popupWindowURISpec,
54 popupData.popupWindowName,
55 popupData.popupWindowFeatures
62 case "GetBlockedPopupList": {
63 let state = this.docState;
64 let length = Math.min(state.popupData.length, MAX_SENT_POPUPS);
68 for (let i = 0; i < length; ++i) {
69 let popup = state.popupData[i];
71 let popupWindowURISpec = popup.popupWindowURISpec;
73 if (this.contentWindow.location.href == popupWindowURISpec) {
74 popupWindowURISpec = "<self>";
76 // Limit 500 chars to be sent because the URI will be cropped
77 // by the UI anyway, and data: URIs can be significantly larger.
78 popupWindowURISpec = popupWindowURISpec.substring(0, 500);
95 case "DOMPopupBlocked":
96 this.onPopupBlocked(event);
99 this.onPageShow(event);
105 onPopupBlocked(event) {
106 if (event.target != this.document) {
110 let state = this.docState;
112 // Avoid spamming the parent process with too many blocked popups.
113 if (state.popupData.length >= PopupBlockingChild.maxReportedPopups) {
118 popupWindowURISpec: event.popupWindowURI
119 ? event.popupWindowURI.spec
121 popupWindowFeatures: event.popupWindowFeatures,
122 popupWindowName: event.popupWindowName,
123 requestingWindow: event.requestingWindow,
124 requestingDocument: event.requestingWindow.document,
127 state.popupData.push(popup);
128 this.updateBlockedPopups(true);
132 if (event.target != this.document) {
136 this.updateBlockedPopups(false);
139 updateBlockedPopups(shouldNotify) {
140 this.sendAsyncMessage("UpdateBlockedPopups", {
142 count: this.docState.popupData.length,
147 XPCOMUtils.defineLazyPreferenceGetter(
150 "privacy.popups.maxReported"