Files
fullcalendar/build/tasks/generateLanguages.js
T
2014-07-25 16:23:04 +01:00

210 lines
4.8 KiB
JavaScript

var pathLib = require('path');
module.exports = function(grunt) {
var config = grunt.config('generateLanguages');
grunt.registerTask('generateLanguages', function() {
var combinedJS = '';
var languageCnt = 0;
var skippedLangCodes = [];
grunt.file.mkdir(config.dest, 0755);
grunt.file.expand(pathLib.join(config.moment, '*.js')).forEach(function(momentPath) {
var langCode = momentPath.match(/([^\/]*)\.js$/)[1];
var js = getLangJS(langCode, momentPath);
if (js) {
grunt.file.write(
pathLib.join(config.dest, langCode + '.js'),
wrapWithUMD(js)
);
combinedJS += wrapWithClosure(js) + '\n';
languageCnt++;
}
else {
skippedLangCodes.push(langCode);
}
});
// code for resetting the language back to English
combinedJS += '\nmoment.lang("en");';
combinedJS += '\n$.fullCalendar.lang("en");';
combinedJS += '\nif ($.datepicker) $.datepicker.setDefaults($.datepicker.regional[""]);';
if (config.allDest) {
grunt.file.write(config.allDest, wrapWithUMD(combinedJS));
}
grunt.log.writeln(skippedLangCodes.length + ' skipped languages: ' + skippedLangCodes.join(', '));
grunt.log.writeln(languageCnt + ' generated languages.');
});
function getLangJS(langCode, momentPath) {
var shortLangCode;
var momentLangJS;
var datepickerLangJS;
var fullCalendarLangJS;
// given "fr-ca", get just "fr"
if (langCode.indexOf('-') != -1) {
shortLangCode = langCode.replace(/-.*/, '');
}
momentLangJS = getMomentLangJS(momentPath);
datepickerLangJS = getDatepickerLangJS(langCode);
if (!datepickerLangJS && shortLangCode) {
datepickerLangJS = getDatepickerLangJS(shortLangCode, langCode);
}
fullCalendarLangJS = getFullCalendarLangJS(langCode);
if (!fullCalendarLangJS && shortLangCode) {
fullCalendarLangJS = getFullCalendarLangJS(shortLangCode, langCode);
}
// If this is an "en" language, only the Moment config is needed.
// For all other languages, all 3 configs are needed.
if (momentLangJS && (shortLangCode == 'en' || (datepickerLangJS && fullCalendarLangJS))) {
// if there is no definition, we still need to tell FC to set the default
if (!fullCalendarLangJS) {
fullCalendarLangJS = '$.fullCalendar.lang("' + langCode + '");';
}
datepickerLangJS = datepickerLangJS || '';
return momentLangJS + '\n' +
datepickerLangJS + '\n' +
fullCalendarLangJS;
}
}
function wrapWithUMD(body) {
return [
'(function(factory) {',
' if (typeof define === "function" && define.amd) {',
' define([ "jquery", "moment" ], factory);',
' }',
' else {',
' factory(jQuery, moment);',
' }',
'})(function($, moment) {',
'',
body,
'',
'});'
].join('\n');
}
function wrapWithClosure(body) {
return [
'(function() {',
'',
body,
'',
'})();'
].join('\n');
}
function getMomentLangJS(path) { // file assumed to exist
var js = grunt.file.read(path);
js = js.replace( // remove the UMD wrap
/\(\s*function[\S\s]*?function\s*\(\s*moment\s*\)\s*\{([\S\s]*)\}\)\);?/,
function(m0, body) {
body = body.replace(/^ /mg, ''); // remove 1 level of indentation
return body;
}
);
js = js.replace( // replace the `return` statement so execution continues
/^(\s*)return moment\.lang\(/m,
'$1moment.lang('
);
return js;
}
function getDatepickerLangJS(langCode, targetLangCode) {
// convert "en-ca" to "en-CA"
var datepickerLangCode = langCode.replace(/\-(\w+)/, function(m0, m1) {
return '-' + m1.toUpperCase();
});
var path = pathLib.join(config.datepicker, 'jquery.ui.datepicker-' + datepickerLangCode + '.js');
var js;
try {
js = grunt.file.read(path);
}
catch (ex) {
return false;
}
js = js.replace(
/^jQuery\([\S\s]*?\{([\S\s]*)\}\);?/m, // inside the jQuery(function) wrap,
function(m0, body) { // use only the function body, modified.
var match = body.match(/\$\.datepicker\.regional[\S\s]*?(\{[\S\s]*?\});?/);
var props = match[1];
// remove 1 level of tab indentation
props = props.replace(/^\t/mg, '');
return "$.fullCalendar.datepickerLang(" +
"'" + (targetLangCode || langCode) + "', " + // for FullCalendar
"'" + datepickerLangCode + "', " + // for datepicker
props +
");";
}
);
return js;
}
function getFullCalendarLangJS(langCode, targetLangCode) {
var path = pathLib.join(config.fullCalendar, langCode + '.js');
var js;
try {
js = grunt.file.read(path);
}
catch (ex) {
return false;
}
// if we originally wanted "ar-ma", but only "ar" is available, we have to adjust
// the declaration
if (targetLangCode && targetLangCode != langCode) {
js = js.replace(
/\$\.fullCalendar\.lang\(['"]([^'"]*)['"]/,
'$.fullCalendar.lang("' + targetLangCode + '"'
);
}
return js;
}
};