Add String formatting
Add String formatting by extending the String object with a format method. Now we can do stuff like "Text: %s, %d".format(somevar, 5) This is required for proper translation of some strings. https://bugzilla.gnome.org/show_bug.cgi?id=595661
This commit is contained in:
parent
caa08f27fa
commit
64cd51667d
@ -1,4 +1,5 @@
|
|||||||
jsmiscdir = $(pkgdatadir)/js/misc
|
jsmiscdir = $(pkgdatadir)/js/misc
|
||||||
|
|
||||||
dist_jsmisc_DATA = \
|
dist_jsmisc_DATA = \
|
||||||
docInfo.js
|
docInfo.js \
|
||||||
|
format.js
|
||||||
|
44
js/misc/format.js
Normal file
44
js/misc/format.js
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function is intended to extend the String object and provide
|
||||||
|
* an String.format API for string formatting.
|
||||||
|
* It has to be set up using String.prototype.format = Format.format;
|
||||||
|
* Usage:
|
||||||
|
* "somestring %s %d".format('hello', 5);
|
||||||
|
* It supports %s, %d and %f, for %f it also support precisions like
|
||||||
|
* "%.2f".format(1.526)
|
||||||
|
*/
|
||||||
|
|
||||||
|
function format() {
|
||||||
|
let str = this;
|
||||||
|
let i = 0;
|
||||||
|
let args = arguments;
|
||||||
|
|
||||||
|
return str.replace(/%(?:\.([0-9]+))?(.)/g, function (str, precisionGroup, genericGroup) {
|
||||||
|
|
||||||
|
if (precisionGroup != '' && genericGroup != 'f')
|
||||||
|
throw new Error("Precision can only be specified for 'f'");
|
||||||
|
|
||||||
|
switch (genericGroup) {
|
||||||
|
case '%':
|
||||||
|
return '%';
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
return args[i++].toString();
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
return parseInt(args[i++]);
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
if (precisionGroup == '')
|
||||||
|
return parseFloat(args[i++]);
|
||||||
|
else
|
||||||
|
return parseFloat(args[i++]).toFixed(parseInt(precisionGroup));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Error('Unsupported conversion character %' + genericGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
@ -4,6 +4,8 @@ const St = imports.gi.St;
|
|||||||
|
|
||||||
const Tweener = imports.ui.tweener;
|
const Tweener = imports.ui.tweener;
|
||||||
|
|
||||||
|
const Format = imports.misc.format;
|
||||||
|
|
||||||
// "monkey patch" in some varargs ClutterContainer methods; we need
|
// "monkey patch" in some varargs ClutterContainer methods; we need
|
||||||
// to do this per-container class since there is no representation
|
// to do this per-container class since there is no representation
|
||||||
// of interfaces in Javascript
|
// of interfaces in Javascript
|
||||||
@ -30,4 +32,5 @@ _patchContainerClass(St.Table);
|
|||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
Tweener.init();
|
Tweener.init();
|
||||||
|
String.prototype.format = Format.format;
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,8 @@ TEST_JS = \
|
|||||||
interactive/scrolling.js \
|
interactive/scrolling.js \
|
||||||
interactive/table.js \
|
interactive/table.js \
|
||||||
testcommon/border-image.png \
|
testcommon/border-image.png \
|
||||||
testcommon/ui.js
|
testcommon/ui.js \
|
||||||
|
unit/format.js
|
||||||
EXTRA_DIST += $(TEST_JS)
|
EXTRA_DIST += $(TEST_JS)
|
||||||
|
|
||||||
TEST_MISC = \
|
TEST_MISC = \
|
||||||
|
29
tests/unit/format.js
Normal file
29
tests/unit/format.js
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test cases for the Format module
|
||||||
|
*/
|
||||||
|
|
||||||
|
const JsUnit = imports.jsUnit;
|
||||||
|
const assertEquals = JsUnit.assertEquals;
|
||||||
|
const assertRaises = JsUnit.assertRaises;
|
||||||
|
|
||||||
|
// We can't depend on environment.js to set up the String.prototype.format,
|
||||||
|
// because the tests run in one JS context, and the imports run in the GJS
|
||||||
|
// "load context" which has its own copy of the String class
|
||||||
|
const Format = imports.misc.format;
|
||||||
|
String.prototype.format = Format.format;
|
||||||
|
|
||||||
|
// Test common usage and %% handling
|
||||||
|
assertEquals("foo", "%s".format('foo'));
|
||||||
|
assertEquals("%s", "%%s".format('foo'));
|
||||||
|
assertEquals("%%s", "%%%%s".format('foo'));
|
||||||
|
assertEquals("foo 5", "%s %d".format('foo', 5));
|
||||||
|
assertEquals("8", "%d".format(8));
|
||||||
|
assertEquals("2.58 6.96", "%f %.2f".format(2.58, 6.958));
|
||||||
|
|
||||||
|
// Precision is only allowed for %f
|
||||||
|
assertRaises(function() { "%.2d".format(5.21) });
|
||||||
|
|
||||||
|
// Wrong conversion character ' '
|
||||||
|
assertRaises( function() { "%s is 50% done".format('foo') });
|
Loading…
Reference in New Issue
Block a user