tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

withPseudoLocalization.mjs (2974B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 import { useEffect, useGlobals, useChannel } from "@storybook/preview-api";
      6 import {
      7  DIRECTIONS,
      8  DIRECTION_BY_STRATEGY,
      9  UPDATE_STRATEGY_EVENT,
     10  FLUENT_CHANGED,
     11 } from "./constants.mjs";
     12 import { provideFluent } from "../fluent-utils.mjs";
     13 
     14 /**
     15 * withPseudoLocalization is a Storybook decorator that handles emitting an
     16 * event to update translations when a new pseudo localization strategy is
     17 * applied. It also handles setting a "dir" attribute on the root element in the
     18 * Storybook iframe.
     19 *
     20 * @param {Function} StoryFn - Provided by Storybook, used to render the story.
     21 * @param {object} context - Provided by Storybook, data about the story.
     22 * @returns {Function} StoryFn with a modified "dir" attr set.
     23 */
     24 export const withPseudoLocalization = (StoryFn, context) => {
     25  const [{ pseudoStrategy }] = useGlobals();
     26  const direction = DIRECTION_BY_STRATEGY[pseudoStrategy] || DIRECTIONS.ltr;
     27  const isInDocs = context.viewMode === "docs";
     28  const emit = useChannel({});
     29 
     30  useEffect(() => {
     31    if (pseudoStrategy) {
     32      emit(UPDATE_STRATEGY_EVENT, pseudoStrategy);
     33    }
     34  }, [pseudoStrategy]);
     35 
     36  useEffect(() => {
     37    if (isInDocs) {
     38      document.documentElement.setAttribute("dir", DIRECTIONS.ltr);
     39      let storyElements = document.querySelectorAll(".docs-story");
     40      storyElements.forEach(element => element.setAttribute("dir", direction));
     41    } else {
     42      document.documentElement.setAttribute("dir", direction);
     43    }
     44  }, [direction, isInDocs]);
     45 
     46  return StoryFn();
     47 };
     48 
     49 /**
     50 * withFluentStrings is a Storybook decorator that handles emitting an
     51 * event to update the Fluent strings shown in the Fluent panel.
     52 *
     53 * @param {Function} StoryFn - Provided by Storybook, used to render the story.
     54 * @param {object} context - Provided by Storybook, data about the story.
     55 * @returns {Function} StoryFn unmodified.
     56 */
     57 export const withFluentStrings = (StoryFn, context) => {
     58  const [{ fluentStrings }, updateGlobals] = useGlobals();
     59  const emit = useChannel({});
     60  const fileName = context.component + ".ftl";
     61  let strings = [];
     62 
     63  if (context.parameters?.fluent && fileName) {
     64    if (fluentStrings.hasOwnProperty(fileName)) {
     65      strings = fluentStrings[fileName];
     66    } else {
     67      let resource = provideFluent(context.parameters.fluent, fileName);
     68      for (let message of resource.body) {
     69        strings.push([
     70          message.id,
     71          [
     72            message.value,
     73            ...Object.entries(message.attributes).map(
     74              ([key, value]) => `  .${key} = ${value}`
     75            ),
     76          ].join("\n"),
     77        ]);
     78      }
     79      updateGlobals({
     80        fluentStrings: { ...fluentStrings, [fileName]: strings },
     81      });
     82    }
     83  }
     84 
     85  emit(FLUENT_CHANGED, strings, fileName);
     86 
     87  return StoryFn();
     88 };