Child.maxReportedPopups ); const result = []; for (let i = 0; i < length; ++i) { const popup = state.popups[i]; const { popupWindowURISpec } = popup; result.push({ popupWindowURISpec, }); } return result; } #getBlockedRedirect() { const redirect = this.#getOrCreateDocState().redirect; if (!redirect) { return null; } return { redirectURISpec: redirect.redirectURISpec, }; } #unblockPopup(aMessage) { const idx = aMessage.data.index; const popup = this.#getOrCreateDocState().popups[idx]; if (popup?.requestingWindow?.document == popup.requestingDocument) { popup.requestingWindow.open( popup.popupWindowURISpec, popup.popupWindowName, popup.popupWindowFeatures ); } } handleEvent(aEvent) { // Ignore events from other docs (e.g. subframes or old navigated docs). if (aEvent.target != this.document) { return; } switch (aEvent.type) { case "DOMPopupBlocked": this.#onPopupBlocked(aEvent); break; case "DOMRedirectBlocked": this.#onRedirectBlocked(aEvent); break; } } #onPopupBlocked(aEvent) { const state = this.#getOrCreateDocState(); if ( state.popups.length >= PopupAndRedirectBlockingChild.maxReportedPopups ) { return; } const popup = { // If an empty string is passed to window.open, it will open // "about:blank". popupWindowURISpec: aEvent.popupWindowURI?.spec ?? "about:blank", popupWindowFeatures: aEvent.popupWindowFeatures, popupWindowName: aEvent.popupWindowName, requestingWindow: aEvent.requestingWindow, requestingDocument: aEvent.requestingWindow.document, }; state.popups.push(popup); this.#updateParentAboutBlockedPopups(); } #onRedirectBlocked(aEvent) { const state = this.#getOrCreateDocState(); // In case of multiple blocked redirects, we only store the first // since after redirecting the whole state would be destroyed anyway. if (state.redirect) { return; } const redirect = { redirectURISpec: aEvent.redirectURI.spec, requestingWindow: aEvent.requestingWindow, requestingDocument: aEvent.requestingWindow.document, }; state.redirect = redirect; this.#updateParentAboutBlockedRedirect(); } #updateParentAboutBlockedPopups() { this.sendAsyncMessage("UpdateBlockedPopups", { count: this.#getOrCreateDocState().popups.length, }); } #updateParentAboutBlockedRedirect() { this.sendAsyncMessage("UpdateBlockedRedirect"); } } XPCOMUtils.defineLazyPreferenceGetter( PopupAndRedirectBlockingChild, "maxReportedPopups", "privacy.popups.maxReported" ); PK