ma1 pushed to branch mullvad-browser-128.5.0esr-14.0-1 at The Tor Project / Applications / Mullvad Browser
Commits:
-
437543c6
by Arturo Mejia at 2024-11-25T15:21:36+01:00
-
33f6b33b
by Malte Juergens at 2024-11-25T15:21:38+01:00
-
412bde12
by Makoto Kato at 2024-11-25T15:21:40+01:00
-
866130a7
by Cathy Lu at 2024-11-25T15:21:41+01:00
16 changed files:
- dom/ipc/WindowGlobalParent.cpp
- dom/security/test/https-only/browser.toml
- + dom/security/test/https-only/browser_iframe_buttons.js
- + dom/security/test/https-only/file_iframe_buttons.html
- mobile/android/android-components/components/feature/app-links/src/main/java/mozilla/components/feature/app/links/SimpleRedirectDialogFragment.kt
- mobile/android/android-components/components/feature/app-links/src/test/java/mozilla/components/feature/app/links/SimpleRedirectDialogFragmentTest.kt
- mobile/android/android-components/components/feature/session/src/main/java/mozilla/components/feature/session/SessionUseCases.kt
- mobile/android/android-components/components/feature/session/src/test/java/mozilla/components/feature/session/SessionUseCasesTest.kt
- mobile/android/android-components/docs/changelog.md
- mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CrashReportingTest.kt
- mobile/android/geckoview/src/main/java/org/mozilla/gecko/Clipboard.java
- mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoInputConnection.java
- toolkit/components/httpsonlyerror/content/errorpage.html
- toolkit/components/httpsonlyerror/content/errorpage.js
- toolkit/locales/en-US/toolkit/about/aboutHttpsOnlyError.ftl
- widget/android/nsClipboard.cpp
Changes:
... | ... | @@ -1378,18 +1378,11 @@ mozilla::ipc::IPCResult WindowGlobalParent::RecvReloadWithHttpsOnlyException() { |
1378 | 1378 | return IPC_FAIL(this, "HTTPS-only mode: Illegal state");
|
1379 | 1379 | }
|
1380 | 1380 | |
1381 | - // If the error page is within an iFrame, we create an exception for whatever
|
|
1382 | - // scheme the top-level site is currently on, because the user wants to
|
|
1383 | - // unbreak the iFrame and not the top-level page. When the error page shows up
|
|
1384 | - // on a top-level request, then we replace the scheme with http, because the
|
|
1385 | - // user wants to unbreak the whole page.
|
|
1381 | + // We replace the scheme with http, because the user wants to unbreak the
|
|
1382 | + // whole page.
|
|
1386 | 1383 | nsCOMPtr<nsIURI> newURI;
|
1387 | - if (!BrowsingContext()->IsTop()) {
|
|
1388 | - newURI = innerURI;
|
|
1389 | - } else {
|
|
1390 | - Unused << NS_MutateURI(innerURI).SetScheme("http"_ns).Finalize(
|
|
1391 | - getter_AddRefs(newURI));
|
|
1392 | - }
|
|
1384 | + Unused << NS_MutateURI(innerURI).SetScheme("http"_ns).Finalize(
|
|
1385 | + getter_AddRefs(newURI));
|
|
1393 | 1386 | |
1394 | 1387 | OriginAttributes originAttributes =
|
1395 | 1388 | TopWindowContext()->DocumentPrincipal()->OriginAttributesRef();
|
... | ... | @@ -29,6 +29,9 @@ support-files = [ |
29 | 29 | ["browser_httpsonly_speculative_connect.js"]
|
30 | 30 | support-files = ["file_httpsonly_speculative_connect.html"]
|
31 | 31 | |
32 | +["browser_iframe_buttons.js"]
|
|
33 | +support-files = ["file_iframe_buttons.html"]
|
|
34 | + |
|
32 | 35 | ["browser_iframe_test.js"]
|
33 | 36 | skip-if = [
|
34 | 37 | "os == 'linux' && bits == 64", # Bug 1735565
|
1 | +/* Any copyright is dedicated to the Public Domain.
|
|
2 | + https://creativecommons.org/publicdomain/zero/1.0/ */
|
|
3 | + |
|
4 | +"use strict";
|
|
5 | + |
|
6 | +// Ensure the buttons at the buttom of the HTTPS-Only error page do not get
|
|
7 | +// displayed in an iframe (Bug 1909396).
|
|
8 | + |
|
9 | +add_task(async function test_iframe_buttons() {
|
|
10 | + await BrowserTestUtils.withNewTab(
|
|
11 | + "https://example.com/browser/dom/security/test/https-only/file_iframe_buttons.html",
|
|
12 | + async function (browser) {
|
|
13 | + await SpecialPowers.pushPrefEnv({
|
|
14 | + set: [["dom.security.https_only_mode", true]],
|
|
15 | + });
|
|
16 | + |
|
17 | + await SpecialPowers.spawn(browser, [], async function () {
|
|
18 | + const iframe = content.document.getElementById("iframe");
|
|
19 | + // eslint-disable-next-line @microsoft/sdl/no-insecure-url
|
|
20 | + iframe.src = "http://nocert.example.com";
|
|
21 | + |
|
22 | + await ContentTaskUtils.waitForCondition(
|
|
23 | + () => iframe.contentWindow.document.readyState === "interactive",
|
|
24 | + "Iframe error page should have loaded"
|
|
25 | + );
|
|
26 | + |
|
27 | + ok(
|
|
28 | + !!iframe.contentWindow.document.getElementById("explanation-iframe"),
|
|
29 | + "#explanation-iframe should exist"
|
|
30 | + );
|
|
31 | + |
|
32 | + is(
|
|
33 | + iframe.contentWindow.document
|
|
34 | + .getElementById("explanation-iframe")
|
|
35 | + .getAttribute("hidden"),
|
|
36 | + null,
|
|
37 | + "#explanation-iframe should not be hidden"
|
|
38 | + );
|
|
39 | + |
|
40 | + for (const id of ["explanation-continue", "goBack", "openInsecure"]) {
|
|
41 | + is(
|
|
42 | + iframe.contentWindow.document.getElementById(id),
|
|
43 | + null,
|
|
44 | + `#${id} should have been removed`
|
|
45 | + );
|
|
46 | + }
|
|
47 | + });
|
|
48 | + }
|
|
49 | + );
|
|
50 | +}); |
1 | +<!DOCTYPE html>
|
|
2 | +<html lang="en">
|
|
3 | +<head>
|
|
4 | + <meta charset="UTF-8">
|
|
5 | +</head>
|
|
6 | +<body>
|
|
7 | + <iframe id="iframe" frameborder="0"></iframe>
|
|
8 | +</body>
|
|
9 | +</html> |
... | ... | @@ -11,6 +11,7 @@ import androidx.annotation.StringRes |
11 | 11 | import androidx.annotation.StyleRes
|
12 | 12 | import androidx.annotation.VisibleForTesting
|
13 | 13 | import androidx.appcompat.app.AlertDialog
|
14 | +import mozilla.components.support.ktx.util.PromptAbuserDetector
|
|
14 | 15 | import mozilla.components.ui.widgets.withCenterAlignedButtons
|
15 | 16 | |
16 | 17 | /**
|
... | ... | @@ -23,6 +24,10 @@ import mozilla.components.ui.widgets.withCenterAlignedButtons |
23 | 24 | */
|
24 | 25 | class SimpleRedirectDialogFragment : RedirectDialogFragment() {
|
25 | 26 | |
27 | + @VisibleForTesting
|
|
28 | + internal var promptAbuserDetector =
|
|
29 | + PromptAbuserDetector(maxSuccessiveDialogSecondsLimit = TIME_SHOWN_OFFSET_SECONDS)
|
|
30 | + |
|
26 | 31 | @VisibleForTesting
|
27 | 32 | internal var testingContext: Context? = null
|
28 | 33 | |
... | ... | @@ -32,6 +37,8 @@ class SimpleRedirectDialogFragment : RedirectDialogFragment() { |
32 | 37 | return if (themeID == 0) AlertDialog.Builder(context) else AlertDialog.Builder(context, themeID)
|
33 | 38 | }
|
34 | 39 | |
40 | + promptAbuserDetector.updateJSDialogAbusedState()
|
|
41 | + |
|
35 | 42 | return with(requireBundle()) {
|
36 | 43 | val dialogTitleText = getInt(KEY_TITLE_TEXT, R.string.mozac_feature_applinks_normal_confirm_dialog_title)
|
37 | 44 | val dialogMessageString = getString(KEY_MESSAGE_STRING, "")
|
... | ... | @@ -40,18 +47,29 @@ class SimpleRedirectDialogFragment : RedirectDialogFragment() { |
40 | 47 | val themeResId = getInt(KEY_THEME_ID, 0)
|
41 | 48 | val cancelable = getBoolean(KEY_CANCELABLE, false)
|
42 | 49 | |
43 | - getBuilder(themeResId)
|
|
50 | + val dialog = getBuilder(themeResId)
|
|
44 | 51 | .setTitle(dialogTitleText)
|
45 | 52 | .setMessage(dialogMessageString)
|
46 | - .setPositiveButton(positiveButtonText) { _, _ ->
|
|
47 | - onConfirmRedirect()
|
|
48 | - }
|
|
53 | + .setPositiveButton(positiveButtonText) { _, _ -> }
|
|
49 | 54 | .setNegativeButton(negativeButtonText) { _, _ ->
|
50 | 55 | onCancelRedirect()
|
51 | 56 | }
|
52 | 57 | .setCancelable(cancelable)
|
53 | 58 | .create()
|
54 | - .withCenterAlignedButtons()
|
|
59 | + |
|
60 | + dialog.withCenterAlignedButtons()
|
|
61 | + dialog.setOnShowListener {
|
|
62 | + val okButton = dialog.getButton(AlertDialog.BUTTON_POSITIVE)
|
|
63 | + okButton.setOnClickListener {
|
|
64 | + if (promptAbuserDetector.areDialogsBeingAbused()) {
|
|
65 | + promptAbuserDetector.updateJSDialogAbusedState()
|
|
66 | + } else {
|
|
67 | + onConfirmRedirect()
|
|
68 | + dialog.dismiss()
|
|
69 | + }
|
|
70 | + }
|
|
71 | + }
|
|
72 | + dialog
|
|
55 | 73 | }
|
56 | 74 | }
|
57 | 75 | |
... | ... | @@ -101,6 +119,7 @@ class SimpleRedirectDialogFragment : RedirectDialogFragment() { |
101 | 119 | const val KEY_THEME_ID = "KEY_THEME_ID"
|
102 | 120 | |
103 | 121 | const val KEY_CANCELABLE = "KEY_CANCELABLE"
|
122 | + private const val TIME_SHOWN_OFFSET_SECONDS = 1
|
|
104 | 123 | }
|
105 | 124 | |
106 | 125 | private fun requireBundle(): Bundle {
|
... | ... | @@ -13,6 +13,7 @@ import mozilla.components.support.test.mock |
13 | 13 | import mozilla.components.support.test.robolectric.testContext
|
14 | 14 | import org.junit.Assert.assertFalse
|
15 | 15 | import org.junit.Assert.assertTrue
|
16 | +import org.junit.Ignore
|
|
16 | 17 | import org.junit.Test
|
17 | 18 | import org.junit.runner.RunWith
|
18 | 19 | import org.mockito.Mockito.doNothing
|
... | ... | @@ -27,6 +28,7 @@ class SimpleRedirectDialogFragmentTest { |
27 | 28 | private val themeResId = appcompatR.style.Theme_AppCompat_Light
|
28 | 29 | |
29 | 30 | @Test
|
31 | + @Ignore("This will be addressed in another follow up ticket")
|
|
30 | 32 | fun `Dialog confirmed callback is called correctly`() {
|
31 | 33 | var onConfirmCalled = false
|
32 | 34 | var onCancelCalled = false
|
... | ... | @@ -104,6 +106,7 @@ class SimpleRedirectDialogFragmentTest { |
104 | 106 | assertFalse(onCancelCalled)
|
105 | 107 | }
|
106 | 108 | |
109 | + @Suppress("unused")
|
|
107 | 110 | private fun mockFragmentManager(): FragmentManager {
|
108 | 111 | val fragmentManager: FragmentManager = mock()
|
109 | 112 | val transaction: FragmentTransaction = mock()
|
... | ... | @@ -4,7 +4,6 @@ |
4 | 4 | |
5 | 5 | package mozilla.components.feature.session
|
6 | 6 | |
7 | -import mozilla.components.browser.state.action.ContentAction
|
|
8 | 7 | import mozilla.components.browser.state.action.CrashAction
|
9 | 8 | import mozilla.components.browser.state.action.EngineAction
|
10 | 9 | import mozilla.components.browser.state.action.LastAccessAction
|
... | ... | @@ -94,13 +93,6 @@ class SessionUseCases( |
94 | 93 | flags = flags,
|
95 | 94 | additionalHeaders = additionalHeaders,
|
96 | 95 | )
|
97 | - // Update the url in content immediately until the engine updates with any new changes to the state.
|
|
98 | - store.dispatch(
|
|
99 | - ContentAction.UpdateUrlAction(
|
|
100 | - loadSessionId,
|
|
101 | - url,
|
|
102 | - ),
|
|
103 | - )
|
|
104 | 96 | store.dispatch(
|
105 | 97 | EngineAction.OptimizedLoadUrlTriggeredAction(
|
106 | 98 | loadSessionId,
|
... | ... | @@ -11,7 +11,6 @@ import mozilla.components.browser.state.action.EngineAction |
11 | 11 | import mozilla.components.browser.state.action.TabListAction
|
12 | 12 | import mozilla.components.browser.state.engine.EngineMiddleware
|
13 | 13 | import mozilla.components.browser.state.selector.findTab
|
14 | -import mozilla.components.browser.state.selector.selectedTab
|
|
15 | 14 | import mozilla.components.browser.state.state.BrowserState
|
16 | 15 | import mozilla.components.browser.state.state.TabSessionState
|
17 | 16 | import mozilla.components.browser.state.state.createCustomTab
|
... | ... | @@ -81,7 +80,6 @@ class SessionUseCasesTest { |
81 | 80 | assertEquals("mozilla", action.tabId)
|
82 | 81 | assertEquals("https://getpocket.com", action.url)
|
83 | 82 | }
|
84 | - assertEquals("https://getpocket.com", store.state.selectedTab?.content?.url)
|
|
85 | 83 | |
86 | 84 | useCases.loadUrl("https://www.mozilla.org", LoadUrlFlags.select(LoadUrlFlags.EXTERNAL))
|
87 | 85 | store.waitUntilIdle()
|
... | ... | @@ -95,7 +93,6 @@ class SessionUseCasesTest { |
95 | 93 | assertEquals("https://www.mozilla.org", action.url)
|
96 | 94 | assertEquals(LoadUrlFlags.select(LoadUrlFlags.EXTERNAL), action.flags)
|
97 | 95 | }
|
98 | - assertEquals("https://www.mozilla.org", store.state.selectedTab?.content?.url)
|
|
99 | 96 | |
100 | 97 | useCases.loadUrl("https://firefox.com", store.state.selectedTabId)
|
101 | 98 | store.waitUntilIdle()
|
... | ... | @@ -105,7 +102,6 @@ class SessionUseCasesTest { |
105 | 102 | assertEquals("mozilla", action.tabId)
|
106 | 103 | assertEquals("https://firefox.com", action.url)
|
107 | 104 | }
|
108 | - assertEquals("https://firefox.com", store.state.selectedTab?.content?.url)
|
|
109 | 105 | |
110 | 106 | useCases.loadUrl.invoke(
|
111 | 107 | "https://developer.mozilla.org",
|
... | ... | @@ -109,9 +109,6 @@ permalink: /changelog/ |
109 | 109 | * **feature-customtabs**
|
110 | 110 | * Fallback behaviour when failing to open a new window in custom tab will now be loading the URL directly in the same custom tab. [Bug 1832357](https://bugzilla.mozilla.org/show_bug.cgi?id=1832357)
|
111 | 111 | |
112 | -* **feature-session**
|
|
113 | - * Update URL in the store immediately when using the optimized load URL code path.
|
|
114 | - |
|
115 | 112 | * **tooling-lint**
|
116 | 113 | * Added a lint rule to detect when `Response#close` may not have been called. Note: Currently, this rule only runs on Android Components.
|
117 | 114 |
... | ... | @@ -83,7 +83,7 @@ class CrashReportingTest : TestSetup() { |
83 | 83 | verifyPageContent(tabCrashMessage)
|
84 | 84 | }.openTabDrawer(activityTestRule) {
|
85 | 85 | verifyExistingOpenTabs(firstWebPage.title)
|
86 | - verifyExistingOpenTabs("about:crashcontent")
|
|
86 | + verifyExistingOpenTabs(secondWebPage.title)
|
|
87 | 87 | }.closeTabDrawer {
|
88 | 88 | }.goToHomescreen {
|
89 | 89 | verifyExistingTopSitesList()
|
... | ... | @@ -11,6 +11,7 @@ import android.content.ClipboardManager.OnPrimaryClipChangedListener; |
11 | 11 | import android.content.Context;
|
12 | 12 | import android.content.res.AssetFileDescriptor;
|
13 | 13 | import android.os.Build;
|
14 | +import android.os.PersistableBundle;
|
|
14 | 15 | import android.text.TextUtils;
|
15 | 16 | import android.util.Log;
|
16 | 17 | import java.io.ByteArrayOutputStream;
|
... | ... | @@ -133,8 +134,9 @@ public final class Clipboard { |
133 | 134 | * @return true if copy is successful.
|
134 | 135 | */
|
135 | 136 | @WrapForJNI(calledFrom = "gecko")
|
136 | - public static boolean setText(final Context context, final CharSequence text) {
|
|
137 | - return setData(context, ClipData.newPlainText("text", text));
|
|
137 | + public static boolean setText(
|
|
138 | + final Context context, final CharSequence text, final boolean isPrivateData) {
|
|
139 | + return setData(context, ClipData.newPlainText("text", text), isPrivateData);
|
|
138 | 140 | }
|
139 | 141 | |
140 | 142 | /**
|
... | ... | @@ -147,8 +149,11 @@ public final class Clipboard { |
147 | 149 | */
|
148 | 150 | @WrapForJNI(calledFrom = "gecko")
|
149 | 151 | private static boolean setHTML(
|
150 | - final Context context, final CharSequence text, final String htmlText) {
|
|
151 | - return setData(context, ClipData.newHtmlText("html", text, htmlText));
|
|
152 | + final Context context,
|
|
153 | + final CharSequence text,
|
|
154 | + final String htmlText,
|
|
155 | + final boolean isPrivateData) {
|
|
156 | + return setData(context, ClipData.newHtmlText("html", text, htmlText), isPrivateData);
|
|
152 | 157 | }
|
153 | 158 | |
154 | 159 | /**
|
... | ... | @@ -158,11 +163,17 @@ public final class Clipboard { |
158 | 163 | * @param clipData a {@link android.content.ClipData} to set to clipboard
|
159 | 164 | * @return true if copy is successful.
|
160 | 165 | */
|
161 | - private static boolean setData(final Context context, final ClipData clipData) {
|
|
166 | + private static boolean setData(
|
|
167 | + final Context context, final ClipData clipData, final boolean isPrivateData) {
|
|
162 | 168 | // In API Level 11 and above, CLIPBOARD_SERVICE returns android.content.ClipboardManager,
|
163 | 169 | // which is a subclass of android.text.ClipboardManager.
|
164 | 170 | final ClipboardManager cm =
|
165 | 171 | (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
|
172 | + if (isPrivateData && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
|
173 | + final PersistableBundle extras = new PersistableBundle();
|
|
174 | + extras.putBoolean(ClipDescription.EXTRA_IS_SENSITIVE, true);
|
|
175 | + clipData.getDescription().setExtras(extras);
|
|
176 | + }
|
|
166 | 177 | try {
|
167 | 178 | cm.setPrimaryClip(clipData);
|
168 | 179 | } catch (final NullPointerException e) {
|
... | ... | @@ -228,7 +239,7 @@ public final class Clipboard { |
228 | 239 | @WrapForJNI(calledFrom = "gecko")
|
229 | 240 | private static void clear(final Context context) {
|
230 | 241 | if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) {
|
231 | - setText(context, null);
|
|
242 | + setText(context, null, false);
|
|
232 | 243 | return;
|
233 | 244 | }
|
234 | 245 | // Although we don't know more details of https://crbug.com/1203377, Blink doesn't use
|
... | ... | @@ -70,6 +70,7 @@ import org.mozilla.gecko.util.ThreadUtils; |
70 | 70 | private ExtractedTextRequest mUpdateRequest;
|
71 | 71 | private final InputConnection mKeyInputConnection;
|
72 | 72 | private CursorAnchorInfo.Builder mCursorAnchorInfoBuilder;
|
73 | + private boolean mIsPrivateBrowsing;
|
|
73 | 74 | |
74 | 75 | public static SessionTextInput.InputConnectionClient create(
|
75 | 76 | final GeckoSession session,
|
... | ... | @@ -208,12 +209,13 @@ import org.mozilla.gecko.util.ThreadUtils; |
208 | 209 | // If selection is empty, we'll select everything
|
209 | 210 | if (selStart == selEnd) {
|
210 | 211 | // Fill the clipboard
|
211 | - Clipboard.setText(view.getContext(), editable);
|
|
212 | + Clipboard.setText(view.getContext(), editable, mIsPrivateBrowsing);
|
|
212 | 213 | editable.clear();
|
213 | 214 | } else {
|
214 | 215 | Clipboard.setText(
|
215 | 216 | view.getContext(),
|
216 | - editable.subSequence(Math.min(selStart, selEnd), Math.max(selStart, selEnd)));
|
|
217 | + editable.subSequence(Math.min(selStart, selEnd), Math.max(selStart, selEnd)),
|
|
218 | + mIsPrivateBrowsing);
|
|
217 | 219 | editable.delete(selStart, selEnd);
|
218 | 220 | }
|
219 | 221 | break;
|
... | ... | @@ -231,7 +233,7 @@ import org.mozilla.gecko.util.ThreadUtils; |
231 | 233 | : editable
|
232 | 234 | .toString()
|
233 | 235 | .substring(Math.min(selStart, selEnd), Math.max(selStart, selEnd));
|
234 | - Clipboard.setText(view.getContext(), copiedText);
|
|
236 | + Clipboard.setText(view.getContext(), copiedText, mIsPrivateBrowsing);
|
|
235 | 237 | break;
|
236 | 238 | }
|
237 | 239 | return true;
|
... | ... | @@ -603,6 +605,9 @@ import org.mozilla.gecko.util.ThreadUtils; |
603 | 605 | outAttrs.imeOptions |= EditorInfo.IME_FLAG_NO_EXTRACT_UI | EditorInfo.IME_FLAG_NO_FULLSCREEN;
|
604 | 606 | }
|
605 | 607 | |
608 | + mIsPrivateBrowsing =
|
|
609 | + ((outAttrs.imeOptions & InputMethods.IME_FLAG_NO_PERSONALIZED_LEARNING) != 0);
|
|
610 | + |
|
606 | 611 | if (DEBUG) {
|
607 | 612 | Log.d(
|
608 | 613 | LOGTAG,
|
... | ... | @@ -70,6 +70,16 @@ |
70 | 70 | inert
|
71 | 71 | ></button>
|
72 | 72 | </div>
|
73 | + |
|
74 | + <p id="explanation-iframe" hidden>
|
|
75 | + <span data-l10n-id="about-httpsonly-explanation-iframe"></span>
|
|
76 | + <a
|
|
77 | + id="mixedContentLearnMoreLink"
|
|
78 | + target="_blank"
|
|
79 | + data-l10n-id="about-httpsonly-link-learn-more"
|
|
80 | + ></a>
|
|
81 | + </p>
|
|
82 | + |
|
73 | 83 | <div class="suggestion-box" hidden>
|
74 | 84 | <h2 data-l10n-id="about-httpsonly-suggestion-box-header"></h2>
|
75 | 85 | </div>
|
... | ... | @@ -29,28 +29,35 @@ function initPage() { |
29 | 29 | document
|
30 | 30 | .getElementById("learnMoreLink")
|
31 | 31 | .setAttribute("href", baseSupportURL + "https-only-prefs");
|
32 | + document
|
|
33 | + .getElementById("mixedContentLearnMoreLink")
|
|
34 | + .setAttribute("href", baseSupportURL + "mixed-content");
|
|
35 | + |
|
36 | + const isTopLevel = window.top == window;
|
|
37 | + if (!isTopLevel) {
|
|
38 | + for (const id of ["explanation-continue", "goBack", "openInsecure"]) {
|
|
39 | + document.getElementById(id).remove();
|
|
40 | + }
|
|
41 | + document.getElementById("explanation-iframe").removeAttribute("hidden");
|
|
42 | + return;
|
|
43 | + }
|
|
32 | 44 | |
33 | 45 | document
|
34 | 46 | .getElementById("openInsecure")
|
35 | 47 | .addEventListener("click", onOpenInsecureButtonClick);
|
48 | + document
|
|
49 | + .getElementById("goBack")
|
|
50 | + .addEventListener("click", onReturnButtonClick);
|
|
36 | 51 | |
37 | 52 | const delay = RPMGetIntPref("security.dialog_enable_delay", 1000);
|
38 | 53 | setTimeout(() => {
|
39 | 54 | document.getElementById("openInsecure").removeAttribute("inert");
|
40 | 55 | }, delay);
|
41 | 56 | |
42 | - if (window.top == window) {
|
|
43 | - document
|
|
44 | - .getElementById("goBack")
|
|
45 | - .addEventListener("click", onReturnButtonClick);
|
|
46 | - addAutofocus("#goBack", "beforeend");
|
|
47 | - } else {
|
|
48 | - document.getElementById("goBack").remove();
|
|
49 | - }
|
|
57 | + addAutofocus("#goBack", "beforeend");
|
|
50 | 58 | |
51 | - const isTopLevel = window.top == window;
|
|
52 | 59 | const hasWWWPrefix = pageUrl.href.startsWith("https://www.");
|
53 | - if (isTopLevel && !hasWWWPrefix) {
|
|
60 | + if (!hasWWWPrefix) {
|
|
54 | 61 | // HTTPS-Only generally simply replaces http: with https:;
|
55 | 62 | // here we additionally try to add www and see if that allows to upgrade the connection if it is top level
|
56 | 63 |
... | ... | @@ -12,6 +12,7 @@ about-httpsonly-explanation-question = What could be causing this? |
12 | 12 | about-httpsonly-explanation-nosupport = Most likely, the website simply does not support HTTPS.
|
13 | 13 | about-httpsonly-explanation-risk = It’s also possible that an attacker is involved. If you decide to visit the website, you should not enter any sensitive information like passwords, emails, or credit card details.
|
14 | 14 | about-httpsonly-explanation-continue = If you continue, HTTPS-Only Mode will be turned off temporarily for this site.
|
15 | +about-httpsonly-explanation-iframe = Due to mixed content blocking, it is not possible to manually allow this frame to load.
|
|
15 | 16 | |
16 | 17 | about-httpsonly-button-continue-to-site = Continue to HTTP Site
|
17 | 18 | about-httpsonly-button-go-back = Go Back
|
... | ... | @@ -92,14 +92,16 @@ nsClipboard::SetNativeClipboardData(nsITransferable* aTransferable, |
92 | 92 | return rv;
|
93 | 93 | }
|
94 | 94 | |
95 | + bool isPrivate = aTransferable->GetIsPrivateData();
|
|
96 | + |
|
95 | 97 | if (!html.IsEmpty() &&
|
96 | 98 | java::Clipboard::SetHTML(java::GeckoAppShell::GetApplicationContext(),
|
97 | - text, html)) {
|
|
99 | + text, html, isPrivate)) {
|
|
98 | 100 | return NS_OK;
|
99 | 101 | }
|
100 | 102 | if (!text.IsEmpty() &&
|
101 | 103 | java::Clipboard::SetText(java::GeckoAppShell::GetApplicationContext(),
|
102 | - text)) {
|
|
104 | + text, isPrivate)) {
|
|
103 | 105 | return NS_OK;
|
104 | 106 | }
|
105 | 107 |