emdemir / Flask-Babel-JS

Flask extension to use Babel catalogs in Javascript
BSD 3-Clause "New" or "Revised" License
12 stars 8 forks source link

Issue with ngettext when trying to look up plural translations #6

Open macnewbold opened 2 years ago

macnewbold commented 2 years ago

I'm getting javascript exceptions from this section of code, when my translations define what plural means:

babel.ngettext = function(text, text_plural, n, variables) {
        var p;
        if (babel.plural) {
            p = babel.plural(n);
        } else {
            p = p === 1 ? 0 : 1;
        }

        if ((text in babel.catalog) && babel.catalog.hasOwnProperty(text)) {
            return babel.format(babel.catalog[text][p], variables);
        } else {
            return babel.format([text, text_plural][p], variables);
        }
    };

When the translation defines Plural-Forms: in the PO file, that leads to the creation and existence of babel.plural, which evaluates n to determine if it is plural, and returns a boolean true or false. The else branch though sets p to an integer, 1 or 0. Then down below when it looks up the catalog property, it tries to take that catalog value for the text (which is a string) and use the boolean p value as a subscript, which throws an error. The other case, where it isn't in the catalog, works fine using p as a subscript, as long as babel.plural wasn't defined, but fails if babel.plural exists.

If I were proposing a fix, it would be to convert the babel.plural result to an integer, and remove the [p] subscript on the branch where the catalog has the value.

macnewbold commented 2 years ago

This seems to be a replacement that is functioning well for me:

    babel.ngettext = function(text, text_plural, n, variables) {
        var p;
        var str;
        if (babel.plural) {
            p = babel.plural(n);
        } else {
            p = (n !== 1);
        }
        p = (p ? 1 : 0);
        str = [text, text_plural][p];

        if ((str in babel.catalog) && babel.catalog.hasOwnProperty(str)) {
            return babel.format(babel.catalog[str], variables);
        } else {
            return babel.format(str, variables);
        }
    };