ma1 pushed to branch mullvad-browser-128.5.0esr-14.0-1 at The Tor Project / Applications / Mullvad Browser

Commits:

16 changed files:

Changes:

  • dom/ipc/WindowGlobalParent.cpp
    ... ... @@ -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();
    

  • dom/security/test/https-only/browser.toml
    ... ... @@ -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
    

  • dom/security/test/https-only/browser_iframe_buttons.js
    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
    +});

  • dom/security/test/https-only/file_iframe_buttons.html
    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>

  • mobile/android/android-components/components/feature/app-links/src/main/java/mozilla/components/feature/app/links/SimpleRedirectDialogFragment.kt
    ... ... @@ -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 {
    

  • mobile/android/android-components/components/feature/app-links/src/test/java/mozilla/components/feature/app/links/SimpleRedirectDialogFragmentTest.kt
    ... ... @@ -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()
    

  • mobile/android/android-components/components/feature/session/src/main/java/mozilla/components/feature/session/SessionUseCases.kt
    ... ... @@ -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,
    

  • mobile/android/android-components/components/feature/session/src/test/java/mozilla/components/feature/session/SessionUseCasesTest.kt
    ... ... @@ -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",
    

  • mobile/android/android-components/docs/changelog.md
    ... ... @@ -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
     
    

  • mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CrashReportingTest.kt
    ... ... @@ -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()
    

  • mobile/android/geckoview/src/main/java/org/mozilla/gecko/Clipboard.java
    ... ... @@ -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
    

  • mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoInputConnection.java
    ... ... @@ -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,
    

  • toolkit/components/httpsonlyerror/content/errorpage.html
    ... ... @@ -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>
    

  • toolkit/components/httpsonlyerror/content/errorpage.js
    ... ... @@ -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
     
    

  • toolkit/locales/en-US/toolkit/about/aboutHttpsOnlyError.ftl
    ... ... @@ -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
    

  • widget/android/nsClipboard.cpp
    ... ... @@ -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