2012-10-04 19:48:24 +02:00
|
|
|
"use strict";
|
|
|
|
|
2012-10-04 07:45:44 +02:00
|
|
|
// Global variables, categorized by place of definition.
|
|
|
|
var globals =
|
|
|
|
// Third-party libraries
|
2013-08-26 18:35:25 +02:00
|
|
|
' $ _ jQuery Spinner Handlebars XDate zxcvbn Intl mixpanel Notification'
|
2013-12-19 17:03:08 +01:00
|
|
|
+ ' LazyLoad Dropbox SockJS marked'
|
2012-10-04 07:45:44 +02:00
|
|
|
|
2013-07-26 19:51:56 +02:00
|
|
|
// Node-based unit tests
|
|
|
|
+ ' module'
|
|
|
|
|
2013-06-14 00:25:02 +02:00
|
|
|
// Cocoa<-> Javascript bridge
|
|
|
|
+ ' bridge'
|
|
|
|
|
2012-10-04 07:45:44 +02:00
|
|
|
// index.html
|
2013-03-25 23:26:14 +01:00
|
|
|
+ ' page_params'
|
2012-10-04 07:45:44 +02:00
|
|
|
|
2012-10-18 20:29:16 +02:00
|
|
|
// common.js
|
2013-04-03 22:30:36 +02:00
|
|
|
+ ' status_classes password_quality'
|
2012-10-18 20:29:16 +02:00
|
|
|
|
2012-10-04 07:45:44 +02:00
|
|
|
// setup.js
|
2013-02-16 10:45:32 +01:00
|
|
|
+ ' csrf_token'
|
2012-10-04 07:45:44 +02:00
|
|
|
|
2013-02-19 05:11:13 +01:00
|
|
|
// Modules, defined in their respective files.
|
2013-08-11 21:21:47 +02:00
|
|
|
+ ' compose compose_fade rows hotkeys narrow reload notifications_bar search subs'
|
2014-01-30 19:25:25 +01:00
|
|
|
+ ' composebox_typeahead server_events typeahead_helper notifications hashchange'
|
2013-08-16 17:10:22 +02:00
|
|
|
+ ' invite ui util activity timerender MessageList MessageListView blueslip unread stream_list'
|
2014-03-04 23:37:29 +01:00
|
|
|
+ ' message_edit tab_bar emoji popovers navigate people settings alert_words_ui message_store'
|
2013-08-07 22:28:45 +02:00
|
|
|
+ ' avatar feature_flags search_suggestion referral stream_color Dict'
|
2013-12-18 19:55:18 +01:00
|
|
|
+ ' Filter summary admin stream_data muting WinChan muting_ui Socket channel'
|
2014-02-27 00:01:18 +01:00
|
|
|
+ ' message_flags bot_data'
|
2013-02-07 19:57:45 +01:00
|
|
|
|
2013-02-16 09:43:27 +01:00
|
|
|
// colorspace.js
|
|
|
|
+ ' colorspace'
|
|
|
|
|
2013-02-13 22:04:35 +01:00
|
|
|
// tutorial.js
|
|
|
|
+ ' tutorial'
|
|
|
|
|
2013-02-16 10:45:32 +01:00
|
|
|
// templates.js
|
|
|
|
+ ' templates'
|
|
|
|
|
2013-08-29 21:33:26 +02:00
|
|
|
// alert_words.js
|
|
|
|
+ ' alert_words'
|
|
|
|
|
2014-01-27 23:20:50 +01:00
|
|
|
// fenced_code.js
|
|
|
|
+ ' fenced_code'
|
|
|
|
|
2013-12-19 17:03:08 +01:00
|
|
|
// echo.js
|
|
|
|
+ ' echo'
|
|
|
|
|
2014-01-16 16:42:30 +01:00
|
|
|
// localstorage.js
|
|
|
|
+ ' localstorage'
|
|
|
|
|
2013-07-29 22:48:16 +02:00
|
|
|
// zulip.js
|
2014-01-31 00:00:33 +01:00
|
|
|
+ ' all_msg_list home_msg_list narrowed_msg_list current_msg_list'
|
2013-11-26 19:06:21 +01:00
|
|
|
+ ' keep_pointer_in_view unread_messages_read_in_narrow'
|
2013-03-28 19:16:48 +01:00
|
|
|
+ ' respond_to_message recenter_view last_viewport_movement_direction'
|
2013-05-29 19:17:32 +02:00
|
|
|
+ ' scroll_to_selected get_private_message_recipient'
|
2014-01-31 23:13:22 +01:00
|
|
|
+ ' viewport process_loaded_for_unread'
|
2014-01-31 16:27:24 +01:00
|
|
|
+ ' have_scrolled_away_from_top'
|
2013-02-12 22:32:14 +01:00
|
|
|
+ ' maybe_scroll_to_selected recenter_pointer_on_display suppress_scroll_pointer_update'
|
2013-05-07 20:02:24 +02:00
|
|
|
+ ' fast_forward_pointer recent_subjects unread_subjects'
|
2014-01-31 16:27:24 +01:00
|
|
|
+ ' furthest_read server_furthest_read'
|
2012-10-04 07:45:44 +02:00
|
|
|
;
|
|
|
|
|
|
|
|
|
2013-02-19 04:40:57 +01:00
|
|
|
var options = {
|
2012-10-04 07:45:44 +02:00
|
|
|
vars: true, // Allow multiple 'var' per function
|
|
|
|
sloppy: true, // Don't require "use strict"
|
|
|
|
white: true, // Lenient whitespace rules
|
|
|
|
plusplus: true, // Allow increment/decrement operators
|
|
|
|
regexp: true, // Allow . and [^...] in regular expressions
|
|
|
|
todo: true, // Allow "TODO" comments.
|
2013-02-12 21:41:59 +01:00
|
|
|
newcap: true, // Don't assume that capitalized functions are
|
|
|
|
// constructors (and the converse)
|
2013-02-19 04:40:57 +01:00
|
|
|
nomen: true, // Tolerate underscore at the beginning of a name
|
|
|
|
stupid: true // Allow synchronous methods
|
2012-10-04 07:45:44 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// For each error.raw message, we can return 'true' to ignore
|
|
|
|
// the error.
|
|
|
|
var exceptions = {
|
|
|
|
"Unexpected 'else' after 'return'." : function () {
|
|
|
|
return true;
|
2013-02-12 23:26:25 +01:00
|
|
|
},
|
|
|
|
|
|
|
|
"Don't make functions within a loop." : function () {
|
|
|
|
return true;
|
2013-04-04 00:04:47 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
// We use typeof to test if a variable exists at all.
|
|
|
|
"Unexpected 'typeof'. Use '===' to compare directly with {a}.": function (error) {
|
|
|
|
return error.a === 'undefined';
|
2012-10-04 07:45:44 +02:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
var fs = require('fs');
|
2012-10-04 19:15:37 +02:00
|
|
|
var path = require('path');
|
|
|
|
var JSLINT = require(path.join(__dirname, 'jslint')).JSLINT;
|
2012-10-04 07:45:44 +02:00
|
|
|
|
2012-10-04 19:40:29 +02:00
|
|
|
var cwd = process.cwd();
|
2012-10-04 07:45:44 +02:00
|
|
|
|
|
|
|
var exit_code = 0;
|
2013-02-19 04:40:57 +01:00
|
|
|
var i;
|
2012-10-04 07:45:44 +02:00
|
|
|
|
2013-02-19 04:40:57 +01:00
|
|
|
// Drop 'node' and the script name from args.
|
|
|
|
for (i=0; i<2; i++) {
|
|
|
|
process.argv.shift();
|
|
|
|
}
|
2012-10-04 07:45:44 +02:00
|
|
|
|
2013-02-19 04:40:57 +01:00
|
|
|
process.argv.forEach(function (filepath) {
|
2012-10-04 19:40:29 +02:00
|
|
|
var contents = fs.readFileSync(filepath, 'utf8');
|
2012-10-04 07:45:44 +02:00
|
|
|
var messages = [];
|
|
|
|
|
2013-02-19 04:40:57 +01:00
|
|
|
// We mutate 'options' so be sure to clear everything.
|
2013-07-25 22:41:44 +02:00
|
|
|
if (filepath.indexOf('static/js/') !== -1) {
|
2013-02-19 04:40:57 +01:00
|
|
|
// Frontend browser code
|
|
|
|
options.browser = true;
|
|
|
|
options.node = false;
|
|
|
|
options.predef = globals.split(/\s+/);
|
|
|
|
} else {
|
|
|
|
// Backend code for Node.js
|
|
|
|
options.browser = false;
|
|
|
|
options.node = true;
|
|
|
|
|
2013-07-29 23:03:31 +02:00
|
|
|
if (filepath.indexOf('zerver/tests/frontend/') !== -1) {
|
2013-07-15 23:43:30 +02:00
|
|
|
// Include '$' and browser globals because we use them inside
|
|
|
|
// casper.evaluate
|
2014-01-31 06:16:20 +01:00
|
|
|
options.predef = ['casper', '$', 'document', 'window', 'set_global', 'add_dependencies', 'patch_builtin', 'assert'];
|
2013-02-19 04:40:57 +01:00
|
|
|
} else {
|
|
|
|
options.predef = [];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!JSLINT(contents, options)) {
|
2012-10-04 07:45:44 +02:00
|
|
|
JSLINT.errors.forEach(function (error) {
|
|
|
|
if (error === null) {
|
|
|
|
// JSLint stopping error
|
|
|
|
messages.push(' (JSLint giving up)');
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
var exn = exceptions[error.raw];
|
|
|
|
if (exn && exn(error)) {
|
|
|
|
// Ignore this error.
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// NB: this will break on a 10,000 line file
|
|
|
|
var line = (' ' + error.line).slice(-4);
|
|
|
|
|
|
|
|
messages.push(' ' + line + ' ' + error.reason);
|
|
|
|
});
|
|
|
|
|
|
|
|
if (messages.length > 0) {
|
|
|
|
exit_code = 1;
|
|
|
|
|
2012-10-04 19:40:29 +02:00
|
|
|
console.log(path.relative(cwd, filepath));
|
2012-10-04 07:45:44 +02:00
|
|
|
|
|
|
|
// Something very wacky happens if we do
|
|
|
|
// .forEach(console.log) directly.
|
|
|
|
messages.forEach(function (msg) {
|
|
|
|
console.log(msg);
|
|
|
|
});
|
|
|
|
|
|
|
|
console.log('');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
process.exit(exit_code);
|