Skip to content

Commit ca5793a

Browse files
committed
Message: add support for custom formatters
Most globalize modules can now be used directly from within messages. Also fixes selectOrdinal not using the correct plural function. The messageformat compiler and runtime are forked from messageformat.js. Fixes #563
1 parent 32aaaa6 commit ca5793a

File tree

21 files changed

+504
-95
lines changed

21 files changed

+504
-95
lines changed

Gruntfile.js

Lines changed: 25 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,8 @@ module.exports = function( grunt ) {
132132
paths: {
133133
cldr: "../external/cldrjs/dist/cldr",
134134
"make-plural": "../external/make-plural/make-plural",
135-
messageformat: "../external/messageformat/messageformat",
135+
"messageformat-parser": "../node_modules/messageformat-parser/parser",
136+
"reserved-words": "../node_modules/reserved-words/lib/reserved-words",
136137
"zoned-date-time": "../node_modules/zoned-date-time/src/zoned-date-time"
137138
},
138139
shim: {
@@ -151,8 +152,7 @@ module.exports = function( grunt ) {
151152
// Only for root id's (the ones in src, not in src's subpaths). Note there's no
152153
// conditional code checking for this type.
153154
onBuildWrite: function( id, path, contents ) {
154-
var messageformat,
155-
name = camelCase( id.replace( /util\/|common\//, "" ) );
155+
var name = camelCase( id.replace( /util\/|common\//, "" ) );
156156

157157
// MakePlural
158158
if ( ( /make-plural/ ).test( id ) ) {
@@ -200,68 +200,39 @@ module.exports = function( grunt ) {
200200
"/* jshint ignore:end */"
201201
].join( "\n" ) );
202202

203-
// messageformat
204-
} else if ( ( /messageformat/ ).test( id ) ) {
205-
return contents
203+
// messageformat-parser
204+
} else if ( ( /messageformat-parser/.test( id ) ) ) {
206205

207-
// Remove browserify wrappers.
208-
.replace( /^\(function\(f\)\{if\(typeof exports==="object"&&type.*/, "" )
209-
.replace( "},{}],2:[function(require,module,exports){", "" )
210-
.replace( /\},\{"\.\/messageformat-parser":1,"make-plural\/plural.*/, "" )
211-
.replace( /\},\{\}\]\},\{\},\[2\]\)\(2\)[\s\S]*?$/, "" )
212-
213-
// Set `MessageFormat.plurals` and remove `make-plural/plurals`
214-
// completely. This is populated by Globalize on demand.
215-
.replace( /var _cp = \[[\s\S]*?$/, "" )
216-
.replace(
217-
"MessageFormat.plurals = require('make-plural/plurals')",
218-
"MessageFormat.plurals = {}"
219-
)
220-
221-
// Set `MessageFormat._parse`
222-
.replace(
223-
"MessageFormat._parse = require('./messageformat-parser').parse;",
224-
""
225-
)
226-
.replace( /module\.exports = \(function\(\) \{([\s\S]*?)\n\}\)\(\);/, [
227-
"MessageFormat._parse = (function() {",
228-
"$1",
229-
"}()).parse;"
206+
return contents
207+
.replace( /^/, [
208+
"var Parser;",
209+
"/* jshint ignore:start */\n",
210+
"Parser = (function() {"
230211
].join( "\n" ) )
212+
.replace( "module.exports = ", "return " )
213+
.replace( /$/, [
214+
"}());",
215+
"/* jshint ignore:end */"
216+
].join( "\n" ) );
231217

232-
// Remove unused code.
233-
.replace( /if \(!pluralFunc\) \{\n[\s\S]*?\n \}/, "" )
234-
.replace( /if \(!locale\) \{\n[\s\S]*? \}\n/, "this.lc = [locale];" )
235-
.replace( /(MessageFormat\.formatters) = \{[\s\S]*?\n\};/, "$1 = {};" )
236-
.replace( /MessageFormat\.prototype\.setIntlSupport[\s\S]*?\n\};/, "" )
218+
// reserved-words
219+
} else if ( ( /reserved-words/.test( id ) ) ) {
237220

238-
// Wrap everything into a var assignment.
239-
.replace( "module.exports = MessageFormat;", "" )
221+
return contents
240222
.replace( /^/, [
241-
"var MessageFormat;",
242-
"/* jshint ignore:start */",
243-
"MessageFormat = (function() {"
223+
"var reserved;",
224+
"/* jshint ignore:start */\n",
225+
"reserved = (function() {",
226+
"var exports = {};"
244227
].join( "\n" ) )
228+
.replace( "var assert = require\('assert'\);", "" )
229+
.replace( /^\s*assert\(.*;\s*$/gm, "" )
245230
.replace( /$/, [
246-
"return MessageFormat;",
231+
"return exports;",
247232
"}());",
248233
"/* jshint ignore:end */"
249234
].join( "\n" ) );
250235

251-
// message-runtime
252-
} else if ( ( /message-runtime/ ).test( id ) ) {
253-
messageformat = require( "./external/messageformat/messageformat" );
254-
delete messageformat.prototype.runtime.fmt;
255-
delete messageformat.prototype.runtime.pluralFuncs;
256-
contents = contents.replace( "Globalize._messageFormat = {};", [
257-
"/* jshint ignore:start */",
258-
"Globalize._messageFormat = (function() {",
259-
messageformat.prototype.runtime.toString(),
260-
"return {number: number, plural: plural, select: select};",
261-
"}());",
262-
"/* jshint ignore:end */"
263-
].join( "\n" ) );
264-
265236
// ZonedDateTime
266237
} else if ( ( /zoned-date-time/ ).test( id ) ) {
267238
contents = contents.replace(

examples/amd-bower/main.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ require([
4141
"json!cldr-data/supplemental/likelySubtags.json",
4242
"json!cldr-data/supplemental/metaZones.json",
4343
"json!cldr-data/supplemental/plurals.json",
44+
"json!cldr-data/supplemental/ordinals.json",
4445
"json!cldr-data/supplemental/timeData.json",
4546
"json!cldr-data/supplemental/weekData.json",
4647
"json!messages/en.json",
@@ -54,9 +55,8 @@ require([
5455
"globalize/plural",
5556
"globalize/relative-time",
5657
"globalize/unit"
57-
], function( Globalize, enGregorian, enCurrencies, enDateFields, enNumbers,
58-
enTimeZoneNames, enUnits, currencyData, likelySubtags, metaZones,
59-
pluralsData, timeData, weekData, messages, ianaTzData ) {
58+
], function( Globalize, enGregorian, enCurrencies, enDateFields, enNumbers, enUnits, currencyData,
59+
likelySubtags, pluralsData, ordinalsData, timeData, weekData, messages ) {
6060

6161
var en, like, number;
6262

@@ -72,6 +72,7 @@ require([
7272
likelySubtags,
7373
metaZones,
7474
pluralsData,
75+
ordinalsData,
7576
timeData,
7677
weekData
7778
);

examples/node-npm/main.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ Globalize.load(
1313
require( "cldr-data/supplemental/likelySubtags" ),
1414
require( "cldr-data/supplemental/metaZones" ),
1515
require( "cldr-data/supplemental/plurals" ),
16+
require( "cldr-data/supplemental/ordinals" ),
1617
require( "cldr-data/supplemental/timeData" ),
1718
require( "cldr-data/supplemental/weekData" )
1819
);

examples/plain-javascript/index.html

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,14 @@ <h2>Demo output</h2>
267267
"pluralRule-count-one": "i = 1 and v = 0 @integer 1",
268268
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
269269
}
270+
},
271+
"plurals-type-ordinal": {
272+
"en": {
273+
"pluralRule-count-one": "n % 10 = 1 and n % 100 != 11 @integer 1, 21, 31, 41, 51, 61, 71, 81, 101, 1001, …",
274+
"pluralRule-count-two": "n % 10 = 2 and n % 100 != 12 @integer 2, 22, 32, 42, 52, 62, 72, 82, 102, 1002, …",
275+
"pluralRule-count-few": "n % 10 = 3 and n % 100 != 13 @integer 3, 23, 33, 43, 53, 63, 73, 83, 103, 1003, …",
276+
"pluralRule-count-other": " @integer 0, 4~18, 100, 1000, 10000, 100000, 1000000, …"
277+
}
270278
}
271279
}
272280
});

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,9 @@
9595
"iana-tz-data": ">=2017.0.0",
9696
"matchdep": "0.3.0",
9797
"mocha": "^3.3.0",
98-
"zoned-date-time": "0.0.4"
98+
"zoned-date-time": "0.0.4",
99+
"messageformat-parser": "^1.0.0",
100+
"reserved-words": "^0.1.1"
99101
},
100102
"commitplease": {
101103
"nohook": true

src/common/validate/parameter-type/plural-type.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ return function( value, name ) {
66
validateParameterType(
77
value,
88
name,
9-
value === undefined || value === "cardinal" || value === "ordinal",
10-
"String \"cardinal\" or \"ordinal\""
9+
value === undefined || value === "cardinal" || value === "ordinal" || value === "both",
10+
"String \"cardinal\" or \"ordinal\" or \"both\""
1111
);
1212
};
1313

src/core.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,12 @@ Globalize.locale = function( locale ) {
8686
return this.cldr;
8787
};
8888

89+
Globalize._messageFmts = {};
90+
91+
Globalize.addMessageFormatterFunction = function( name, fn ) {
92+
Globalize._messageFmts[name] = fn;
93+
};
94+
8995
/**
9096
* Optimization to avoid duplicating some internal functions across modules.
9197
*/

src/currency.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,14 @@ Globalize.prototype.currencyFormatter = function( currency, options ) {
9191
return returnFn;
9292
};
9393

94+
Globalize.addMessageFormatterFunction( "currency", function( currency, style ) {
95+
var options = {};
96+
if ( style ) {
97+
options.style = style;
98+
}
99+
return this.currencyFormatter( currency, options );
100+
});
101+
94102
/**
95103
* .currencyParser( currency [, options] )
96104
*

src/date.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,16 @@ Globalize.prototype.dateToPartsFormatter = function( options ) {
210210
return returnFn;
211211
};
212212

213+
[ "date", "time", "datetime" ].map(function( type ) {
214+
Globalize.addMessageFormatterFunction( type, function( p ) {
215+
var options = {};
216+
if ( p ) {
217+
options[type] = p;
218+
}
219+
return this.dateFormatter( options );
220+
});
221+
});
222+
213223
/**
214224
* .dateParser( options )
215225
*

src/message-runtime.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,14 @@ define([
22
"./common/runtime-key",
33
"./common/validate/parameter-type/message-variables",
44
"./core-runtime",
5-
"./message/formatter-fn"
6-
], function( runtimeKey, validateParameterTypeMessageVariables, Globalize, messageFormatterFn ) {
5+
"./message/formatter-fn",
6+
"./message/formatter-runtime"
7+
], function( runtimeKey, validateParameterTypeMessageVariables, Globalize, messageFormatterFn,
8+
messageFormatterRuntime
9+
) {
710

811
Globalize._messageFormatterFn = messageFormatterFn;
9-
Globalize._messageFormat = {};
12+
Globalize._messageFormat = new messageFormatterRuntime(); // TODO setStrictNumber
1013
Globalize._validateParameterTypeMessageVariables = validateParameterTypeMessageVariables;
1114

1215
Globalize.messageFormatter =

0 commit comments

Comments
 (0)