Skip to content

Commit 792c943

Browse files
committed
Message: Provide Bidi structured text support (2/2)
Closes #539 Fixes #599
1 parent eaf5709 commit 792c943

File tree

7 files changed

+53
-62
lines changed

7 files changed

+53
-62
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -484,7 +484,7 @@ Read more details about locale at [UTS#35 locale][].
484484

485485
[Read more...](doc/api/message/load-messages.md)
486486

487-
- **`.messageFormatter( path ) ➡ function( [variables] )`**
487+
- **`.messageFormatter( path [, options] ) ➡ function( [variables] )`**
488488

489489
Return a function that formats a message (using ICU message format pattern)
490490
given its path and a set of variables into a user-readable string. It supports
@@ -500,9 +500,9 @@ Read more details about locale at [UTS#35 locale][].
500500

501501
[Read more...](doc/api/message/message-formatter.md)
502502

503-
- **`.formatMessage( path [, variables ] )`**
503+
- **`.formatMessage( path [, variables, options ] )`**
504504

505-
Alias for `.messageFormatter( path )([ variables ])`.
505+
Alias for `.messageFormatter( path [, options] )([ variables ])`.
506506

507507
### Number module
508508

bower.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
},
1414
"devDependencies": {
1515
"es5-shim": "3.4.0",
16-
"make-plural": "eemeli/make-plural.js#^3.0.0-rc4",
16+
"make-plural": "eemeli/make-plural.js#3.0.0",
1717
"messageformat": "SlexAxton/messageformat.js#v0.3.0",
1818
"qunit": "1.18.0",
1919
"requirejs": "2.1.20",

doc/api/message/message-formatter.md

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
## .messageFormatter( path, options ) ➡ function([ variables ])
1+
## .messageFormatter( path [, options] ) ➡ function([ variables ])
22

33
Return a function that formats a message (using ICU message format pattern)
44
given its path and a set of variables into a user-readable string. It supports
@@ -16,22 +16,22 @@ String or Array containing the path of the message content, eg.
1616

1717
**options** (optional)
1818

19-
Options should be an Objects, where each property can be referenced by name.
20-
The possible property having name recognizable by messageFormatter is "setBiDiSupport".
21-
It should have Boolean value indicating whether Bidi structuring is to be imposed on formatted
22-
message (like {"setBiDiSupport": true}).
23-
Special Unicode Bidi marks are inserted depending on locale in order to preserve the text
24-
flow of structured message which corresponds give local (from right-to-left for Bidi scripts
25-
like Arabic, Hebrew or Pharsi and left-to-right otherwise.
26-
For more info on Bidi structured text see:
27-
http://cldr.unicode.org/development/development-process/design-proposals/bidi-handling-of-structured-text
19+
A JSON object including none or any of the following options.
20+
21+
> **setBiDiSupport** Optional
22+
>
23+
> Boolean (default `false`) enable or disable the addition of Unicode BiDi
24+
> control characters to all input to preserve the the integrity of the output
25+
> when mixing LTR and RTL text, e.g., `{ setBiDiSupport: true }`.
26+
>
27+
> For more information on BiDi structured text see:
28+
> http://cldr.unicode.org/development/development-process/design-proposals/bidi-handling-of-structured-text
2829
2930
**variables** (optional)
3031

31-
Variables can be Objects, where each property can be referenced by name inside a
32-
message; or Arrays, where each entry of the Array can be used inside a message,
33-
using numeric indices. When passing one or more arguments of other types,
34-
they're converted to an Array and used as such.
32+
A JSON object or an Array. When it's a JSON object, each key corresponds to a
33+
message variable. When it's an Array, each item corresponds to a message
34+
variable using numeric indices.
3535

3636
### Example
3737

@@ -84,10 +84,6 @@ formatter = Globalize( "en" ).messageFormatter( "hello" );
8484
formatter([ "Wolfgang", "Amadeus", "Mozart" ]);
8585
// > "Hello, Wolfgang Amadeus Mozart"
8686

87-
// Numbered variables using function arguments.
88-
formatter( "Wolfgang", "Amadeus", "Mozart" );
89-
// > "Hello, Wolfgang Amadeus Mozart"
90-
9187
// Named variables using Object key-value pairs.
9288
formatter = Globalize( "en" ).messageFormatter( "hey" );
9389
formatter({
@@ -224,16 +220,16 @@ likeFormatter( 2 );
224220
likeFormatter( 3 );
225221
// > "You and 2 others liked this"
226222
```
227-
#### Bidi structured meessage
228-
Globalize.loadMessages({
229-
ar: { breadcrumb: "{0} >> {1} >> {2}" }
230-
});
231-
bidiFormatter = Globalize( "ar" ).messageFormatter( "breadcrumb", {"setBiDiSupport": true} );
223+
224+
#### BiDi structured meessage
225+
Globalize.loadMessages({
226+
ar: { breadcrumb: "{0} >> {1} >> {2}" }
227+
});
228+
bidiFormatter = Globalize( "ar" ).messageFormatter( "breadcrumb", { setBiDiSupport: true } );
232229

233230
bidiFormatter( "First", "Second", "Third" );
234231
// > "Third << Second << First"
235232

236-
237233
Read on [SlexAxton/messageFormatter.js][] for more information on regard of ICU
238234
MessageFormat.
239235

src/message-runtime.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,16 @@ Globalize._messageFormat = {};
1010
Globalize._validateParameterTypeMessageVariables = validateParameterTypeMessageVariables;
1111

1212
Globalize.messageFormatter =
13-
Globalize.prototype.messageFormatter = function( /* path */ ) {
13+
Globalize.prototype.messageFormatter = function( path, options ) {
14+
options = options || {};
1415
return Globalize[
15-
runtimeKey( "messageFormatter", this._locale, [].slice.call( arguments, 0 ) )
16+
runtimeKey( "messageFormatter", this._locale, [ path, options ] )
1617
];
1718
};
1819

1920
Globalize.formatMessage =
20-
Globalize.prototype.formatMessage = function( path /* , variables */ ) {
21-
return this.messageFormatter( path ).apply( {}, [].slice.call( arguments, 1 ) );
21+
Globalize.prototype.formatMessage = function( path, variables, options ) {
22+
return this.messageFormatter( path, options ).apply( {}, [ variables ] );
2223
};
2324

2425
return Globalize;

src/message.js

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@ define([
2222
validateParameterPresence, validateParameterType, validateParameterTypePlainObject, Globalize,
2323
messageFormatterFn, messageFormatterRuntimeBind, alwaysArray ) {
2424

25-
var slice = [].slice;
26-
2725
/**
2826
* .loadMessages( json )
2927
*
@@ -62,19 +60,21 @@ Globalize.loadMessages = function( json ) {
6260
*/
6361
Globalize.messageFormatter =
6462
Globalize.prototype.messageFormatter = function( path, options ) {
65-
var cldr, messageFormat, formatter, message, pluralGenerator, returnFn,
66-
args = slice.call( arguments, 0 );
63+
var args, cldr, formatter, message, messageFormat, pluralGenerator, returnFn;
6764

6865
validateParameterPresence( path, "path" );
6966
validateParameterType( path, "path", typeof path === "string" || Array.isArray( path ),
7067
"a String nor an Array" );
7168

72-
path = alwaysArray( path );
7369
cldr = this.cldr;
70+
options = options || {};
7471

7572
validateDefaultLocale( cldr );
7673
validateMessageBundle( cldr );
7774

75+
args = [ path, options ];
76+
path = alwaysArray( path );
77+
7878
message = cldr.get( [ "globalize-messages/{bundle}" ].concat( path ) );
7979
validateMessagePresence( path, message );
8080

@@ -104,19 +104,19 @@ Globalize.prototype.messageFormatter = function( path, options ) {
104104
};
105105

106106
/**
107-
* .formatMessage( path [, variables] )
107+
* .formatMessage( path [, variables, options] )
108108
*
109109
* @path [String or Array]
110110
*
111111
* @variables [Number, String, Array or Object]
112112
*
113+
* @options [object]
114+
*
113115
* Format a message given its path.
114116
*/
115117
Globalize.formatMessage =
116-
Globalize.prototype.formatMessage = function( path /* , variables */ ) {
117-
return ( arguments[ 1 ] && arguments[ 1 ].setBiDiSupport === true ) ?
118-
this.messageFormatter( path, arguments[ 1 ] ).apply( {}, slice.call( arguments, 2 ) ) :
119-
this.messageFormatter( path ).apply( {}, slice.call( arguments, 1 ) );
118+
Globalize.prototype.formatMessage = function( path, variables, options ) {
119+
return this.messageFormatter( path, options ).apply( {}, [ variables ] );
120120
};
121121

122122
return Globalize;

test/functional/message/format-message.js

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
define([
1+
define([
22
"globalize",
33
"json!cldr-data/supplemental/likelySubtags.json",
44
"json!cldr-data/supplemental/plurals.json",
@@ -50,15 +50,11 @@ QUnit.test( "should format a message", function( assert ) {
5050
}), "Hello, Beethoven" );
5151
});
5252

53-
QUnit.test( "should format a message", function( assert ) {
54-
assert.equal( Globalize( "en" ).formatMessage( "greetings/hello", {
55-
name: "Beethoven"
56-
}), "Hello, Beethoven" );
57-
});
58-
59-
QUnit.test( "should support Bidi structured text", function( assert ) {
60-
assert.equal( Globalize( "he" ).formatMessage( "breadcrumb", {"setBiDiSupport": true},
61-
[ "Mozart", "Bethoven", "Dvorzak" ]
53+
QUnit.test( "should support BiDi structured text", function( assert ) {
54+
assert.equal( Globalize( "he" ).formatMessage(
55+
"breadcrumb",
56+
[ "Mozart", "Bethoven", "Dvorzak" ],
57+
{ setBiDiSupport: true }
6258
), "\u200FMozart\u200F >> \u200FBethoven\u200F >> \u200FDvorzak\u200F" );
6359
});
6460

test/functional/message/message-formatter.js

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -146,10 +146,6 @@ QUnit.test( "should support ICU message format", function( assert ) {
146146
assert.messageFormatter( "en", "greetings/helloArray", "Beethoven", "Hello, Beethoven" );
147147
assert.messageFormatter( "en", "greetings/helloArray2", [ "Beethoven", "Mozart" ],
148148
"Hello, Beethoven and Mozart" );
149-
assert.equal(
150-
Globalize( "en" ).messageFormatter( "greetings/helloArray2" )( "Beethoven", "Mozart" ),
151-
"Hello, Beethoven and Mozart"
152-
);
153149
assert.messageFormatter( "en", "greetings/helloName", {
154150
name: "Beethoven"
155151
}, "Hello, Beethoven" );
@@ -178,9 +174,11 @@ QUnit.test( "should support ICU message format", function( assert ) {
178174
assert.equal( like({ count: 3 }), "You and 2 others liked this" );
179175
});
180176

181-
QUnit.test( "should support Bidi structured text", function( assert ) {
177+
QUnit.test( "should support BiDi structured text", function( assert ) {
182178
assert.equal(
183-
Globalize( "he" ).messageFormatter( "helloArray", {"setBiDiSupport": true} )( "Beethoven", "Mozart" ),
179+
Globalize( "he" ).messageFormatter( "helloArray", {
180+
setBiDiSupport: true
181+
})( "Beethoven", "Mozart" ),
184182
"Hello, \u200FBeethoven\u200F & \u200FMozart\u200F"
185183
);
186184
});
@@ -205,8 +203,8 @@ QUnit.test( "should allow for runtime compilation", function( assert ) {
205203
util.assertRuntimeBind(
206204
assert,
207205
Globalize( "en" ).messageFormatter( "amen" ),
208-
"b639686813",
209-
"Globalize(\"en\").messageFormatter(\"amen\")",
206+
"b141291319",
207+
"Globalize(\"en\").messageFormatter(\"amen\",{})",
210208
function( runtimeArgs ) {
211209
assert.equal(
212210
runtimeArgs[ 0 ].toString(),
@@ -218,8 +216,8 @@ QUnit.test( "should allow for runtime compilation", function( assert ) {
218216
util.assertRuntimeBind(
219217
assert,
220218
Globalize( "en" ).messageFormatter( "like" ),
221-
"b328290139",
222-
"Globalize(\"en\").messageFormatter(\"like\")",
219+
"b452335545",
220+
"Globalize(\"en\").messageFormatter(\"like\",{})",
223221
function( runtimeArgs ) {
224222
assert.equal(
225223
runtimeArgs[ 0 ].toString(),

0 commit comments

Comments
 (0)