0

Is there an easy way make popup/content/options pages multilingual?

The documentation gave me an impression that the only way is to use JS to add localized strings into html. This would make things very cumbersome and complicated (each node would need an ID or class, etc)
I've tried use ${tag} in HTML but it just displayed the tags themselves (It seems only css supports tags).
So for now I've wrote this little snippet that checks each element of the page and replace all ${tag} with string from chrome.i18n.getMessage(tag):

!function()
{
  let i18nRegExp = /\$\{([^}]+)\}/g,
      cache = {},
      i18n = function(a,b)
      {
        return cache[b] || (cache[b] = chrome.i18n.getMessage(b) || a);
      };

  !function loop(node)
  {
    if (node.attributes)
      for(let i = 0; i < node.attributes.length; i++)
        node.attributes[i].value = node.attributes[i].value.replace(i18nRegExp, i18n);

    if (!node.childNodes.length)
      node.textContent = node.textContent.replace(i18nRegExp, i18n);
    else
      for(let i = 0; i < node.childNodes.length; i++)
        loop(node.childNodes[i]);
  }(document.body.parentNode);
}();

Is there a better way do this?

vanowm
  • 9,466
  • 2
  • 21
  • 37
  • It's essentially the only way but you can utilize other DOM stuff like attributes. There should be libraries specifically for extensions like that. – wOxxOm Nov 30 '20 at 14:03

2 Answers2

2

The developer of the treestyletab extension has created a simple library for localizing HTML called webextensions-lib-l10n.

evilpie
  • 2,718
  • 20
  • 21
  • Thank you. the xpath seems to be 3 times faster on html with 3k lines vs my loop method. And cache makes absolutely no difference in performance on 10k lines html – vanowm Dec 01 '20 at 00:23
0

I have created a simple HTML-Internationalization (only 4 lines) that I have been using in all my add-ons (an some others) for years.

It uses DOM method which is faster & uses less resources than plain RegEx (which involves DOM to text and back to DOM conversion) or xpath (which involves searching for text nodes and then use RegEx replace).

Update based on comment

Please note that HTML localisation is primarily meant for static values. Dynamic values are set by the script.
title is also not a valid attribute for <input> element.
Although that is not an average case, here is an example of what I would do, nonetheless ...

// Example given
// <input title="english" pattern="a-z" placeholder="yay" value="yes"> 

// HTML
<input data-i18n="lang|title" pattern="a-z" placeholder="yay" value="yes"> 

// in script
document.querySelectorAll('input').forEach(item => {
  item.placeholder = chrome.i18n.getMessage(item.placeholder);
  item.value = chrome.i18n.getMessage(item.value);
}):
erosman
  • 7,094
  • 7
  • 27
  • 46