ckedOpened.record(); this.setupBlockLayout(uploadEnabled); } this.setupEventHandlers(); if (uploadEnabled) { this.elements.telemetryDisabledMessage.setAttribute("hidden", "true"); } else { this.elements.telemetryDisabledMessage.removeAttribute("hidden"); } this.elements.reportCheckbox.disabled = !uploadEnabled; this.elements.emailCheckbox.disabled = !uploadEnabled; this.elements.emailInput.disabled = !uploadEnabled; this.elements.emailInput.readOnly = !uploadEnabled; } setupEventHandlers() { this.elements.dialogCloseButton.addEventListener("click", () => { this.close(true); }); // This is needed because a simple element on the page run afoul // of the "Content windows may never have chrome windows as their openers" // error, so we use openTrustedLinkIn instead." this.elements.moreInfoLink.addEventListener("click", () => { this.onLearnMoreLink(); }); this.elements.learnMoreLink.addEventListener("click", () => { this.onLearnMoreLink(); }); this.elements.allowButton.addEventListener("click", () => { this.onAllow(); }); this.elements.blockButton.addEventListener("click", () => { this.onBlock(); }); // If the user has filled in their email, but not checked the report checkbox, // we automatically check both report checkboxes when the email input loses focus. this.elements.emailInput.addEventListener("change", e => { const hasEmail = this.elements.emailInput.value.trim() !== ""; if (!hasEmail) { return; } // If the user has typed in the email field, and clicks the (unchecked) // email checkbox, on blur we would set the email checkbox to checked, // then the click event would toggle it back to unchecked. So we need to // defer the check to the next event loop tick. setTimeout(() => { this.console?.warn(`Rechecking checkboxes`); if (this.elements.emailInput.value.trim()) { this.elements.emailCheckbox.checked = true; this.elements.reportCheckbox.checked = true; } }, 0); // The email input field is _inside_ the email checkbox, so we need to // stop the click event from propagating to the checkbox e.stopPropagation(); }); // If the user unchecks the report email checkbox, clear the email field // This is a little complicated because this.elements.emailCheckbox.addEventListener("change", () => { if (!this.elements.emailCheckbox.checked) { this.elements.emailInput.value = ""; } }); // If the user unchecks the report checkbox, clear the email field this.elements.reportCheckbox.addEventListener("change", () => { if (!this.elements.reportCheckbox.checked) { this.elements.emailCheckbox.checked = false; this.elements.emailInput.value = ""; } }); } setupAllowLayout() { this.elements.unexpectedScriptLoadDetail1.setAttribute( "data-l10n-id", "unexpected-script-load-detail-1-allow" ); this.elements.allowButton.setAttribute("type", "primary"); this.elements.blockButton.setAttribute("type", ""); } setupBlockLayout(uploadEnabled) { this.elements.unexpectedScriptLoadDetail1.setAttribute( "data-l10n-id", "unexpected-script-load-detail-1-block" ); this.elements.reportCheckbox.checked = uploadEnabled; this.elements.allowButton.setAttribute("type", ""); this.elements.blockButton.setAttribute("type", "primary"); } /** * Hide the pop up (for event handlers). * * @param {boolean} userDismissed */ close(userDismissed) { this.console?.log("UnexpectedScriptLoadPanel is closing"); if (userDismissed) { Glean.unexpectedScriptLoad.dialogDismissed.record(); } window.close(); GleanPings.unexpectedScriptLoad.submit(); } /* * Handler for clicking the learn more link from linked text * within the translations panel. */ onLearnMoreLink() { Glean.unexpectedScriptLoad.moreInfoOpened.record(); this.close(false); // This is an ugly hack. // If a modal is open, we will not focus the tab we are opening, even if we ask to // ref: https://searchfox.org/mozilla-central/rev/fcb776c1d580000af961677f6df3aeef67168a6f/browser/components/tabbrowser/content/tabbrowser.js#438 // However we do not remove the window-modal-open until _after_ the dialog is closed // which is after we open the tab. // ref: https://searchfox.org/mozilla-central/rev/fcb776c1d580000af961677f6df3aeef67168a6f/browser/base/content/browser.js#5180 window.top.document.documentElement.removeAttribute("window-modal-open"); window.browsingContext.top.window.openTrustedLinkIn( "https://support.mozilla.org/kb/unexpected-script-load", "tab" ); } maybeReport() { if (this.elements.reportCheckbox.checked) { let extra = { script_url: this.#scriptName, }; if (this.elements.emailCheckbox.checked) { extra.user_email = this.elements.emailInput.value.trim(); } Glean.unexpectedScriptLoad.scriptReported.record(extra); } } onBlock() { this.console?.log("UnexpectedScriptLoadPanel.onBlock() called"); Glean.unexpectedScriptLoad.scriptBlocked.record(); this.maybeReport(); Services.prefs.setBoolPref( "security.block_parent_unrestricted_js_loads.temporary", true ); window.browsingContext.top.window.gNotificationBox .getNotificationWithValue("unexpected-script-notification") ?.close(); Services.obs.notifyObservers( null, "UnexpectedJavaScriptLoad-UserTookAction" ); this.close(false); } onAllow() { this.console?.log("UnexpectedScriptLoadPanel.onAllow() called"); Glean.unexpectedScriptLoad.scriptAllowed.record(); this.maybeReport(); Services.prefs.setBoolPref( "security.allow_parent_unrestricted_js_loads", true ); window.browsingContext.top.window.gNotificationBox .getNotificationWithValue("unexpected-script-notification") ?.close(); Services.obs.notifyObservers( null, "UnexpectedJavaScriptLoad-UserTookAction" ); this.close(false); } })(); // Call the init method when the script loads UnexpectedScriptLoadPanel.init(); PK