Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

message-format

Package Overview
Dependencies
Maintainers
1
Versions
30
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

message-format - npm Package Compare versions

Comparing version 0.0.3 to 0.0.4

scripts/cldr.js

5

package.json
{
"name": "message-format",
"version": "0.0.3",
"version": "0.0.4",
"description": "Intl.MessageFormat polyfill supporting ICU message format",

@@ -27,3 +27,4 @@ "main": "dist/message-format.js",

"benchmark": "6to5-node --loose=all scripts/benchmark.js",
"prepublish": "6to5 --loose all src --out-dir dist",
"cldr": "scripts/cldr.sh",
"prepublish": "6to5 --loose=all src --out-dir dist",
"test": "jshint src/*.js && karma start --browsers Firefox --single-run"

@@ -30,0 +31,0 @@ },

35

README.md

@@ -9,4 +9,2 @@ # message-format

This is still a work in progress. Only the default English locale is available.
Quick Start

@@ -46,2 +44,9 @@ -----------

### Loading locale data
message-format supports plural rules for all CLDR languages. Locale-aware
formatting of number, date, and time are delegated to the `Intl` objects,
and select is the same across all locales. You don't need to load any extra
files for particular locales for message-format.
### Unsupported ICU Formats

@@ -91,4 +96,4 @@

- `options` is an optional object containing options that change the behavior of `MessageFormat`.
-- `cache` default `true`, if `true` cache the result of preparing the `format` function. The cache is shared across all instances of `MessageFormat`.
-- `escape` default `"'"`, if any other character, escape the single character following each escape character.
- `cache` default `true`, if `true` cache the result of preparing the `format` function. The cache is shared across all instances of `MessageFormat`.
- `escape` default `'`, if any other character, escape the single character following each escape character.

@@ -114,4 +119,4 @@ ### `MessageFormat` instances

var message = new MessageFormat('Welcome back, {name}!');
message.format({ name:'Bob' }); // 'Welcome back, Bob!'
message.format({ name:'Bill' }); // 'Welcome back, Bill!'
message.format({ name:'Bob' }); // "Welcome back, Bob!"
message.format({ name:'Bill' }); // "Welcome back, Bill!"
```

@@ -123,6 +128,10 @@

1 `''` is always `'`
2 `'` begins an escaped string only if followed immediately by a syntax char (`'{}#'`)
3 `'` ends an escaped string, unless it is doubled. See #1
1. `''` is always `'`
2. `'` begins an escaped string only if followed immediately by a syntax char (`{}#`)
3. `'` ends an escaped string, unless it is doubled. See #1
The recommendation from ICU is to use the ASCII apostrophe (`'` U+0027) only
for escaping syntax characters, and use the pretty single quote (`’` U+2019)
for actual apostrophes and single quotes in a message pattern.
```js

@@ -141,9 +150,9 @@ var message = new MessageFormat('This isn\'\'t a \'{simple}\' \'string\'');

var message = new MessageFormat('You took {n,number} pictures since {d,date} {d,time}');
message.format({ n:4000, d:new Date() }); // 'You took 4,000 pictures since Jan 1, 2015 9:33:04 AM'
message.format({ n:4000, d:new Date() }); // "You took 4,000 pictures since Jan 1, 2015 9:33:04 AM"
message = new MessageFormat('{ n, number, percent }');
message.format({ n:0.1 }); // '10%'
message.format({ n:0.1 }); // "10%"
message = new MessageFormat('{ shorty, date, short }');
message.format({ shorty:new Date() }); // '1/1/15'
message.format({ shorty:new Date() }); // "1/1/15"
```

@@ -174,3 +183,3 @@

