Skip to content

Commit fd693d6

Browse files
committed
Messages: Support React elements in the message (empty tags)
1 parent 33e27d8 commit fd693d6

File tree

1 file changed

+66
-0
lines changed

1 file changed

+66
-0
lines changed

src/message.js

+66
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,69 @@ function messageSetup(componentProps, instance, args) {
7171

7272
}
7373

74+
function replaceElements(componentProps, formatted) {
75+
var elements = componentProps.elements;
76+
77+
function _replaceElements(string, elements) {
78+
if (typeof string !== "string") {
79+
throw new Error("missing or invalid string `" + string + "` (" + typeof string + ")");
80+
}
81+
if (typeof elements !== "object") {
82+
throw new Error("missing or invalid elements `" + elements + "` (" + typeof elements + ")");
83+
}
84+
85+
// Given [x, y, z], it returns [x, element, y, element, z].
86+
function spreadElementsInBetweenItems(array, element) {
87+
var getElement = typeof element === "function" ? element : function() {
88+
return element;
89+
};
90+
return array.slice(1).reduce(function(ret, item, i) {
91+
ret.push(getElement(i), item);
92+
return ret;
93+
}, [array[0]]);
94+
}
95+
96+
function splice(sourceArray, start, deleteCount, itemsArray) {
97+
[].splice.apply(sourceArray, [start, deleteCount].concat(itemsArray));
98+
}
99+
100+
return Object.keys(elements).reduce(function(ret, key) {
101+
var element = elements[key];
102+
103+
ret.forEach(function(string, i) {
104+
var aux;
105+
106+
// Insert array into the correct ret position.
107+
function replaceRetItem(array) {
108+
splice(ret, i, 1, array);
109+
}
110+
111+
if (typeof string !== "string") {
112+
return; // continue;
113+
}
114+
115+
// Empty tags, e.g., `[foo/]`.
116+
aux = string.split("[" + key + "/]");
117+
if (aux.length > 1) {
118+
aux = spreadElementsInBetweenItems(aux, element);
119+
replaceRetItem(aux);
120+
return; // continue;
121+
}
122+
});
123+
124+
return ret;
125+
}, [string]);
126+
}
127+
128+
129+
// Elements replacement.
130+
if (elements) {
131+
formatted = React.DOM.span.apply(React.DOM.span, [{}].concat(_replaceElements(formatted, elements)));
132+
}
133+
134+
return formatted;
135+
}
136+
74137
function sanitizePath(pathString) {
75138
return pathString.trim().replace(/\{/g, "(").replace(/\}/g, ")").replace(/\//g, "|").replace(/\n/g, " ").replace(/ +/g, " ").replace(/"/g, "'");
76139
}
@@ -93,5 +156,8 @@ Globalize.prototype.messageFormatter = function(pathOrMessage) {
93156
export default React.createClass(generator("formatMessage", ["path", "variables"], {
94157
beforeFormat: function() {
95158
messageSetup(this.props, this.instance, this.args);
159+
},
160+
afterFormat: function(formattedValue) {
161+
return replaceElements(this.props, formattedValue);
96162
}
97163
}));

0 commit comments

Comments
 (0)