All files / utils get-lang-from-element.util.js

90.9% Statements 50/55
76.19% Branches 16/21
100% Functions 3/3
90.9% Lines 50/55

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 562x 2x 2x 2x 2x 2x 2x 2x 2x       2x 2x 2x 2x 2x 2x 2x 2x 3x 3x 1x 3x     2x 2x 2x 2x 2x 2x 2x 2x 2x 21x 4x 4x 21x 52x 52x 36x 20x 20x 36x 13x 9x 4x 36x 3x 3x 52x 5x 5x 5x  
import { traverseUpDom } from './traverse-up-dom.js'
 
/**
 * @param {Element} element - target element
 * @returns {string} fallback language
 */
function getFallbackLanguage (element) {
  const root = element.ownerDocument.defaultView ?? globalThis
  if (!root.navigator) {
    // OS/node/browser independent way of obtaining the default locale
    return Intl.DateTimeFormat().resolvedOptions().locale
  }
  const langs = root.navigator.languages || [root.navigator.language]
  return langs[0]
}
 
/**
 * @param {Element} element - element with invalid lang attribute
 * @returns {string} corrected language
 */
function handleInvalidLanguage (element) {
  if (element === element.ownerDocument.documentElement) {
    return getFallbackLanguage(element)
  } else if (element.parentNode instanceof ShadowRoot) {
    return getLanguageFromElement(element.parentNode.host)
  }
  return getLanguageFromElement(element.parentElement)
}
 
/**
 * Gets the currently applied language of element, get default locale otherwise
 * @param {Element | null} element - target element
 * @returns {string} element language
 */
export function getLanguageFromElement (element) {
  if (element == null) {
    return Intl.DateTimeFormat().resolvedOptions().locale
  }
  for (const node of traverseUpDom(element)) {
    const langValue = node.getAttribute('lang')
    if (!langValue) { continue }
    try {
      const locale = new Intl.Locale(langValue)
      const { language, region } = locale
      if (region == null) {
        return language
      }
      return `${language}-${region}`
    } catch {
      return handleInvalidLanguage(node)
    }
  }
 
  return getFallbackLanguage(element)
}