Bug 1888590 - Mark some subtests on trusted-types-event-handlers.html as failing...
[gecko.git] / toolkit / actors / PopupBlockingChild.sys.mjs
blob053f9683c598c1991f7174e97df3c7cc2ec83182
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 // The maximum number of popup information we'll send to the parent.
9 const MAX_SENT_POPUPS = 15;
11 import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs";
13 export class PopupBlockingChild extends JSWindowActorChild {
14   constructor() {
15     super();
16     this.weakDocStates = new WeakMap();
17   }
19   /**
20    * Returns the state for the current document referred to via
21    * this.document. If no such state exists, creates it, stores it
22    * and returns it.
23    */
24   get docState() {
25     let state = this.weakDocStates.get(this.document);
26     if (!state) {
27       state = {
28         popupData: [],
29       };
30       this.weakDocStates.set(this.document, state);
31     }
33     return state;
34   }
36   receiveMessage(msg) {
37     switch (msg.name) {
38       case "UnblockPopup": {
39         let i = msg.data.index;
40         let state = this.docState;
41         let popupData = state.popupData[i];
42         if (popupData) {
43           let dwi = popupData.requestingWindow;
45           // If we have a requesting window and the requesting document is
46           // still the current document, open the popup.
47           if (dwi && dwi.document == popupData.requestingDocument) {
48             dwi.open(
49               popupData.popupWindowURISpec,
50               popupData.popupWindowName,
51               popupData.popupWindowFeatures
52             );
53           }
54         }
55         break;
56       }
58       case "GetBlockedPopupList": {
59         let state = this.docState;
60         let length = Math.min(state.popupData.length, MAX_SENT_POPUPS);
62         let result = [];
64         for (let i = 0; i < length; ++i) {
65           let popup = state.popupData[i];
67           let popupWindowURISpec = popup.popupWindowURISpec;
69           if (this.contentWindow.location.href == popupWindowURISpec) {
70             popupWindowURISpec = "<self>";
71           } else {
72             // Limit 500 chars to be sent because the URI will be cropped
73             // by the UI anyway, and data: URIs can be significantly larger.
74             popupWindowURISpec = popupWindowURISpec.substring(0, 500);
75           }
77           result.push({
78             popupWindowURISpec,
79           });
80         }
82         return result;
83       }
84     }
86     return null;
87   }
89   handleEvent(event) {
90     switch (event.type) {
91       case "DOMPopupBlocked":
92         this.onPopupBlocked(event);
93         break;
94       case "pageshow": {
95         this.onPageShow(event);
96         break;
97       }
98     }
99   }
101   onPopupBlocked(event) {
102     if (event.target != this.document) {
103       return;
104     }
106     let state = this.docState;
108     // Avoid spamming the parent process with too many blocked popups.
109     if (state.popupData.length >= PopupBlockingChild.maxReportedPopups) {
110       return;
111     }
113     let popup = {
114       popupWindowURISpec: event.popupWindowURI
115         ? event.popupWindowURI.spec
116         : "about:blank",
117       popupWindowFeatures: event.popupWindowFeatures,
118       popupWindowName: event.popupWindowName,
119       requestingWindow: event.requestingWindow,
120       requestingDocument: event.requestingWindow.document,
121     };
123     state.popupData.push(popup);
124     this.updateBlockedPopups(true);
125   }
127   onPageShow(event) {
128     if (event.target != this.document) {
129       return;
130     }
132     this.updateBlockedPopups(false);
133   }
135   updateBlockedPopups(shouldNotify) {
136     this.sendAsyncMessage("UpdateBlockedPopups", {
137       shouldNotify,
138       count: this.docState.popupData.length,
139     });
140   }
143 XPCOMUtils.defineLazyPreferenceGetter(
144   PopupBlockingChild,
145   "maxReportedPopups",
146   "privacy.popups.maxReported"