react-intl-db
Advanced tools
Comparing version 0.0.3 to 0.0.4
{ | ||
"name": "react-intl-db", | ||
"version": "0.0.3", | ||
"version": "0.0.4", | ||
"description": "Load app translations automatically partitioned by domain", | ||
@@ -27,2 +27,3 @@ "main": "lib/domaindb.js", | ||
"chai": "^2.3.0", | ||
"jsdom": "^3.1.2", | ||
"json-loader": "^0.5.1", | ||
@@ -29,0 +30,0 @@ "mocha": "^2.2.4", |
@@ -38,3 +38,3 @@ react-intl-db | ||
import {IntlDomainDatabase} from `react-intl-db`; | ||
import {IntlDomainDatabase} from 'react-intl-db'; | ||
@@ -46,3 +46,3 @@ i18ndb = new IntlDomainDatabase(loader); | ||
loader returns a promise that resolves to `null` or `undefined` for | ||
that domain. | ||
that domain, or when the loader doesn't define a particular message. | ||
@@ -61,16 +61,10 @@ i18ndb.defaultMessages({ | ||
We can now start using this i18ndb with React. You first need to make | ||
the root component of the application aware of the i18n db: | ||
We can now start using this i18ndb with React. Before we can start the | ||
`React.render` though, we need to make sure we have loaded the information | ||
for the right domain: | ||
const IntlApp = i18ndb.makeIntl(App) | ||
i18ndb.setLocale('en-US').then(() => { | ||
React.render(<App />, document.body); | ||
}); | ||
You now have a new `IntlApp` React component that is like `App``, but | ||
takes the `locales` prop. This should contain the locale you want | ||
the application to use: | ||
<IntlApp locales="en-US" /> | ||
`IntlApp` now also makes sure that the right messages are loaded using | ||
the loader before rendering begins. | ||
We can now create a `Format` component for a particular domain that a | ||
@@ -105,10 +99,16 @@ UI application can then use: | ||
You use it by passing the component (typically `this`) as the first | ||
argument, as it needs this to obtain the locale information from the | ||
context: | ||
You use it by passing the `messageId` as the first argument: | ||
render() { | ||
return <input value={formatStr(this, 'myMessageId')} />; | ||
return <input value={formatStr('myMessageId')} />; | ||
} | ||
You can also put in variables: | ||
render() { | ||
return <input value={formatStr('photos', | ||
{ name: 'Annie', numPhotos=1000, takenDate=Date.now()})} />; | ||
} | ||
Limitation | ||
@@ -119,5 +119,8 @@ ---------- | ||
application, not a list of locales. You can instead make sure the | ||
right fallback is happening in the loader. I'm also happy to receive | ||
code that lists this limitation! | ||
right fallback is happening in the loader. | ||
It also has no support for custom formats yet. | ||
I'm happy to receive code that lifts these limitations! | ||
Example application | ||
@@ -139,2 +142,1 @@ ------------------- | ||
import React from 'react'; | ||
import ReactIntl from 'react-intl'; | ||
import {FormattedMessage} from 'react-intl'; | ||
import {FormattedMessage, IntlMixin} from 'react-intl'; | ||
export class IntlDomainDatabase { | ||
@@ -9,2 +10,3 @@ constructor(loader) { | ||
this.locales = {}; | ||
this.currentLocaleId = null; | ||
this.loader = loader; | ||
@@ -19,2 +21,6 @@ this.neededDomainIds = new Set(); | ||
} | ||
setLocale(localeId) { | ||
this.currentLocaleId = localeId; | ||
return this.loadDomains(localeId); | ||
} | ||
loadMessages(localeId, domainId) { | ||
@@ -38,5 +44,5 @@ let domains = this.locales[localeId]; | ||
return this.loader(localeId, domainId).then(messages => { | ||
const domainMessages = this.defaultDomains[domainId]; | ||
if (!messages) { | ||
messages = this.defaultDomains[domainId]; | ||
if (!messages) { | ||
if (!domainMessages) { | ||
return Promise.reject( | ||
@@ -46,4 +52,8 @@ new Error("Unknown locale " + localeId + | ||
} | ||
return messages; | ||
return domainMessages; | ||
} | ||
if (domainMessages) { | ||
messages = Object.assign(domainMessages, | ||
messages); | ||
} | ||
domains[domainId] = messages; | ||
@@ -90,4 +100,12 @@ return messages; | ||
this.neededDomainIds.add(domainId); | ||
return function(component, path) { | ||
return db.getMessageById(getLocaleId(component), domainId, path); | ||
return function(path, values) { | ||
if (values === undefined) { | ||
values = {}; | ||
} | ||
// XXX formats support | ||
const message = db.getMessageById( | ||
db.currentLocaleId, domainId, path); | ||
const format = IntlMixin.getMessageFormat( | ||
message, db.currentLocaleId, {}); | ||
return format.format(values); | ||
}; | ||
@@ -106,3 +124,3 @@ } | ||
getMessageById(path) { | ||
return db.getMessageById(getLocaleId(this), domainId, path); | ||
return db.getMessageById(db.currentLocaleId, domainId, path); | ||
}, | ||
@@ -112,2 +130,3 @@ render() { | ||
props.message = this.getMessageById(this.props.messageId); | ||
props.locales = db.currentLocaleId; | ||
delete props.messageId; | ||
@@ -118,33 +137,2 @@ return React.createElement(FormattedMessage, props); | ||
} | ||
makeIntl(Component) { | ||
const db = this; | ||
return React.createClass({ | ||
mixins: [ReactIntl.IntlMixin], | ||
getInitialState() { | ||
return { | ||
'messagesLoaded': false | ||
} | ||
}, | ||
componentWillMount() { | ||
db.loadDomains(this.props.locales).then(() => { | ||
this.setState({'messagesLoaded': true}); | ||
}); | ||
}, | ||
render() { | ||
if (!this.state.messagesLoaded) { | ||
return null; | ||
} | ||
const props = Object.assign({}, this.props); | ||
return <Component {...props} />; | ||
} | ||
}); | ||
} | ||
} | ||
function getLocaleId(component) { | ||
const locales = component.props.locales || component.context.locales; | ||
if (Array.isArray(locales)) { | ||
return locales[0]; | ||
} | ||
return locales; | ||
} |
@@ -48,3 +48,3 @@ import React from 'react/addons'; | ||
const db = new IntlDomainDatabase({}, loadDomain); | ||
const db = new IntlDomainDatabase(loadDomain); | ||
@@ -86,11 +86,9 @@ const Format = db.makeFormat('main'); | ||
const IntlApp = db.makeIntl(App); | ||
document.addEventListener('DOMContentLoaded', (event) => { | ||
const locale = 'nl-NL'; | ||
React.render( | ||
<IntlApp locales={locale} />, | ||
document.body | ||
); | ||
db.setLocale('nl-NL').then(() => { | ||
React.render( | ||
<App />, | ||
document.body | ||
); | ||
}); | ||
}); |
@@ -7,2 +7,3 @@ import chai from 'chai'; | ||
import ReactIntl from 'react-intl'; | ||
import jsdom from 'jsdom'; | ||
import { IntlDomainDatabase } from '../src/domaindb'; | ||
@@ -12,2 +13,5 @@ | ||
global.document = jsdom.jsdom('<!doctype html><html><body></body></html>'); | ||
global.window = document.parentWindow; | ||
suite('domaindb', function() { | ||
@@ -132,2 +136,17 @@ test("simple load", function() { | ||
}); | ||
test("missing messages for domain", function(done) { | ||
function myloader(localeId, domainId) { | ||
return Promise.resolve({'present': 'PRESENT'}); | ||
} | ||
const db = new IntlDomainDatabase(myloader); | ||
db.defaultMessages({domainId: 'a', | ||
messages: {'missing': 'MISSING'}}); | ||
db.loadMessages('en-US', 'a').then(messages => { | ||
assert.deepEqual(messages, {'present': 'PRESENT', | ||
'missing': 'MISSING'}); | ||
done(); | ||
}); | ||
}); | ||
test("load domains", function(done) { | ||
@@ -143,3 +162,3 @@ let loads = {'a': 0, 'b': 0}; | ||
db.neededDomainIds.add('b'); | ||
db.loadDomains('en-US').then(() => { | ||
db.setLocale('en-US').then(() => { | ||
assert.equal(loads.a, 1); | ||
@@ -157,3 +176,4 @@ assert.equal(loads.b, 1); | ||
const Format = React.createFactory(db.makeFormat('a')); | ||
const formatted = Format({'messageId': 'foo', 'locales': 'en-US'}); | ||
db.setLocale('en-US'); | ||
const formatted = Format({'messageId': 'foo'}); | ||
renderer.render(formatted); | ||
@@ -165,3 +185,3 @@ const output = renderer.getRenderOutput(); | ||
{'message': 'bar', | ||
'locales': 'en-US'})); | ||
'locales': 'en-US'})); | ||
}); | ||
@@ -177,5 +197,4 @@ | ||
const Element = React.createClass({ | ||
mixins: [ReactIntl.IntlMixin], | ||
render() { | ||
return formatStr(this, 'foo'); | ||
return formatStr('foo'); | ||
} | ||
@@ -185,3 +204,4 @@ }); | ||
const ElementFactory = React.createFactory(Element); | ||
const formatted = ElementFactory({'locales': 'en-US'}); | ||
db.setLocale('en-US'); | ||
const formatted = ElementFactory(); | ||
renderer.render(formatted); | ||
@@ -216,6 +236,7 @@ const output = renderer.getRenderOutput(); | ||
const Format = React.createFactory(db.makeFormat('a')); | ||
const formatted = Format({'messageId': 'hello', 'locales': 'en-US'}); | ||
const formatted2 = Format({'messageId': 'hello', 'locales': 'nl-NL'}); | ||
const formatted = Format({'messageId': 'hello'}); | ||
const formatted2 = Format({'messageId': 'hello'}); | ||
db.loadDomains('en-US').then(() => { | ||
db.setLocale('en-US').then(() => { | ||
db.setLocale('en-US'); | ||
renderer.render(formatted); | ||
@@ -230,3 +251,4 @@ const output = renderer.getRenderOutput(); | ||
db.clearMessages(); | ||
db.loadDomains('nl-NL').then(() => { | ||
db.setLocale('nl-NL').then(() => { | ||
db.setLocale('nl-NL'); | ||
renderer.render(formatted2); | ||
@@ -238,3 +260,3 @@ const output = renderer.getRenderOutput(); | ||
{'message': 'Hallo wereld!', | ||
'locales': 'nl-NL'})); | ||
'locales': 'nl-NL'})); | ||
done(); | ||
@@ -245,5 +267,32 @@ }); | ||
}); | ||
// FIXME: unfortunately writing a test for makeIntl is insanely difficult | ||
// due to setState not actually calling the callback. | ||
test("Format date", function() { | ||
const db = new IntlDomainDatabase(); | ||
db.defaultMessages({ | ||
domainId: 'a', | ||
messages: {'foo': 'From {start, date, long}'}}); | ||
const Format = React.createFactory(db.makeFormat('a')); | ||
db.setLocale('en-US'); | ||
const formatted = Format({'messageId': 'foo', | ||
start: new Date('2003-12-24')}); | ||
React.render(formatted, document.body); | ||
assert.equal(document.body.textContent, 'From December 24, 2003'); | ||
}); | ||
test("formatStr date", function() { | ||
const db = new IntlDomainDatabase(); | ||
db.defaultMessages({ | ||
domainId: 'a', | ||
messages: {'foo': 'From {start, date, long}'}}); | ||
const formatStr = db.makeFormatStr('a'); | ||
const Element = React.createClass({ | ||
render() { | ||
return React.createElement( | ||
'span', null, | ||
formatStr('foo', {'start': new Date('2003-12-24')})); | ||
} | ||
}); | ||
const ElementFactory = React.createFactory(Element); | ||
db.setLocale('en-US'); | ||
React.render(ElementFactory(), document.body); | ||
assert.equal(document.body.textContent, 'From December 24, 2003'); | ||
}); | ||
}); |
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
137
24962
7
14
510
1