kernel/loadTextes.js

import { textes, getLanguage } from './kernel'

let lastLanguage, wasForEditor

/**
 * Charge un fichier woff2 et l'ajoute au document avant de charger les déclarations normales du font-face roboto
 * Cf README.FONT.md pour les motivations détaillées
 * @return {Promise<void>}
 */
async function loadRobotoFont () {
  const { default: fontFile } = await import('roboto-fontface/fonts/roboto/Roboto-Regular.woff2')
  const fontFace = new FontFace('Roboto', `url(${fontFile})`)
  await fontFace.load()
  document.fonts.add(fontFace)
  // et maintenant que l'on a ce fichier de police vraiment chargé, on peut charger le fontFace complet qui va enrichir tout ça
  await import('roboto-fontface/css/roboto/roboto-fontface.css')
}
async function loadArabicFont () {
  const { default: fontFile } = await import('@fontsource/noto-sans-arabic/files/noto-sans-arabic-arabic-400-normal.woff2')
  const fontFace = new FontFace('Roboto', `url(${fontFile})`)
  await fontFace.load()
  document.fonts.add(fontFace)
  // et maintenant que l'on a ce fichier de police vraiment chargé, on peut charger le fontFace complet qui va enrichir tout ça
  await import('@fontsource/noto-sans-arabic')
}

/**
 * Initialise les textes (exportés par kernel), appelé par le loader
 * La promesse retournée sera résolue quand toutes les polices en cours de chargement
 * (y compris l'arabe éventuellement déclenché par cet appel) seront chargées
 * @param {string} language
 * @param {boolean} isForEditor
 * @returns {Promise<undefined>}
 */
async function loadTextes (language, isForEditor) {
  const lang = language || getLanguage()
  // attention, si on a déjà été appelé pour le player et qu'on est rappelé pour l'éditeur faut charger ce qu'il manque
  if (lang === lastLanguage && (wasForEditor || !isForEditor)) {
    // on nous demande la dernière langue chargée, c'est déjà fait
    return
  }
  const fontPromises = [loadRobotoFont()]
  const txtPromises = []
  // si on a déjà chargé les textes de l'éditeur, faut le refaire quoi qu'il arrive,
  // sinon on pourrait avoir les textes de l'éditeur dans une langue et ceux du player dans une autre
  if (wasForEditor) {
    isForEditor = true
  } else {
    wasForEditor = isForEditor
  }
  if (lang === 'fr') {
    txtPromises.push(import('../textes/textesFr.js'))
    if (isForEditor) txtPromises.push(import('../textes/textesFrAdd.js'))
  } else if (lang === 'de') {
    txtPromises.push(import('../textes/textesDe.js'))
    if (isForEditor) txtPromises.push(import('../textes/textesDeAdd.js'))
  } else if (lang === 'es') {
    txtPromises.push(import('../textes/textesEs.js'))
    if (isForEditor) txtPromises.push(import('../textes/textesEsAdd.js'))
  } else if (lang === 'ar') {
    txtPromises.push(import('../textes/textesAr.js'))
    // pour l'arabe il faut charger cette police car roboto ne contient pas tous les caractères
    // on ne l'ajoute pas à promises que ne doit contenir que des promesses résolues
    // avec des textes
    fontPromises.push(loadArabicFont())
    if (isForEditor) txtPromises.push(import('../textes/textesArAdd.js'))
  } else {
    txtPromises.push(import('../textes/textesEn.js'))
    if (isForEditor) txtPromises.push(import('../textes/textesEnAdd.js'))
  }
  // on ajoute les textes chargés à l'objet textes du kernel
  const esModules = await Promise.all(txtPromises)
  // on ajoute les textes dans l'ordre du tableau, donc le add en dernier
  for (const esModule of esModules) {
    Object.assign(textes, esModule.default)
  }
  // on attend que les polices finissent de se charger
  await Promise.all(fontPromises)
  lastLanguage = lang
  // et si on est dans un navigateur (pas le cas pour MtgCli qui nous utilise),
  // on attend que les fichiers de polices soient effectivement chargés
  // (pas seulement les css qui déclarent les @font-face)
  // https://developer.mozilla.org/en-US/docs/Web/API/Document/fonts
  // https://developer.mozilla.org/en-US/docs/Web/API/FontFaceSet/ready
  if (typeof document !== 'undefined') {
    await document.fonts.ready
    // on ne fait pas de `return document.fonts.ready` car ça retournerait une promesse résolue avec un FontFaceSet
  }
}

export default loadTextes