Skip to content

Instantly share code, notes, and snippets.

@SlexAxton
Last active December 20, 2015 03:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SlexAxton/6066075 to your computer and use it in GitHub Desktop.
Save SlexAxton/6066075 to your computer and use it in GitHub Desktop.
A messageformat require plugin
{
"error_message_required" : {
"message" : "Required",
"contentType" : null,
"description" : "This is a message displayed to a user that inputs are required.",
"variables" : [],
"photos" : []
},
"error_message_minlength" : {
"message" : "{number, plural, one { # character too short } other { # characters too short } }",
"contentType" : null,
"description" : "This is a message displayed to a user that inputs are too short.",
"variables" : [
{
"name" : "number",
"type" : "plural",
"description": "This is the number of characters that are shorter than required."
}
],
"photos" : []
},
"error_message_mmaxlength" : {
"message" : "{number, plural, one { # character too long } other { # characters too long } }",
"contentType" : null,
"description" : "This is a message displayed to a user that inputs are too long.",
"variables" : [
{
"name" : "number",
"type" : "plural",
"description": "This is the number of characters that are longer than required."
}
],
"photos" : []
}
}
define([
//>>excludeStart('excludeDev', pragmas.excludeDev)
'underscore', 'messageformat', 'json2'
//>>excludeEnd('excludeDev')
],
function (
//>>excludeStart('excludeDev', pragmas.excludeDev)
_, MessageFormat, JSON
//>>excludeEnd('excludeDev')
) {
//>>excludeStart('excludeDev', pragmas.excludeDev)
var fs;
var getXhr;
var progIds = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0'];
var fetchText = function () {
throw new Error('Environment unsupported.');
};
var customNameExtension = "@mf";
var fileExtension = ".mf.json";
var buildMap = {};
var cache = {};
var fetchOrGetCached;
if (typeof window !== "undefined" && window.navigator && window.document) {
// Browser action
getXhr = function () {
//Would love to dump the ActiveX crap in here. Need IE 6 to die first.
var xhr;
var i;
var progId;
if (typeof XMLHttpRequest !== "undefined") {
return new XMLHttpRequest();
}
else {
for (i = 0; i < 3; i++) {
progId = progIds[i];
try {
xhr = new ActiveXObject(progId);
}
catch (e) {}
if (xhr) {
progIds = [progId]; // so faster next time
break;
}
}
}
if (!xhr) {
throw new Error("getXhr(): XMLHttpRequest not available");
}
return xhr;
};
fetchText = function (url, callback) {
var xhr = getXhr();
if ( ! ~url.indexOf('http') ) {
url = window.location.protocol + url;
}
xhr.open('GET', url, true);
xhr.onreadystatechange = function (evt) {
if (xhr.readyState === 4 ) {
if ( xhr.status === 200) {
callback(xhr.responseText);
}
else if (require.onError) {
require.onError({
"hbs" : true,
"status" : xhr.status,
"url" : url
});
}
}
};
xhr.send(null);
};
}
else if (typeof process !== "undefined" && process.versions && !!process.versions.node) {
//Using special require.nodeRequire, something added by r.js.
fs = require.nodeRequire('fs');
fetchText = function (path, callback) {
callback(fs.readFileSync(path, 'utf8'));
};
}
fetchOrGetCached = function (name, parentRequire, config, callback) {
if (config.turbo) {
require(['mfMap'], function (map) {
callback(map[name]);
});
return;
}
var path = parentRequire.toUrl(name + fileExtension);
if (cache[path]){
callback(cache[path]);
}
else {
fetchText(path, function (data) {
cache[path] = data;
callback.call(this, data);
});
}
};
//>>excludeEnd('excludeDev')
return {
load : function (name, parentRequire, load, config) {
//>>excludeStart('excludeDev', pragmas.excludeDev)
// TODO :: actually take locale arguments
var mf = new MessageFormat();
// No collisions this way
var compiledName = name + customNameExtension;
var defaultTs = {};
fetchOrGetCached(name, parentRequire, config, function (rawMf) {
var messages = JSON.parse(rawMf);
var compiledPairs = [];
_(messages).forEach(function (msg, key) {
// Handle individual overrides
if (config.localeMapping && config.localeMapping[key]) {
msg = config.localeMapping[key];
}
else if (defaultTs[key]) {
msg = defaultTs[key];
}
else {
msg = msg.message;
}
// Just precompile here
var precompileFunc;
try {
precompileFunc = mf.precompile( mf.parse(msg) );
}
catch (e) {
precompileFunc = 'function () { throw ' + JSON.stringify( e.toString() ) + '; }';
}
var precompileFuncStr = 'function (x) { try { return (' + precompileFunc + ')(x||{}); } catch(e){ /*SomeErrorTracker.error(new Error(\'MF error on `' + key + '`: \' + e.toString()));*/ return ""; } }';
compiledPairs.push('"' + key.replace(/"/g, '\"') + '" : ' + precompileFuncStr);
});
// Create the module as a string
var text = "define(['messageformat'], function (MessageFormat) { \n" +
" return {\n" + compiledPairs.join(',') + "\n};\n" +
"});\n";
buildMap[compiledName] = text;
load.fromText(text);
//Give result to load. Need to wait until the module
//is fully parse, which will happen after this
//execution.
parentRequire([name], function (value) {
load(value);
});
});
//>>excludeEnd('excludeDev')
},
write : function (pluginName, moduleName, write) {
//>>excludeStart('excludeDev', pragmas.excludeDev)
if ((moduleName + customNameExtension) in buildMap) {
var text = buildMap[moduleName + customNameExtension];
write.asModule(pluginName + "!" + moduleName, text);
}
//>>excludeEnd('excludeDev')
}
};
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment