Skip to content

Commit 904a7d9

Browse files
authored
fix(localization): correctly format number with escaped semicolon (T1275922)
1 parent 789d098 commit 904a7d9

File tree

2 files changed

+40
-2
lines changed

2 files changed

+40
-2
lines changed

packages/devextreme/js/localization/ldml/number.js

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,36 @@ function getGroupSizes(formatString) {
1919
});
2020
}
2121

22+
function splitSignParts(format, separatorChar = ';', escapingChar = ESCAPING_CHAR) {
23+
const parts = [];
24+
let currentPart = '';
25+
let state = 'searchingSeparator';
26+
27+
for(let i = 0; i < format.length; i++) {
28+
const char = format[i];
29+
if(state === 'searchingSeparator' && char === escapingChar) {
30+
state = 'skippingSeparationInsideEscaping';
31+
} else if(state === 'skippingSeparationInsideEscaping' && char === escapingChar) {
32+
state = 'searchingSeparator';
33+
} else if(state === 'searchingSeparator' && char === separatorChar) {
34+
state = 'separating';
35+
parts.push(currentPart);
36+
currentPart = '';
37+
}
38+
39+
if(state !== 'separating') {
40+
currentPart += char;
41+
} else {
42+
state = 'searchingSeparator';
43+
}
44+
}
45+
46+
parts.push(currentPart);
47+
return parts;
48+
}
49+
2250
function getSignParts(format) {
23-
const signParts = format.split(';');
51+
const signParts = splitSignParts(format);
2452

2553
if(signParts.length === 1) {
2654
signParts.push('-' + signParts[0]);
@@ -38,7 +66,7 @@ function isPercentFormat(format) {
3866
}
3967

4068
function removeStubs(str) {
41-
return str.replace(/'.+'/g, '');
69+
return str.replace(/'[^']*'/g, '');
4270
}
4371

4472
function getNonRequiredDigitCount(floatFormat) {

packages/devextreme/testing/tests/DevExpress.localization/ldml.tests.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,16 @@ QUnit.module('number formatter', () => {
228228
assert.strictEqual(getNumberFormatter('#0.00 руб\'.\'')(15), '15.00 руб.', 'special chars was escaped');
229229
});
230230

231+
QUnit.test('escaped semicolon in format', function(assert) {
232+
const formatter = getNumberFormatter('\';\'plus \';\' 0;minus \';\' 0\';\'');
233+
234+
assert.strictEqual(formatter(-8), 'minus ; 8;', 'semicolons were escaped');
235+
assert.strictEqual(formatter(8), ';plus ; 8', 'semicolons were escaped');
236+
237+
// T1275922
238+
assert.strictEqual(getNumberFormatter('\';\'0')(8), ';8', 'semicolons were escaped');
239+
});
240+
231241
QUnit.test('percent formatting with leading zero', function(assert) {
232242
const formatter = getNumberFormatter('#0.#%;(#0.#%)');
233243

0 commit comments

Comments
 (0)