Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Use stricter JSHint rules and fix errors related to those

  • Loading branch information...
commit 0034235516db253fa8166b52f5a986c501e7e1a3 1 parent 1021dc2
@BYK BYK authored
View
3  .jshintignore
@@ -0,0 +1,3 @@
+.idea/
+node_modules/
+tests/inputs
View
23 .jshintrc
@@ -0,0 +1,23 @@
+{
+ "node": true,
+ "strict": true,
+
+ "undef": true,
+ "unused": true,
+ "eqnull": true,
+ "white": true,
+ "eqeqeq": true,
+ "bitwise": true,
+ "indent": 2,
+ "newcap": true,
+ "trailing": true,
+ "immed": true,
+ "freeze": true,
+ "latedef": true,
+ "noarg": true,
+ "noempty": true,
+ "nonew": true,
+
+ "-W092": true,
+ "-W107": true
+}
View
130 lib/cli.js
@@ -1,54 +1,76 @@
#!/usr/bin/env node
+"use strict";
+
var fs = require('fs');
var path = require('path');
var jsxgettext = require('./jsxgettext');
var opts = require("nomnom")
- .script('jsxgettext')
- .option('output', {
- abbr: 'o',
- metavar: 'FILE',
- default: 'messages.po',
- help: 'write output to specified file'
- })
- .option('output-dir', {
- abbr: 'p',
- metavar: 'DIR',
- help: 'output files will be placed in directory DIR'
- })
- .option('version', {
- abbr: 'v',
- flag: true,
- help: 'print version and exit',
- callback: function() {
- return require('../package.json').version;
- }
- })
- .option('input', {
- position: 0,
- required: true,
- list: true,
- help: 'input files'
- })
- .option('keyword', {
- abbr: 'k',
- metavar: 'WORD',
- help: 'additional keyword to be looked for'
- })
- .option('join-existing', {
- abbr: 'j',
- flag: true,
- help: 'join messages with existing file'
- })
- .option('language', {
- abbr: 'L',
- metavar: 'NAME',
- default: 'JavaScript',
- help: 'recognise the specified language (JavaScript, EJS, Jinja, Jade, Handlebars)'
- })
- .parse();
+ .script('jsxgettext')
+ .option('output', {
+ abbr: 'o',
+ metavar: 'FILE',
+ default: 'messages.po',
+ help: 'write output to specified file'
+ })
+ .option('output-dir', {
+ abbr: 'p',
+ metavar: 'DIR',
+ help: 'output files will be placed in directory DIR'
+ })
+ .option('version', {
+ abbr: 'v',
+ flag: true,
+ help: 'print version and exit',
+ callback: function () {
+ return require('../package.json').version;
+ }
+ })
+ .option('input', {
+ position: 0,
+ required: true,
+ list: true,
+ help: 'input files'
+ })
+ .option('keyword', {
+ abbr: 'k',
+ metavar: 'WORD',
+ help: 'additional keyword to be looked for'
+ })
+ .option('join-existing', {
+ abbr: 'j',
+ flag: true,
+ help: 'join messages with existing file'
+ })
+ .option('language', {
+ abbr: 'L',
+ metavar: 'NAME',
+ default: 'JavaScript',
+ help: 'recognise the specified language (JavaScript, EJS, Jinja, Jade, Handlebars)'
+ })
+ .parse();
+
+function gen(sources) {
+ var result;
+ if (opts.language.toUpperCase() === 'EJS') {
+ result = jsxgettext.generateFromEJS(sources, opts);
+ } else if (opts.language.toUpperCase() === 'JINJA') {
+ result = jsxgettext.generateFromJinja(sources, opts);
+ } else if (opts.language.toUpperCase() === 'JADE') {
+ result = jsxgettext.generateFromJade(sources, opts);
+ } else if (opts.language.toUpperCase() === 'HANDLEBARS') {
+ result = jsxgettext.generateFromHandlebars(sources, opts);
+ } else {
+ result = jsxgettext.generate(sources, opts);
+ }
+ if (opts.output === '-') {
+ console.log(result);
+ } else {
+ fs.writeFileSync(path.resolve(path.join(opts['output-dir'] || '', opts.output)), result, "utf8");
+ }
+}
-function main () {
+function main() {
var files = opts.input;
var sources = {};
@@ -70,24 +92,4 @@ function main () {
}
}
-function gen (sources) {
- var result;
- if (opts.language.toUpperCase() === 'EJS') {
- result = jsxgettext.generateFromEJS(sources, opts);
- } else if (opts.language.toUpperCase() === 'JINJA') {
- result = jsxgettext.generateFromJinja(sources, opts);
- } else if (opts.language.toUpperCase() === 'JADE') {
- result = jsxgettext.generateFromJade(sources, opts);
- } else if (opts.language.toUpperCase() === 'HANDLEBARS') {
- result = jsxgettext.generateFromHandlebars(sources, opts);
- } else {
- result = jsxgettext.generate(sources, opts);
- }
- if (opts.output === '-') {
- console.log(result);
- } else {
- fs.writeFileSync(path.resolve(path.join(opts['output-dir'] || '', opts.output)), result, "utf8");
- }
-}
-
main();
View
137 lib/jsxgettext.js
@@ -1,5 +1,4 @@
-/* jshint node: true, undef: true */
-/* global module, require */
+/* global require */
"use strict";
/* This Source Code Form is subject to the terms of the Mozilla Public
@@ -65,8 +64,16 @@ function extractStr(node) {
return extractStr(node.left) + extractStr(node.right);
}
+function loadStrings(poFile) {
+ try {
+ return gettextParser.po.parse(fs.readFileSync(path.resolve(poFile)), "utf-8");
+ } catch (e) {
+ return null;
+ }
+}
+
// generate extracted strings file
-function gen (sources, options) {
+function gen(sources, options) {
var poJSON;
if (options['join-existing'])
poJSON = loadStrings(path.resolve(path.join(options['output-dir'] || '', options.output)));
@@ -95,7 +102,7 @@ function gen (sources, options) {
var source = sources[filename].replace(/^#.*/, ''); // strip leading hash-bang
var astComments = [];
var ast = parser.parse(source, {
- onComment: function (block, text, start, end, line, column) {
+ onComment: function (block, text, start, end, line/*, column*/) {
text = text.replace(/^\s*L10n:/, '');
if (!text)
@@ -110,10 +117,10 @@ function gen (sources, options) {
});
// finds comments that end on the previous line
- function findComments (comments, line) {
+ function findComments(comments, line) {
return comments.map(function (node) {
var commentLine = node.line;
- if (commentLine == line || commentLine + 1 == line) {
+ if (commentLine === line || commentLine + 1 === line) {
return node.value;
}
}).filter(Boolean).join('\n');
@@ -169,60 +176,16 @@ function gen (sources, options) {
return gettextParser.po.compile(poJSON).toString();
}
-// generate extracted strings file from EJS
-function genEJS (ejsSources, options) {
- Object.keys(ejsSources).forEach(function (filename) {
- ejsSources[filename] = parseEJS(ejsSources[filename]);
- });
-
- return gen(ejsSources, options);
-}
-
-// generate extracted strings file from Jade templates
-function genJade (jadeSources, options) {
- Object.keys(jadeSources).forEach(function (filename) {
- jadeSources[filename] = parseJade(jadeSources[filename], options);
- });
- return gen(jadeSources, options);
-}
-
-
-// generate extracted strings file from Handlebars/Mustache templates
-function genHandlebars (hbSources, options) {
- Object.keys(hbSources).forEach(function (filename) {
- hbSources[filename] = parseHandlebars(hbSources[filename]);
- });
- return gen(hbSources, options);
-}
-
-// generate extracted strings file from Jinja2 templates
-function genJinja (jinjaSources, options) {
- Object.keys(jinjaSources).forEach(function (filename) {
- jinjaSources[filename] = parseEJS(jinjaSources[filename], {open: "{{", close: "}}"});
- });
-
- return gen(jinjaSources, options);
-}
-
-function loadStrings (poFile) {
- try {
- return gettextParser.po.parse(fs.readFileSync(path.resolve(poFile)), "utf-8");
- } catch (e) {
- return null;
- }
-}
-
// strips everything but the javascript bits
-function parseEJS (str, options){
+function parseEJS(str, options) {
options = options || {};
var open = options.open || '<%',
close = options.close || '%>';
var buf = [];
- var lineno = 1;
for (var i = 0, len = str.length; i < len; ++i) {
- if (str.slice(i, open.length + i) == open) {
+ if (str.slice(i, open.length + i) === open) {
i += open.length;
switch (str.substr(i, 1)) {
case '=':
@@ -232,36 +195,46 @@ function parseEJS (str, options){
}
var end = str.indexOf(close, i), js = str.substring(i, end), start = i, n = 0;
- if ('-' == js[js.length-1]){
+ if ('-' === js[js.length - 1]) {
js = js.substring(0, js.length - 2);
}
- /* jshint -W030 */
- while (~(n = js.indexOf("\n", n))) n++,buf.push("\n");
- /* jshint +W030 */
+
+ while ((n = js.indexOf("\n", n)) > -1) {
+ n += 1;
+ buf.push("\n");
+ }
+
// skip EJS include statements which are not valid javascript
if (/^\s*include\s*[^\s]+\s*$/.test(js)) js = "";
buf.push(js, ';');
i += end - start + close.length - 1;
- } else if (str.substr(i, 1) == "\n") {
- buf.push("\n");
+ } else if (str.substr(i, 1) === "\n") {
+ buf.push("\n");
}
}
return buf.join('');
}
+// generate extracted strings file from EJS
+function genEJS(ejsSources, options) {
+ Object.keys(ejsSources).forEach(function (filename) {
+ ejsSources[filename] = parseEJS(ejsSources[filename]);
+ });
+
+ return gen(ejsSources, options);
+}
+
// From MDN:
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#Using_Special_Characters
-function escapeRegExp(string){
+function escapeRegExp(string) {
return string.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1");
}
function parseJade(str, options) {
options = options || {};
- var lineno = 1;
-
var parser = new jade.Parser(str);
var lexer = parser.lexer;
var token;
@@ -277,7 +250,7 @@ function parseJade(str, options) {
if (typeof(str) !== 'string') return '';
var tmp = str.match(gettexRegex) || [];
- return tmp.map(function(t) {
+ return tmp.map(function (t) {
return t + ')';
}).join(';');
}
@@ -295,10 +268,11 @@ function parseJade(str, options) {
do {
token = lexer.next();
lineN = token.line - 1;
- switch(token.type) {
+ switch (token.type) {
case 'attrs':
tmp = Object.keys(token.attrs).map(extractFromObj, token.attrs).filter(isEmpty);
- if(tmp.length) buf[lineN] = tmp.join('') + ';';
+ if (tmp.length)
+ buf[lineN] = tmp.join('') + ';';
break;
case 'text':
case 'code':
@@ -306,14 +280,22 @@ function parseJade(str, options) {
if (tmp.length) buf[lineN] = tmp + ';';
break;
}
- } while(token.type != 'eos');
+ } while (token.type !== 'eos');
return buf.join('\n');
}
+// generate extracted strings file from Jade templates
+function genJade(jadeSources, options) {
+ Object.keys(jadeSources).forEach(function (filename) {
+ jadeSources[filename] = parseJade(jadeSources[filename], options);
+ });
+ return gen(jadeSources, options);
+}
+
// Turn handlebars helper calls into javascript-syntax functions.
// Also comment blocks are turned into javascript comments.
-function parseHandlebars(str, options) {
+function parseHandlebars(str/*, options*/) {
// Using regexes for parsing, ooooh yeeeahhh!
// Short comments: {{! this is a comment }}
@@ -372,10 +354,10 @@ function parseHandlebars(str, options) {
str = str.substring(match.index + match[0].length);
// Translate the match into an appropriate chunk of javascript.
- if (match.type == 'comment') {
+ if (match.type === 'comment') {
// Template comment => javascript comment
match[1].split("\n").forEach(addComment);
- } else if (match.type == 'block') {
+ } else if (match.type === 'block') {
// Template block helper => javascript function call
var helperName = match[1];
buf.push(helperName);
@@ -395,7 +377,7 @@ function parseHandlebars(str, options) {
str = '';
}
buf.push('")\n');
- } else if (match.type == 'func') {
+ } else if (match.type === 'func') {
// Template function helper => javascript function call
buf.push(match[1]);
buf.push('(');
@@ -407,6 +389,23 @@ function parseHandlebars(str, options) {
return buf.join('');
}
+// generate extracted strings file from Handlebars/Mustache templates
+function genHandlebars(hbSources, options) {
+ Object.keys(hbSources).forEach(function (filename) {
+ hbSources[filename] = parseHandlebars(hbSources[filename]);
+ });
+ return gen(hbSources, options);
+}
+
+// generate extracted strings file from Jinja2 templates
+function genJinja(jinjaSources, options) {
+ Object.keys(jinjaSources).forEach(function (filename) {
+ jinjaSources[filename] = parseEJS(jinjaSources[filename], {open: "{{", close: "}}"});
+ });
+
+ return gen(jinjaSources, options);
+}
+
exports.generate = gen;
exports.generateFromEJS = genEJS;
exports.generateFromJade = genJade;
View
2  tests/all.js
@@ -15,7 +15,7 @@ exports.testAll['test po_quotes'] = require("./po_quotes");
exports.testAll['test expressions'] = require('./expressions');
exports.testAll['test anonymous_functions'] = require('./anonymous_functions');
-if (module == require.main) {
+if (module === require.main) {
require('test').run(exports);
} else {
console.log("Just a module");
View
4 tests/anonymous_functions.js
@@ -1,3 +1,5 @@
+"use strict";
+
var
fs = require('fs'),
jsxgettext = require('../lib/jsxgettext'),
@@ -21,4 +23,4 @@ exports['test anonymous functions and method calls'] = function (assert, cb) {
});
};
-if (module == require.main) require('test').run(exports);
+if (module === require.main) require('test').run(exports);
View
4 tests/creation_date.js
@@ -1,3 +1,5 @@
+"use strict";
+
var
jsxgettext = require('../lib/jsxgettext'),
gettextParser = require('gettext-parser');
@@ -17,4 +19,4 @@ exports['test creation date'] = function (assert, cb) {
};
-if (module == require.main) require('test').run(exports);
+if (module === require.main) require('test').run(exports);
View
4 tests/ejs.js
@@ -1,3 +1,5 @@
+"use strict";
+
var fs = require('fs');
var jsxgettext = require('../lib/jsxgettext');
var path = require('path');
@@ -19,4 +21,4 @@ exports['test ejs'] = function (assert, cb) {
};
-if (module == require.main) require('test').run(exports);
+if (module === require.main) require('test').run(exports);
View
4 tests/expressions.js
@@ -1,3 +1,5 @@
+"use strict";
+
var
fs = require('fs'),
jsxgettext = require('../lib/jsxgettext'),
@@ -47,4 +49,4 @@ exports['test concatenated strings (issue #10)'] = function (assert, cb) {
});
};
-if (module == require.main) require('test').run(exports);
+if (module === require.main) require('test').run(exports);
View
12 tests/handlebars.js
@@ -1,3 +1,5 @@
+"use strict";
+
var fs = require('fs');
var jsxgettext = require('../lib/jsxgettext');
var path = require('path');
@@ -12,13 +14,13 @@ exports['test handlebars'] = function (assert, cb) {
assert.equal(typeof result, 'string', 'result is a string');
assert.ok(result.length > 1, 'result is not empty');
- assert.equal(result.split(/msgid ".+"/).length, 4, 'exactly three strings are found')
- assert.notEqual(result.indexOf('msgid "translated text"'), -1, 'result contains the first string')
- assert.notEqual(result.indexOf('msgid "block helper"'), -1, 'result contains the second string')
- assert.notEqual(result.indexOf('msgid "so let\'s test"'), -1, 'result contains the third string')
+ assert.equal(result.split(/msgid ".+"/).length, 4, 'exactly three strings are found');
+ assert.notEqual(result.indexOf('msgid "translated text"'), -1, 'result contains the first string');
+ assert.notEqual(result.indexOf('msgid "block helper"'), -1, 'result contains the second string');
+ assert.notEqual(result.indexOf('msgid "so let\'s test"'), -1, 'result contains the third string');
cb();
});
};
-if (module == require.main) require('test').run(exports);
+if (module === require.main) require('test').run(exports);
View
21 tests/jade.js
@@ -1,3 +1,5 @@
+"use strict";
+
var fs = require('fs');
var jsxgettext = require('../lib/jsxgettext');
var path = require('path');
@@ -21,20 +23,21 @@ exports['test parsing'] = function (assert, cb) {
cb();
});
};
-exports['test regexp escaping'] = function(assert, cb) {
+
+exports['test regexp escaping'] = function (assert, cb) {
// check that files with leading hash parse
var inputFilename = path.join(__dirname, 'inputs', 'second_attribute.jade');
fs.readFile(inputFilename, "utf8", function (err, source) {
+ // if keyword is not escaped, this will throw an exception
+ var opts = {keyword: 'foo)bar'},
+ sources = {'inputs/second_attribute.jade': source};
- // if keyword is not escaped, this will throw an exception
- var opts = {keyword: 'foo)bar'},
- sources = {'inputs/second_attribute.jade': source},
- result = jsxgettext.generateFromJade(sources, opts);
- // ..and won't reach to here.
- assert.ok(true, 'regexp should not throw');
- cb();
+ jsxgettext.generateFromJade(sources, opts);
+ // ..and won't reach to here.
+ assert.ok(true, 'regexp should not throw');
+ cb();
});
};
-if (module == require.main) require('test').run(exports);
+if (module === require.main) require('test').run(exports);
View
46 tests/join_existing.js
@@ -1,4 +1,6 @@
-const
+"use strict";
+
+var
fs = require('fs'),
jsxgettext = require('../lib/jsxgettext'),
utils = require('./utils'),
@@ -14,6 +16,26 @@ const
var sourceFirstPass;
+var test2 = function (assert, cb) {
+ // We'll extract strings from inputs/second.js
+ // This should match outputs/messages.js
+ var inputFilename = path.join(__dirname, 'inputs', 'second.js');
+ fs.readFile(inputFilename, 'utf8', function (err, source) {
+ var opts = {"join-existing": true},
+ sources = {'inputs/first.js': sourceFirstPass,
+ 'inputs/second.js': source},
+ result = jsxgettext.generate(sources, 'inputs/second.js', opts);
+
+ assert.equal(typeof result, 'string', 'Result should be a string');
+ assert.ok(result.length > 0, 'Result should not be empty');
+ var outputFilename = path.join(__dirname, 'outputs', 'messages_secondpass.pot');
+
+ utils.compareResultWithFile(result, outputFilename, assert, function () {
+ fs.unlink('messages.pot', cb); // cleanup
+ });
+ });
+};
+
exports['we gettext from first file'] = function (assert, cb) {
// We'll extract strings from inputs/first.js
// This should match outputs/messages_firstpass.js
@@ -38,24 +60,4 @@ exports['we gettext from first file'] = function (assert, cb) {
});
};
-var test2 = function (assert, cb) {
- // We'll extract strings from inputs/second.js
- // This should match outputs/messages.js
- var inputFilename = path.join(__dirname, 'inputs', 'second.js');
- fs.readFile(inputFilename, 'utf8', function (err, source) {
- var opts = {"join-existing": true},
- sources = {'inputs/first.js': sourceFirstPass,
- 'inputs/second.js': source},
- result = jsxgettext.generate(sources, 'inputs/second.js', opts);
-
- assert.equal(typeof result, 'string', 'Result should be a string');
- assert.ok(result.length > 0, 'Result should not be empty');
- var outputFilename = path.join(__dirname, 'outputs', 'messages_secondpass.pot');
-
- utils.compareResultWithFile(result, outputFilename, assert, function () {
- fs.unlink('messages.pot', cb); // cleanup
- });
- });
-};
-
-if (module == require.main) require('test').run(exports);
+if (module === require.main) require('test').run(exports);
View
4 tests/leading_hash.js
@@ -1,3 +1,5 @@
+"use strict";
+
var
fs = require('fs'),
jsxgettext = require('../lib/jsxgettext'),
@@ -19,4 +21,4 @@ exports['leading hash'] = function (assert, cb) {
};
-if (module == require.main) require('test').run(exports);
+if (module === require.main) require('test').run(exports);
View
24 tests/messages.js
@@ -1,24 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-BrowserID.Wait = (function(){
- "use strict";
-
- var Wait = {
- authentication: {
- /* L10n: test block */
- title: gettext("Finishing Sign In..."),
- message: gettext("In just a moment you'll be signed into Persona.")
- },
-
- generateKey: {
- // L10n: test
- message: gettext("Please wait a few seconds while we sign you into the site.")
- },
- };
-
-
- return Wait;
-}());
-
-
View
11 tests/po_quotes.js
@@ -1,3 +1,5 @@
+"use strict";
+
var
fs = require('fs'),
jsxgettext = require('../lib/jsxgettext'),
@@ -14,15 +16,14 @@ exports['test quotes and newlines when folding msgid'] = function (assert, cb) {
result = jsxgettext.generate(sources, 'inputs/po_quotes.js', opts);
// short line is escaped properly
- assert.ok(result.indexOf('\nmsgid "Hello \\"World\\"\\n"\n')>=0, 'short line');
+ assert.ok(result.indexOf('\nmsgid "Hello \\"World\\"\\n"\n') >= 0, 'short line');
// long folded line should also get escaped
- assert.ok(result.indexOf('\n"This is a long string with \\"quotes\\", newlines \\n"\n')>=0, 'long folded line, 1');
- assert.ok(result.indexOf('\n" and such. The line should get folded"\n')>=0, 'long folded line, 2');
+ assert.ok(result.indexOf('\n"This is a long string with \\"quotes\\", newlines \\n"\n') >= 0, 'long folded line, 1');
+ assert.ok(result.indexOf('\n" and such. The line should get folded"\n') >= 0, 'long folded line, 2');
cb();
});
};
-
-if (module == require.main) require('test').run(exports);
+if (module === require.main) require('test').run(exports);
View
5 tests/second_attribute.js
@@ -1,3 +1,5 @@
+"use strict";
+
var
fs = require('fs'),
jsxgettext = require('../lib/jsxgettext'),
@@ -17,5 +19,4 @@ exports['test second attribute'] = function (assert, cb) {
});
};
-
-if (module == require.main) require('test').run(exports);
+if (module === require.main) require('test').run(exports);
View
5 tests/test_comment.js
@@ -1,3 +1,5 @@
+"use strict";
+
var
fs = require('fs'),
jsxgettext = require('../lib/jsxgettext'),
@@ -18,5 +20,4 @@ exports['test comments'] = function (assert, cb) {
});
};
-
-if (module == require.main) require('test').run(exports);
+if (module === require.main) require('test').run(exports);
View
2  tests/utils.js
@@ -1,3 +1,5 @@
+"use strict";
+
var fs = require('fs');
exports.compareResultWithFile = function (result, filePath, assert, cb, msg) {
View
35 tests/wait-messages.js
@@ -1,35 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-BrowserID.Wait = (function(){
- "use strict";
-
- var Wait = {
- authentication: {
- /* L10n: test block */
- title: gettext("Finishing Sign In..."),
- message: gettext("In just a moment you'll be signed into BrowserID.")
- },
-
- generateKey: {
- title: gettext("Finishing Sign In..."),
- /* L10n: test multi
- * line */
- message: gettext("Please wait a few seconds while we sign you into the site.")
- },
-
- slowXHR: {
- // L10n: test single line comment
- title: gettext("We are sorry, this request is taking a LOOONG time."),
- // ignore this comment
- message: _("This message will go away when the request completes (hopefully soon). If you wait too long, close this window and try again."),
- id: "slowXHR"
- }
-
- };
-
-
- return Wait;
-}());
-
-
Please sign in to comment.
Something went wrong with that request. Please try again.