| ... | ... | @@ -10,37 +10,28 @@ XPCOMUtils.defineLazyGetter(this, "NewIdentityStrings", () => { | 
| 10 | 10 |    );
 | 
| 11 | 11 |    const brandShortName = brandBundle.GetStringFromName("brandShortName");
 | 
| 12 | 12 |  
 | 
| 13 |  | -  let strings = {
 | 
| 14 |  | -    new_identity: "New Identity",
 | 
| 15 |  | -    new_identity_sentence_case: "New identity",
 | 
| 16 |  | -    new_identity_prompt_title: "Reset your identity?",
 | 
| 17 |  | -    new_identity_prompt: `${brandShortName} will close all windows and tabs. All website sessions will be lost. \nRestart ${brandShortName} now to reset your identity?`,
 | 
| 18 |  | -    new_identity_restart: `Restart ${brandShortName}`,
 | 
| 19 |  | -    new_identity_ask_again: "Never ask me again",
 | 
| 20 |  | -    new_identity_menu_accesskey: "I",
 | 
| 21 |  | -  };
 | 
| 22 |  | -  let bundle = null;
 | 
|  | 13 | +  const fallbackBundle = Services.strings.createBundle(
 | 
|  | 14 | +    "resource:///chrome/en-US/locale/browser/newIdentity.properties"
 | 
|  | 15 | +  );
 | 
|  | 16 | +  const strings = {};
 | 
|  | 17 | +  const brandedStrings = ["new_identity_prompt", "new_identity_restart"];
 | 
|  | 18 | +  for (let { key } of fallbackBundle.getSimpleEnumeration()) {
 | 
|  | 19 | +    strings[key] = fallbackBundle.GetStringFromName(key);
 | 
|  | 20 | +  }
 | 
| 23 | 21 |    try {
 | 
| 24 |  | -    bundle = Services.strings.createBundle(
 | 
|  | 22 | +    const bundle = Services.strings.createBundle(
 | 
| 25 | 23 |        "chrome://browser/locale/newIdentity.properties"
 | 
| 26 | 24 |      );
 | 
| 27 |  | -  } catch (e) {
 | 
| 28 |  | -    console.warn("Could not load the New Identity strings");
 | 
| 29 |  | -  }
 | 
| 30 |  | -  if (bundle) {
 | 
| 31 | 25 |      for (const key of Object.keys(strings)) {
 | 
| 32 | 26 |        try {
 | 
| 33 | 27 |          strings[key] = bundle.GetStringFromName(key);
 | 
| 34 | 28 |        } catch (e) {}
 | 
| 35 | 29 |      }
 | 
| 36 |  | -    strings.new_identity_prompt = strings.new_identity_prompt.replaceAll(
 | 
| 37 |  | -      "%S",
 | 
| 38 |  | -      brandShortName
 | 
| 39 |  | -    );
 | 
| 40 |  | -    strings.new_identity_restart = strings.new_identity_restart.replaceAll(
 | 
| 41 |  | -      "%S",
 | 
| 42 |  | -      brandShortName
 | 
| 43 |  | -    );
 | 
|  | 30 | +  } catch (e) {
 | 
|  | 31 | +    console.warn("Could not load localized New Identity strings");
 | 
|  | 32 | +  }
 | 
|  | 33 | +  for (let key of brandedStrings) {
 | 
|  | 34 | +    strings[key] = strings[key].replaceAll("%S", brandShortName);
 | 
| 44 | 35 |    }
 | 
| 45 | 36 |    return strings;
 | 
| 46 | 37 |  });
 | 