numBananas: 27
}) // 'On 1/1/15 Curious George ate 27 bananas at his house.'
}) // "On 1/1/15 Curious George ate 27 bananas at his house."
```

@@ -177,0 +186,0 @@

import IntlPolyfill from 'intl'
import IntlMF from 'intl-messageformat'
import MessageFormat from './src/message-format'
import Parser from './src/parser'
import MessageFormat from '../src/message-format'
import Parser from '../src/parser'
import Benchmark from 'benchmark'

@@ -6,0 +6,0 @@

@@ -17,6 +17,8 @@ /**

constructor(locale, data, elements) {
constructor(locale, data, formats, elements, options) {
this.originalLocale = locale
this.localeData = data
this.formats = formats
this.elements = elements
this.enableCache = ('cache' in options) ? options.cache : true
}

@@ -26,4 +28,4 @@

compile(elements, parent) {
elements = elements || this.elements
elements = elements.map(element => this.compileElement(element, parent))
elements = elements || this.elements
elements = elements.map(element => this.compileElement(element, parent))

@@ -35,9 +37,9 @@ // optimize common case

return function format(args) {
let message = ''
for (let e = 0, ee = elements.length; e < ee; ++e) {
message += elements[e](args)
}
return message
}
return function format(args) {
let message = ''
for (let e = 0, ee = elements.length; e < ee; ++e) {
message += elements[e](args)
}
return message
}
}

@@ -52,10 +54,10 @@

let
id = element[0],
type = element[1],
style = element[2]
id = element[0],
type = element[1],
style = element[2]
if ('#' === id) {
let
id = parent[0],
offset = parent[2]
id = parent[0],
offset = parent[2]
return this.compileNumber(id, offset, null)

@@ -72,4 +74,4 @@ }

let
offset = element[2],
options = element[3]
offset = element[2],
options = element[3]
return this.compilePlural(id, offset, options)

@@ -88,13 +90,18 @@ case 'select':

let
key = 'number:' + style,
locale = this.originalLocale,
data = this.localeData,
cache = data.cache,
formats = this.formats,
cache = formats.cache,
key = locale + ':number:' + style,
func
if (this.enableCache && key in cache) {
func = cache[key]
if (!func) {
func = cache[key] = new Intl.NumberFormat(locale, data.formats.number[style]).format
} else {
func = cache[key] = new Intl.NumberFormat(locale, formats.number[style]).format
if (this.enableCache) {
cache[key] = func
}
}
return function format(args) {
return func(+args[id] - offset)
}
return func(+args[id] - offset)
}
}

@@ -106,13 +113,18 @@

let
key = type + ':' + style,
locale = this.originalLocale,
data = this.localeData,
cache = data.cache,
formats = this.formats,
cache = formats.cache,
key = locale + ':' + type + ':' + style,
func
if (this.enableCache && key in cache) {
func = cache[key]
if (!func) {
func = cache[key] = new Intl.DateTimeFormat(locale, data.formats[type][style]).format
} else {
func = cache[key] = new Intl.DateTimeFormat(locale, formats[type][style]).format
if (this.enableCache) {
cache[key] = func
}
}
return function format(args) {
return func(args[id])
}
return function format(args) {
return func(args[id])
}
}

@@ -129,13 +141,13 @@

})
return function format(args) {
let
arg = +args[id],
exactSelector = '=' + arg,
keywordSelector = plural(arg - offset),
func =
options[exactSelector] ||
options[keywordSelector] ||
options.other
return func(args)
}
return function format(args) {
let
arg = +args[id],
exactSelector = '=' + arg,
keywordSelector = plural(arg - offset),
func =
options[exactSelector] ||
options[keywordSelector] ||
options.other
return func(args)
}
}

@@ -149,10 +161,10 @@

})
return function format(args) {
let
selector = args[id],
func =
options[selector] ||
options.other
return func(args)
}
return function format(args) {
let
selector = args[id],
func =
options[selector] ||
options.other
return func(args)
}
}

@@ -163,9 +175,9 @@

return function format(args) {
return '' + args[id]
}
return '' + args[id]
}
}
static compile(locale, data, elements) {
return new Compiler(locale, data, elements).compile()
static compile(locale, data, formats, elements, options) {
return new Compiler(locale, data, formats, elements, options).compile()
}

@@ -172,0 +184,0 @@

@@ -7,2 +7,3 @@ /*! Intl.MessageFormat polyfill v0.0.1

import Compiler from './compiler'
import locales from './locales'

@@ -21,6 +22,6 @@ /**

let
closest = lookupClosestLocale(locale, MessageFormat.data),
data = MessageFormat.data[closest],
closest = lookupClosestLocale(locale, MessageFormat.data.locales),
data = MessageFormat.data.locales[closest],
enableCache = ('cache' in options) ? options.cache : true,
cache = data.cache,
cache = MessageFormat.data.formats.cache,
key = 'message:' + pattern,

@@ -35,3 +36,5 @@ format

data,
Parser.parse(pattern, options)
MessageFormat.data.formats,
Parser.parse(pattern, options),
options
)

@@ -63,3 +66,3 @@ if (enableCache) {

let
locales = [].concat(locale || [])
locales = [].concat(locale || [])
for (let l = 0, ll = locales.length; l < ll; ++l) {

@@ -82,28 +85,36 @@ let current = locales[l].split('-')

let data = {
en: {
locale: 'en',
locales: {
en: {
locale: 'en',
plural(n) {
return n === 1 ? 'one' : 'other'
}
}
},
formats: {
cache: {},
plural(n) {
return n === 1 ? 'one' : 'other'
number: {
currency: { style:'currency', currency:'USD' },
percent: { style:'percent' }
},
formats: {
number: {
currency: { style:'currency', currency:'USD' },
percent: { style:'percent' }
},
date: {
short: { month:'numeric', day:'numeric', year:'2-digit' },
medium: { month:'short', day:'numeric', year:'numeric' },
long: { month:'long', day:'numeric', year:'numeric' },
full: { month:'long', day:'numeric', year:'numeric', weekday:'long' }
},
time: {
short: { hour:'numeric', minute:'numeric' },
medium: { hour:'numeric', minute:'numeric', second:'numeric' },
long: { hour:'numeric', minute:'numeric', second:'numeric', timeZoneName:'short' },
full: { hour:'numeric', minute:'numeric', second:'numeric', timeZoneName:'short' }
}
date: {
short: { month:'numeric', day:'numeric', year:'2-digit' },
medium: { month:'short', day:'numeric', year:'numeric' },
long: { month:'long', day:'numeric', year:'numeric' },
full: { month:'long', day:'numeric', year:'numeric', weekday:'long' }
},
time: {
short: { hour:'numeric', minute:'numeric' },
medium: { hour:'numeric', minute:'numeric', second:'numeric' },
long: { hour:'numeric', minute:'numeric', second:'numeric', timeZoneName:'short' },
full: { hour:'numeric', minute:'numeric', second:'numeric', timeZoneName:'short' }
}
}
}
Object.keys(locales).forEach(function(locale) {
let plural = locales[locale]
data.locales[locale] = {
locale, plural
}
})
Object.defineProperty(MessageFormat, 'data', { value:data })

@@ -110,0 +121,0 @@

@@ -58,4 +58,4 @@ import MessageFormat from '../src/message-format'

`On {takenDate, date, short} {name} took {numPhotos, plural,
=0 {no photos.}
=1 {one photo.}
=0 {no photos.}
=1 {one photo.}
other {# photos.}}`,

@@ -69,2 +69,23 @@ message = new MessageFormat(pattern, 'en-US')

it('handles plurals for other locales', () => {
let
pattern =
`{n, plural,
zero {zero}
one {one}
two {two}
few {few}
many {many}
other {other}}`,
message = new MessageFormat(pattern, 'ar')
expect(message.resolvedOptions().locale).toBe('ar')
expect(message.format({ n:0 })).toBe('zero')
expect(message.format({ n:1 })).toBe('one')
expect(message.format({ n:2 })).toBe('two')
expect(message.format({ n:3 })).toBe('few')
expect(message.format({ n:11 })).toBe('many')
})
it('handles select', () => {

@@ -74,5 +95,5 @@ let

`{ gender, select,
male {it's his turn}
female {it's her turn}
other {it's their turn}}`,
male {it's his turn}
female {it's her turn}
other {it's their turn}}`,
message = new MessageFormat(pattern, 'en-US')

@@ -79,0 +100,0 @@ .format({ gender:'female' })

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc