Skip to content

Commit

Permalink
[New] support custom replace implementation
Browse files Browse the repository at this point in the history
in order to support interpolating types other then strings

fix airbnb#170
  • Loading branch information
Xiphe committed Jun 11, 2022
1 parent 96004b2 commit 6723cc6
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 7 deletions.
35 changes: 28 additions & 7 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ var warn = function warn(message) {
warning(false, message);
};

var replace = String.prototype.replace;
var defaultReplace = String.prototype.replace;
var split = String.prototype.split;

// #### Pluralization methods
Expand Down Expand Up @@ -198,7 +198,14 @@ var defaultTokenRegex = /%\{(.*?)\}/g;
//
// You should pass in a third argument, the locale, to specify the correct plural type.
// It defaults to `'en'` with 2 plural forms.
function transformPhrase(phrase, substitutions, locale, tokenRegex, pluralRules) {
function transformPhrase(
phrase,
substitutions,
locale,
tokenRegex,
pluralRules,
replaceImplementation
) {
if (typeof phrase !== 'string') {
throw new TypeError('Polyglot.transformPhrase expects argument #1 to be string');
}
Expand All @@ -209,6 +216,7 @@ function transformPhrase(phrase, substitutions, locale, tokenRegex, pluralRules)

var result = phrase;
var interpolationRegex = tokenRegex || defaultTokenRegex;
var replace = replaceImplementation || defaultReplace;

// allow number as a pluralization shortcut
var options = typeof substitutions === 'number' ? { smart_count: substitutions } : substitutions;
Expand Down Expand Up @@ -248,6 +256,7 @@ function Polyglot(options) {
var allowMissing = opts.allowMissing ? transformPhrase : null;
this.onMissingKey = typeof opts.onMissingKey === 'function' ? opts.onMissingKey : allowMissing;
this.warn = opts.warn || warn;
this.replaceImplementation = opts.replace || defaultReplace;
this.tokenRegex = constructTokenRegex(opts.interpolation);
this.pluralRules = opts.pluralRules || defaultPluralRules;
}
Expand Down Expand Up @@ -403,13 +412,27 @@ Polyglot.prototype.t = function (key, options) {
phrase = opts._;
} else if (this.onMissingKey) {
var onMissingKey = this.onMissingKey;
result = onMissingKey(key, opts, this.currentLocale, this.tokenRegex, this.pluralRules);
result = onMissingKey(
key,
opts,
this.currentLocale,
this.tokenRegex,
this.pluralRules,
this.replaceImplementation
);
} else {
this.warn('Missing translation for key: "' + key + '"');
result = key;
}
if (typeof phrase === 'string') {
result = transformPhrase(phrase, opts, this.currentLocale, this.tokenRegex, this.pluralRules);
result = transformPhrase(
phrase,
opts,
this.currentLocale,
this.tokenRegex,
this.pluralRules,
this.replaceImplementation
);
}
return result;
};
Expand All @@ -422,8 +445,6 @@ Polyglot.prototype.has = function (key) {
};

// export transformPhrase
Polyglot.transformPhrase = function transform(phrase, substitutions, locale) {
return transformPhrase(phrase, substitutions, locale);
};
Polyglot.transformPhrase = transformPhrase;

module.exports = Polyglot;
52 changes: 52 additions & 0 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,58 @@ describe('t', function () {
expect(instance.t('header.sign_in')).to.equal('Sign In');
});

it('supports custom replace implementation', function () {
var instance = new Polyglot({
phrases: phrases,
replace: function (interpolationRegex, callback) {
var phrase = this;
var i = 0;
var matches = Array.from(phrase.matchAll(interpolationRegex));
var children = [];

forEach(matches, function (match) {
if (match.index > i) {
children.push(phrase.substring(i, match.index));
}
children.push(callback(match[0], match[1]));
i = match.index + match[0].length;
});
if (i < phrase.length) {
children.push(phrase.substring(i));
}

return { type: 'might_be_react_fragment', children: children };
}
});

expect(instance.t(
'hi_name_welcome_to_place',
{
name: { type: 'might_be_react_node', children: ['Rudolf'] },
place: { type: 'might_be_react_node', children: ['Earth'] }
}
)).to.deep.equal({
children: [
'Hi, ',
{
children: [
'Rudolf'
],
type: 'might_be_react_node'
},
', welcome to ',
{
children: [
'Earth'
],
type: 'might_be_react_node'
},
'!'
],
type: 'might_be_react_fragment'
});
});

describe('onMissingKey', function () {
it('calls the function when a key is missing', function () {
var expectedKey = 'some key';
Expand Down

0 comments on commit 6723cc6

Please sign in to comment.