| ... | ... | @@ -437,10 +428,76 @@ XPCOMUtils.defineLazyGetter(this, "NewIdentityButton", () => { | 
| 437 | 428 |        logger.info("Opening a new window");
 | 
| 438 | 429 |        return new Promise(resolve => {
 | 
| 439 | 430 |          // Open a new window forcing the about:privatebrowsing page (tor-browser#41765)
 | 
| 440 |  | -        const win = OpenBrowserWindow({private: "no-home"});
 | 
|  | 431 | +        // unless user explicitly overrides this policy (tor-browser #42236)
 | 
|  | 432 | +        const homePref = "browser.startup.homepage";
 | 
|  | 433 | +        const trustedHomePref = "browser.startup.homepage.new_identity";
 | 
|  | 434 | +        const homeURL = Services.prefs.getStringPref(homePref, "");
 | 
|  | 435 | +        const isTrustedHome =
 | 
|  | 436 | +          homeURL === "about:tor" ||
 | 
|  | 437 | +          homeURL.startsWith("chrome://") || // about:blank and other built-ins
 | 
|  | 438 | +          homeURL === Services.prefs.getStringPref(trustedHomePref, "");
 | 
|  | 439 | +        const isCustomHome =
 | 
|  | 440 | +          Services.prefs.getIntPref("browser.startup.page") === 1;
 | 
|  | 441 | +        const win = OpenBrowserWindow({
 | 
|  | 442 | +          private: isCustomHome && isTrustedHome ? "private" : "no-home",
 | 
|  | 443 | +        });
 | 
| 441 | 444 |          // This mechanism to know when the new window is ready is used by
 | 
| 442 | 445 |          // OpenBrowserWindow itself (see its definition in browser.js).
 | 
| 443 |  | -        win.addEventListener("MozAfterPaint", () => resolve(), { once: true });
 | 
|  | 446 | +        win.addEventListener(
 | 
|  | 447 | +          "MozAfterPaint",
 | 
|  | 448 | +          () => {
 | 
|  | 449 | +            resolve();
 | 
|  | 450 | +            if (isTrustedHome || !isCustomHome) {
 | 
|  | 451 | +              return;
 | 
|  | 452 | +            }
 | 
|  | 453 | +            const tbl = win.TabsProgressListener;
 | 
|  | 454 | +            const { onLocationChange } = tbl;
 | 
|  | 455 | +            tbl.onLocationChange = (...args) => {
 | 
|  | 456 | +              tbl.onLocationChange = onLocationChange;
 | 
|  | 457 | +              tbl.onLocationChange(...args);
 | 
|  | 458 | +              let displayAddress;
 | 
|  | 459 | +              try {
 | 
|  | 460 | +                const url = new URL(homeURL);
 | 
|  | 461 | +                displayAddress = url.hostname;
 | 
|  | 462 | +                if (!displayAddress) {
 | 
|  | 463 | +                  // no host, use full address and truncate if too long
 | 
|  | 464 | +                  const MAX_LEN = 32;
 | 
|  | 465 | +                  displayAddress = url.href;
 | 
|  | 466 | +                  if (displayAddress.length > MAX_LEN) {
 | 
|  | 467 | +                    displayAddress = `${displayAddress.substring(0, MAX_LEN)}…`;
 | 
|  | 468 | +                  }
 | 
|  | 469 | +                }
 | 
|  | 470 | +              } catch (e) {
 | 
|  | 471 | +                // malformed URL, bail out
 | 
|  | 472 | +                return;
 | 
|  | 473 | +              }
 | 
|  | 474 | +              const label =
 | 
|  | 475 | +                NewIdentityStrings.new_identity_home_notification.replace(
 | 
|  | 476 | +                  "%S",
 | 
|  | 477 | +                  displayAddress
 | 
|  | 478 | +                );
 | 
|  | 479 | +              const callback = () => {
 | 
|  | 480 | +                Services.prefs.setStringPref(trustedHomePref, homeURL);
 | 
|  | 481 | +                win.BrowserHome();
 | 
|  | 482 | +              };
 | 
|  | 483 | +              const notificationBox = win.gBrowser.getNotificationBox();
 | 
|  | 484 | +              notificationBox.appendNotification(
 | 
|  | 485 | +                "new-identity-safe-home",
 | 
|  | 486 | +                {
 | 
|  | 487 | +                  label,
 | 
|  | 488 | +                  priority: notificationBox.PRIORITY_INFO_MEDIUM,
 | 
|  | 489 | +                },
 | 
|  | 490 | +                [
 | 
|  | 491 | +                  {
 | 
|  | 492 | +                    label: NewIdentityStrings.new_identity_home_load_button,
 | 
|  | 493 | +                    callback,
 | 
|  | 494 | +                  },
 | 
|  | 495 | +                ]
 | 
|  | 496 | +              );
 | 
|  | 497 | +            };
 | 
|  | 498 | +          },
 | 
|  | 499 | +          { once: true }
 | 
|  | 500 | +        );
 | 
| 444 | 501 |        });
 | 
| 445 | 502 |      }
 | 
| 446 | 503 |  
 |