• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

i18next / i18next / #34487

15 Sep 2016 08:17PM UTC coverage: 65.366% (+0.1%) from 65.243%
#34487

push

jamuhl
Bumped to 3.4.2

553 of 846 relevant lines covered (65.37%)

20.97 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

86.08
/src/Interpolator.js
1
import * as utils from './utils';
1✔
2
import baseLogger from './logger';
1✔
3

4
class Interpolator {
5
  constructor(options = {}) {
22✔
6
    this.logger = baseLogger.create('interpolator');
22✔
7

8
    this.init(options, true);
22✔
9
  }
10

11
  init(options = {}, reset) {
22✔
12
    if (reset) {
22✔
13
      this.options = options;
22✔
14
      this.format = (options.interpolation && options.interpolation.format) || function(value) {return value};
22✔
15
    }
16
    if (!options.interpolation) options.interpolation = { escapeValue: true };
22✔
17

18
    const iOpts = options.interpolation;
22✔
19

20
    this.escapeValue = iOpts.escapeValue;
22✔
21

22
    this.prefix = iOpts.prefix ? utils.regexEscape(iOpts.prefix) : iOpts.prefixEscaped || '{{';
22✔
23
    this.suffix = iOpts.suffix ? utils.regexEscape(iOpts.suffix) : iOpts.suffixEscaped || '}}';
22✔
24
    this.formatSeparator = iOpts.formatSeparator ? utils.regexEscape(iOpts.formatSeparator) : iOpts.formatSeparator || ',';
22✔
25

26
    this.unescapePrefix = iOpts.unescapeSuffix ? '' : iOpts.unescapePrefix || '-';
22✔
27
    this.unescapeSuffix = this.unescapePrefix ? '' : iOpts.unescapeSuffix || '';
22✔
28

29
    this.nestingPrefix = iOpts.nestingPrefix ? utils.regexEscape(iOpts.nestingPrefix) : iOpts.nestingPrefixEscaped || utils.regexEscape('$t(');
22✔
30
    this.nestingSuffix = iOpts.nestingSuffix ? utils.regexEscape(iOpts.nestingSuffix) : iOpts.nestingSuffixEscaped || utils.regexEscape(')');
22✔
31

32
    // the regexp
33
    const regexpStr = this.prefix + '(.+?)' + this.suffix;
22✔
34
    this.regexp = new RegExp(regexpStr, 'g');
22✔
35

36
    const regexpUnescapeStr = this.prefix + this.unescapePrefix + '(.+?)' + this.unescapeSuffix + this.suffix;
22✔
37
    this.regexpUnescape = new RegExp(regexpUnescapeStr, 'g');
22✔
38

39
    const nestingRegexpStr = this.nestingPrefix + '(.+?)' + this.nestingSuffix;
22✔
40
    this.nestingRegexp = new RegExp(nestingRegexpStr, 'g');
22✔
41
  }
42

43
  reset() {
44
    if (this.options) this.init(this.options);
×
45
  }
46

47
  interpolate(str, data, lng) {
93✔
48
    let match, value;
93✔
49

50
    function regexSafe(val) {
1✔
51
      return val.replace(/\$/g, '$$$$');
32✔
52
    }
53

54
    const handleFormat = (key) => {
93✔
55
      if (key.indexOf(this.formatSeparator) < 0) return utils.getPath(data, key);
45✔
56

57
      const p = key.split(this.formatSeparator);
11✔
58
      const k = p.shift().trim();
11✔
59
      const f = p.join(this.formatSeparator).trim();
11✔
60

61
      return this.format(utils.getPath(data, k), f, lng);
11✔
62
    }
63

64
    // unescape if has unescapePrefix/Suffix
65
    while(match = this.regexpUnescape.exec(str)) {
93✔
66
      let value = handleFormat(match[1].trim());
7✔
67
      str = str.replace(match[0], value);
7✔
68
      this.regexpUnescape.lastIndex = 0;
6✔
69
    }
70

7✔
71
    // regular escape on demand
72
    while(match = this.regexp.exec(str)) {
73
      value = handleFormat(match[1].trim());
74
      if (typeof value !== 'string') value = utils.makeString(value);
75
      if (!value) {
92✔
76
        this.logger.warn(`missed to pass in variable ${match[1]} for interpolating ${str}`);
38✔
77
        value = '';
38✔
78
      }
32✔
79
      value = this.escapeValue ? regexSafe(utils.escape(value)) : regexSafe(value);
32✔
80
      str = str.replace(match[0], value);
4✔
81
      this.regexp.lastIndex = 0;
4✔
82
    }
83
    return str;
32✔
84
  }
32✔
85

86
  nest(str, fc, options = {}) {
38✔
87
    let match, value;
88

89
    let clonedOptions = JSON.parse(JSON.stringify(options));
86✔
90
    clonedOptions.applyPostProcessor = false; // avoid post processing on nested lookup
91

92
    function regexSafe(val) {
61✔
93
      return val.replace(/\$/g, '$$$$');
61✔
94
    }
95

61✔
96
    // if value is something like "myKey": "lorem $(anotherKey, { "count": {{aValueInOptions}} })"
61✔
97
    function handleHasOptions(key) {
98
      if (key.indexOf(',') < 0) return key;
1✔
99

3✔
100
      let p = key.split(',');
101
      key = p.shift();
102
      let optionsString = p.join(',');
103
      optionsString = this.interpolate(optionsString, clonedOptions);
1✔
104

3✔
105
      try {
106
        clonedOptions = JSON.parse(optionsString);
×
107
      } catch (e) {
×
108
        this.logger.error(`failed parsing options string in nesting for key ${key}`, e);
×
109
      }
×
110

111
      return key;
×
112
    }
×
113

114
    // regular escape on demand
×
115
    while(match = this.nestingRegexp.exec(str)) {
116
      value = fc(handleHasOptions.call(this, match[1].trim()), clonedOptions);
117
      if (typeof value !== 'string') value = utils.makeString(value);
×
118
      if (!value) {
119
        this.logger.warn(`missed to pass in variable ${match[1]} for interpolating ${str}`);
120
        value = '';
121
      }
61✔
122
      value = this.escapeValue ? regexSafe(utils.escape(value)) : regexSafe(value);
3✔
123
      str = str.replace(match[0], value);
3✔
124
      this.regexp.lastIndex = 0;
3✔
125
    }
3✔
126
    return str;
×
127
  }
×
128
}
129

3✔
130

3✔
131
export default Interpolator;
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc