Skip to content

Commit a02f6d1

Browse files
committed
Build
1 parent 27e6314 commit a02f6d1

File tree

13 files changed

+586
-0
lines changed

13 files changed

+586
-0
lines changed

dist/amd/currency.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
define(['react', './generator', 'globalize/currency'], function (React, generator) {
2+
3+
'use strict';
4+
5+
return generator("formatCurrency", ["value", "currency", "options"]);
6+
7+
});

dist/amd/date.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
define(['react', './generator', 'globalize/date'], function (React, generator) {
2+
3+
'use strict';
4+
5+
return generator("formatDate", ["value", "options"]);
6+
7+
});

dist/amd/generator.js

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
define(['react', 'globalize'], function (React, Globalize) {
2+
3+
'use strict';
4+
5+
var commonPropNames = ["elements", "locale"];
6+
7+
function capitalizeFirstLetter(string) {
8+
return string.charAt(0).toUpperCase() + string.slice(1);
9+
}
10+
11+
function omit(set) {
12+
return function(element) {
13+
return set.indexOf(element) === -1;
14+
};
15+
}
16+
17+
function generator(fn, localPropNames, options) {
18+
options = options || {};
19+
var Fn = capitalizeFirstLetter(fn);
20+
var beforeFormat = options.beforeFormat || function() {};
21+
var afterFormat = options.afterFormat || function(formattedValue) {
22+
return formattedValue;
23+
};
24+
var globalizePropNames = commonPropNames.concat(localPropNames);
25+
26+
return React.createClass({
27+
displayName: Fn,
28+
componentWillMount: function() {
29+
this.setup(this.props);
30+
},
31+
componentWillReceiveProps: function(nextProps) {
32+
this.setup(nextProps);
33+
},
34+
setup: function(props) {
35+
this.globalize = props.locale ? Globalize(props.locale) : Globalize;
36+
this.domProps = Object.keys(props).filter(omit(globalizePropNames)).reduce(function(memo, propKey) {
37+
memo[propKey] = props[propKey];
38+
return memo;
39+
}, {});
40+
41+
this.globalizePropValues = localPropNames.map(function(element) {
42+
return props[element];
43+
});
44+
this.globalizePropValues[0] = props.children;
45+
46+
beforeFormat.call(this);
47+
var formattedValue = this.globalize[fn].apply(this.globalize, this.globalizePropValues);
48+
this.value = afterFormat.call(this, formattedValue);
49+
},
50+
render: function() {
51+
return React.DOM.span(this.domProps, this.value);
52+
}
53+
});
54+
}
55+
56+
57+
return generator;
58+
59+
});

dist/amd/message.js

Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
define(['globalize', 'react', './generator', 'globalize/message', 'globalize/plural'], function (Globalize, React, generator) {
2+
3+
'use strict';
4+
5+
function messageSetup(globalize, props, globalizePropValues) {
6+
var defaultMessage;
7+
var children = props.children;
8+
var scope = props.scope;
9+
10+
function getDefaultMessage(children) {
11+
if (typeof children === "string") {
12+
return children;
13+
} else {
14+
throw new Error("Invalid default message type `" + typeof children + "`");
15+
}
16+
}
17+
18+
// Set path - path as props supercedes default value.
19+
if (props.path) {
20+
// Override generator assumption. The generator assumes the globalizePropValues[0]
21+
// (path) and props.children to be mutually exclusive, but this isn't
22+
// true here for messages. Because, it's possible to use props.path (for
23+
// path) and props.children for defaultMessage, which are two different
24+
// variables.
25+
globalizePropValues[0] = props.path;
26+
} else {
27+
// Although the generator had already set globalizePropValues[0] (path) as
28+
// props.children, here its type is checked and its value is sanitized.
29+
defaultMessage = getDefaultMessage(children);
30+
globalizePropValues[0] = sanitizePath(defaultMessage);
31+
}
32+
33+
// Scope path.
34+
if (scope) {
35+
globalizePropValues[0] = scope + "/" + globalizePropValues[0];
36+
}
37+
38+
// Development mode only.
39+
if (process.env.NODE_ENV !== "production") {
40+
var path = props.path ? props.path.split("/") : [globalizePropValues[0]];
41+
/* eslint-disable no-inner-declarations */
42+
function getMessage(globalize, path) {
43+
return globalize.cldr.get(["globalize-messages/{bundle}"].concat(path));
44+
}
45+
46+
function setMessage(globalize, path, message) {
47+
var data = {};
48+
function set(data, path, value) {
49+
var i;
50+
var node = data;
51+
var length = path.length;
52+
53+
for (i = 0; i < length - 1; i++) {
54+
if (!node[path[i]]) {
55+
node[path[i]] = {};
56+
}
57+
node = node[path[i]];
58+
}
59+
node[path[i]] = value;
60+
}
61+
set(data, [globalize.cldr.attributes.bundle].concat(path), message);
62+
Globalize.loadMessages(data);
63+
}
64+
/* eslint-enable no-inner-declarations */
65+
66+
if (globalize.cldr) {
67+
if (!getMessage(globalize, path)) {
68+
defaultMessage = defaultMessage || getDefaultMessage(children);
69+
setMessage(globalize, path, defaultMessage);
70+
}
71+
}
72+
}
73+
}
74+
75+
function replaceElements(props, formatted) {
76+
var elements = props.elements;
77+
78+
function _replaceElements(string, elements) {
79+
if (typeof string !== "string") {
80+
throw new Error("Missing or invalid string `" + string + "` (" + typeof string + ")");
81+
}
82+
if (typeof elements !== "object") {
83+
throw new Error("Missing or invalid elements `" + elements + "` (" + typeof elements + ")");
84+
}
85+
86+
// Given [x, y, z], it returns [x, element, y, element, z].
87+
function spreadElementsInBetweenItems(array, element) {
88+
var getElement = typeof element === "function" ? element : function() {
89+
return element;
90+
};
91+
return array.slice(1).reduce(function(ret, item, i) {
92+
ret.push(getElement(i), item);
93+
return ret;
94+
}, [array[0]]);
95+
}
96+
97+
function splice(sourceArray, start, deleteCount, itemsArray) {
98+
[].splice.apply(sourceArray, [start, deleteCount].concat(itemsArray));
99+
}
100+
101+
return Object.keys(elements).reduce(function(ret, key) {
102+
var element = elements[key];
103+
104+
ret.forEach(function(string, i) {
105+
var aux, contents, regexp, regexp2;
106+
107+
// Insert array into the correct ret position.
108+
function replaceRetItem(array) {
109+
splice(ret, i, 1, array);
110+
}
111+
112+
if (typeof string !== "string") {
113+
return; // continue;
114+
}
115+
116+
// Empty tags, e.g., `[foo/]`.
117+
aux = string.split("[" + key + "/]");
118+
if (aux.length > 1) {
119+
aux = spreadElementsInBetweenItems(aux, element);
120+
replaceRetItem(aux);
121+
return; // continue;
122+
}
123+
124+
// Start-end tags, e.g., `[foo]content[/foo]`.
125+
regexp = new RegExp("\\[" + key + "\\][\\s\\S]*?\\[\\/" + key + "\\]", "g");
126+
regexp2 = new RegExp("\\[" + key + "\\]([\\s\\S]*?)\\[\\/" + key + "\\]");
127+
aux = string.split(regexp);
128+
if (aux.length > 1) {
129+
contents = string.match(regexp).map(function(content) {
130+
return content.replace(regexp2, "$1");
131+
});
132+
aux = spreadElementsInBetweenItems(aux, function(i) {
133+
return React.cloneElement(element, {}, contents[i]);
134+
});
135+
replaceRetItem(aux);
136+
}
137+
});
138+
139+
return ret;
140+
}, [string]);
141+
}
142+
143+
144+
// Elements replacement.
145+
if (elements) {
146+
formatted = React.DOM.span.apply(React.DOM.span, [{}].concat(_replaceElements(formatted, elements)));
147+
}
148+
149+
return formatted;
150+
}
151+
152+
function sanitizePath(pathString) {
153+
return pathString.trim().replace(/\{/g, "(").replace(/\}/g, ")").replace(/\//g, "|").replace(/\n/g, " ").replace(/ +/g, " ").replace(/"/g, "'");
154+
}
155+
156+
// Overload Globalize's `.formatMessage` to allow default message.
157+
var globalizeMessageFormatter = Globalize.messageFormatter;
158+
Globalize.messageFormatter = Globalize.prototype.messageFormatter = function(pathOrMessage) {
159+
var aux = {};
160+
var sanitizedPath = sanitizePath(pathOrMessage);
161+
162+
// Globalize runtime
163+
if (!this.cldr) {
164+
// On runtime, the only way for deciding between using sanitizedPath or
165+
// pathOrMessage as path is by checking which formatter exists.
166+
arguments[0] = sanitizedPath;
167+
aux = globalizeMessageFormatter.apply(this, arguments);
168+
arguments[0] = pathOrMessage;
169+
return aux || globalizeMessageFormatter.apply(this, arguments);
170+
}
171+
172+
var sanitizedPathExists = this.cldr.get(["globalize-messages/{bundle}", sanitizedPath]) !== undefined;
173+
var pathExists = this.cldr.get(["globalize-messages/{bundle}", pathOrMessage]) !== undefined;
174+
175+
// Want to distinguish between default message and path value - just checking
176+
// for sanitizedPath won't be enough, because sanitizedPath !== pathOrMessage
177+
// for paths like "salutations/hi".
178+
if (!sanitizedPathExists && !pathExists) {
179+
aux[this.cldr.attributes.bundle] = {};
180+
aux[this.cldr.attributes.bundle][sanitizedPath] = pathOrMessage;
181+
Globalize.loadMessages(aux);
182+
sanitizedPathExists = true;
183+
}
184+
185+
arguments[0] = sanitizedPathExists ? sanitizedPath : pathOrMessage;
186+
return globalizeMessageFormatter.apply(this, arguments);
187+
};
188+
189+
190+
return generator("formatMessage", ["path", "variables"], {
191+
beforeFormat: function() {
192+
messageSetup(this.globalize, this.props, this.globalizePropValues);
193+
},
194+
afterFormat: function(formattedValue) {
195+
return replaceElements(this.props, formattedValue);
196+
}
197+
});
198+
199+
});

dist/amd/number.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
define(['react', './generator', 'globalize/number'], function (React, generator) {
2+
3+
'use strict';
4+
5+
return generator("formatNumber", ["value", "options"]);
6+
7+
});

dist/amd/relative-time.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
define(['react', './generator', 'globalize/relative-time'], function (React, generator) {
2+
3+
'use strict';
4+
5+
return generator("formatRelativeTime", ["value", "unit", "options"]);
6+
7+
});

dist/currency.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
'use strict';
2+
3+
var React = require('react');
4+
var generator = require('./generator');
5+
6+
7+
module.exports = generator("formatCurrency", ["value", "currency", "options"]);

dist/date.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
'use strict';
2+
3+
var React = require('react');
4+
var generator = require('./generator');
5+
6+
7+
module.exports = generator("formatDate", ["value", "options"]);

dist/generator.js

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
'use strict';
2+
3+
var React = require('react');
4+
var Globalize = require('globalize');
5+
6+
var commonPropNames = ["elements", "locale"];
7+
8+
function capitalizeFirstLetter(string) {
9+
return string.charAt(0).toUpperCase() + string.slice(1);
10+
}
11+
12+
function omit(set) {
13+
return function(element) {
14+
return set.indexOf(element) === -1;
15+
};
16+
}
17+
18+
function generator(fn, localPropNames, options) {
19+
options = options || {};
20+
var Fn = capitalizeFirstLetter(fn);
21+
var beforeFormat = options.beforeFormat || function() {};
22+
var afterFormat = options.afterFormat || function(formattedValue) {
23+
return formattedValue;
24+
};
25+
var globalizePropNames = commonPropNames.concat(localPropNames);
26+
27+
return React.createClass({
28+
displayName: Fn,
29+
componentWillMount: function() {
30+
this.setup(this.props);
31+
},
32+
componentWillReceiveProps: function(nextProps) {
33+
this.setup(nextProps);
34+
},
35+
setup: function(props) {
36+
this.globalize = props.locale ? Globalize(props.locale) : Globalize;
37+
this.domProps = Object.keys(props).filter(omit(globalizePropNames)).reduce(function(memo, propKey) {
38+
memo[propKey] = props[propKey];
39+
return memo;
40+
}, {});
41+
42+
this.globalizePropValues = localPropNames.map(function(element) {
43+
return props[element];
44+
});
45+
this.globalizePropValues[0] = props.children;
46+
47+
beforeFormat.call(this);
48+
var formattedValue = this.globalize[fn].apply(this.globalize, this.globalizePropValues);
49+
this.value = afterFormat.call(this, formattedValue);
50+
},
51+
render: function() {
52+
return React.DOM.span(this.domProps, this.value);
53+
}
54+
});
55+
}
56+
57+
module.exports = generator;

dist/index.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
'use strict';
2+
3+
var FormatCurrency = require('./currency');
4+
var FormatDate = require('./date');
5+
var FormatMessage = require('./message');
6+
var FormatNumber = require('./number');
7+
var FormatRelativeTime = require('./relative-time');
8+
9+
module.exports = {
10+
FormatCurrency: FormatCurrency,
11+
FormatDate: FormatDate,
12+
FormatMessage: FormatMessage,
13+
FormatNumber: FormatNumber,
14+
FormatRelativeTime: FormatRelativeTime
15+
};

0 commit comments

Comments
 (0)