Commit 7dcd217d authored by henry's avatar henry Committed by Pier Angelo Vendrame
Browse files

fixup! TB 11698: Incorporate Tor Browser Manual pages into Tor Browser

TB 44959: Integrate the new manual.
parent 452e9f2f
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -128,6 +128,23 @@ let JSWINDOWACTORS = {
    remoteTypes: ["privilegedabout"],
  },

  AboutManual: {
    parent: {
      esModuleURI:
        "moz-src:///browser/components/aboutmanual/AboutManualParent.sys.mjs",
    },
    child: {
      esModuleURI:
        "moz-src:///browser/components/aboutmanual/AboutManualChild.sys.mjs",

      events: {
        ManualLocaleSelected: { wantUntrusted: true },
      },
    },

    matches: ["about:manual"],
  },

  AboutMessagePreview: {
    parent: {
      esModuleURI: "resource:///actors/AboutMessagePreviewParent.sys.mjs",
+36 −43
Original line number Diff line number Diff line
@@ -212,52 +212,45 @@ static nsAutoCString GetAboutModuleName(nsIURI* aURI) {
  return path;
}

static nsTHashSet<nsCStringHashKey> GetManualLocales() {
  nsTHashSet<nsCStringHashKey> locales;
  RefPtr<nsZipArchive> zip = Omnijar::GetReader(Omnijar::APP);
  if (!zip) {
    // Probably a local build started with ./mach run
    return locales;
static nsAutoCString GetManualChromeURI() {
  nsTArray<nsCString> availableLocales;
  nsCString availableLocalesStr;
  if (NS_SUCCEEDED(mozilla::Preferences::GetCString(
          "torbrowser.manual.available-locales", availableLocalesStr)) &&
      availableLocalesStr.Length() > 0) {
    for (const nsACString& locale : availableLocalesStr.Split(',')) {
      availableLocales.AppendElement(locale);
    }
  UniquePtr<nsZipFind> find;
  const nsAutoCString prefix("chrome/browser/content/browser/manual/");
  nsAutoCString needle = prefix;
  needle.Append("*.html");
  if (NS_SUCCEEDED(zip->FindInit(needle.get(), getter_Transfers(find)))) {
    const char* entryName;
    uint16_t entryNameLen;
    while (NS_SUCCEEDED(find->FindNext(&entryName, &entryNameLen))) {
      // 5 is to remove the final `.html`
      const size_t length = entryNameLen - prefix.Length() - 5;
      locales.Insert(nsAutoCString(entryName + prefix.Length(), length));
  }
  nsCString tryLocale;
  if (!NS_SUCCEEDED(mozilla::Preferences::GetCString("torbrowser.manual.locale",
                                                     tryLocale)) ||
      !availableLocales.Contains(tryLocale)) {
    nsTArray<nsCString> appLocales;
    intl::LocaleService::GetInstance()->GetAppLocalesAsBCP47(appLocales);
    bool found = false;
    for (size_t i = 0; i < appLocales.Length(); i++) {
      tryLocale = appLocales[i];
      if (availableLocales.Contains(tryLocale)) {
        found = true;
        break;
      } else if (tryLocale.Length() > 3 && tryLocale[2] == '-') {
        // Strip the region code and see if the lang matches.
        tryLocale.SetLength(2);
        if (availableLocales.Contains(tryLocale)) {
          found = true;
          break;
        }
  return locales;
      }

static nsAutoCString GetManualChromeURI() {
  static nsTHashSet<nsCStringHashKey> locales = GetManualLocales();

  nsAutoCString reqLocale;
  intl::LocaleService::GetInstance()->GetAppLocaleAsBCP47(reqLocale);
  // Check every time the URL is needed in case the locale has changed.
  // It might help also if we start allowing to change language, e.g., with a
  // get parameter (see tor-browser#42675).
  if (!locales.Contains(reqLocale) && reqLocale.Length() > 2 &&
      reqLocale[2] == '-') {
    // At the moment, codes in our manual output are either 2 letters (en) or
    // 5 letters (pt-BR)
    reqLocale.SetLength(2);
    }
  if (!locales.Contains(reqLocale)) {
    reqLocale = "en";
    if (!found) {
      tryLocale.AssignLiteral("en");
    }

  // %s is the language
  constexpr char model[] = "chrome://browser/content/manual/%s.html";
  nsAutoCString url;
  url.AppendPrintf(model, reqLocale.get());
  return url;
  }
  nsAutoCString uri;
  uri.AppendPrintf("chrome://browser/content/aboutmanual/aboutManual-%s.html",
                   tryLocale.get());
  return uri;
}

NS_IMETHODIMP
+15 −0
Original line number Diff line number Diff line
/**
 * Actor child class for the about:manual page.
 */
export class AboutManualChild extends JSWindowActorChild {
  handleEvent(event) {
    switch (event.type) {
      case "ManualLocaleSelected": {
        const locale = event.detail;
        if (typeof locale === "string") {
          this.sendAsyncMessage("AboutManual:LocaleSelected", locale);
        }
      }
    }
  }
}
+21 −0
Original line number Diff line number Diff line
/**
 * Actor parent class for the about:manual page.
 */
export class AboutManualParent extends JSWindowActorParent {
  receiveMessage(message) {
    switch (message.name) {
      case "AboutManual:LocaleSelected": {
        const locale = message.data;
        if (
          Services.prefs
            .getStringPref("torbrowser.manual.available-locales", "")
            .split(",")
            .includes(locale)
        ) {
          Services.prefs.setStringPref("torbrowser.manual.locale", locale);
          this.browsingContext.reload(Ci.nsIWebNavigation.LOAD_FLAGS_NONE);
        }
      }
    }
  }
}
+67 −0
Original line number Diff line number Diff line
"use strict";

function changePage(initialLoad) {
  let page;
  const hash = location.hash;
  const id = hash.startsWith("#") ? hash.substr(1) : null;
  let targetEl = null;
  if (id) {
    targetEl = document.getElementById(id);
    page = targetEl?.closest(".olm-page");
  }
  if (!page) {
    if (!initialLoad) {
      // Make no change.
      return;
    }
    page = document.getElementById("index");
  }
  const currPage = document.querySelector(".olm-page:not(.d-none)");
  if (currPage === page) {
    // No change in page.
    return;
  }

  currPage?.classList.add("d-none");
  page.classList.remove("d-none");

  // If we are targeting an element that is not a page element, we want to
  // scroll it into view (the focus position should have already shifted to
  // point to it).
  // Otherwise, if we have no target or the target is a page, we want to scroll
  // to the top of the document so that the header is visible.
  const doScroll = () => {
    const scrollEl = targetEl && targetEl !== page ? targetEl : document.body;
    scrollEl.scrollIntoView({
      behavior: "instant",
      block: "start",
      inline: "start",
    });
  };
  if (initialLoad) {
    window.addEventListener("load", doScroll, { once: true });
  } else {
    doScroll();
  }
}

window.addEventListener("DOMContentLoaded", () => {
  const langDropdown = document.getElementById("language-menu-dropdown");
  for (const langButton of langDropdown.querySelectorAll("button")) {
    langButton.addEventListener("click", () => {
      dispatchEvent(
        new CustomEvent("ManualLocaleSelected", {
          // The button's lang attribute is expected to match the locale's code.
          detail: langButton.getAttribute("lang"),
          bubbles: true,
        })
      );
    });
  }

  changePage(true);
});

window.addEventListener("hashchange", () => {
  changePage(false);
});
Loading