Source: products/argos-saleslogix/src/Bootstrap.localization.js

/**
 * @module crm.Bootstrap.localization
 */

export function makeRequest(url) {
  return new Promise((resolve, reject) => {
    const http = new XMLHttpRequest();

    http.open('GET', url);
    http.addEventListener('load', (response) => {
      resolve(response.target.response);
    });
    http.addEventListener('error', err => reject(err));
    http.addEventListener('abort', err => reject(err));
    http.send();
  });
}

export function l20nLoadFunc(localeFiles) {
  return new Promise((resolve) => {
    const https = localeFiles.map(file => makeRequest(file));
    Promise.all(https).then((files) => {
      resolve(files);
    });
  });
}

export function l20nNoFetchFunc(localeFiles) {
  return new Promise((resolve) => {
    resolve(localeFiles);
  });
}

export function l20nLinkFunc(files, context, defaultContext) {
  files.forEach((file) => {
    [context, defaultContext].forEach((ctx) => {
      ctx.linkResource((locale) => {
        return [file.base, locale, file.file].join('/');
      });
    });
  });
}

export function l20nAddResourceFunc(files, context, defaultContext) {
  files.forEach((file) => {
    [context, defaultContext].forEach((ctx) => {
      ctx.addResource(file);
    });
  });
}

/**
 * Bootstrap localization
 * This function handles the bootstrapping of localization for
 * the application.
 * fetchFunc - Takes an array of processed locale files, returns a promise
 * processFunc - Takes the results from fetchFunc along with the current context and defaultContext
 */
export function bootstrapLocalization({
  supportedLocales,
  defaultLocale,
  currentLocale,
  localeFiles,
  fetchFunc = l20nNoFetchFunc,
  processFunc = l20nLinkFunc,
  asGlobal = false,
}) {
  const promise = new Promise((resolve) => {
    // The L20n context (ctx) should only call linkResource once per file.
    // We need to:
    //    * Strip out the locale from the path string (map)
    //    * Remove duplicates (reduce)
    //    * link each resource against a locale (forEach)
    const processedLocaleFiles = localeFiles.map((path) => {
      let trimmed = path;
      supportedLocales.forEach((locale) => {
        trimmed = trimmed.replace(new RegExp(`/${locale}/`), '/');
      });

      const index = trimmed.lastIndexOf('/');
      const basePath = trimmed.substring(0, index);
      const file = trimmed.substring(index + 1, trimmed.length);
      return {
        base: basePath,
        file,
      };
    })
    .reduce((p, c) => {
      if (p.some(pathInfo => pathInfo.base === c.base && pathInfo.file === c.file)) {
        return p;
      }

      return p.concat(c);
    }, []);

    fetchFunc(processedLocaleFiles).then((files) => {
      const ctx = window.L20n.getContext();
      const defaultCtx = window.L20n.getContext();

      processFunc(files, ctx, defaultCtx);

      ctx.registerLocales(defaultLocale, supportedLocales);
      ctx.requestLocales(currentLocale);
      defaultCtx.registerLocales(defaultLocale);
      defaultCtx.requestLocales(defaultLocale);

      window.localeContext = ctx;
      window.defaultLocaleContext = defaultCtx;

      Promise.all([new Promise((res) => {
        ctx.ready(() => res(true));
      }), new Promise((res) => {
        defaultCtx.ready(() => res(true));
      })]).then(() => {
        resolve();
      });
    });
  });
  if (asGlobal) {
    window[asGlobal] = promise;
  }
  return promise;
}