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
|
2012-10-05 20:44:29 +02:00
|
|
|
' $ jQuery Spinner Handlebars XDate'
|
2012-10-04 07:45:44 +02:00
|
|
|
|
|
|
|
// index.html
|
2012-10-10 23:26:01 +02:00
|
|
|
+ ' initial_pointer email stream_list people_list have_initial_messages'
|
2012-10-04 07:45:44 +02:00
|
|
|
|
|
|
|
// compose.js
|
2012-10-15 21:45:15 +02:00
|
|
|
+ ' show_compose hide_compose toggle_compose clear_compose_box compose_button'
|
Make the client reload the page when it detects a server restart
If the client is not composing a message, we can just force a page
reload. However, if he is composing a message, we must preserve that
message while still reloading as soon as possible.
We take the following approach: if the client has not completed the
composition after 5 minutes, do a compose-preserving reload
(described below). If he sends the message before the timeout
expires, reload the page after a successful send. If the send fails
(not due to server timeout), however, we do a compose-perserving
reload in case the error was due to the data format changing. If the
send failed due to server timeout, we don't reload because the reload
will probably also fail.
In a compose-preserving reload, we redirect to an URI that has a
fragment indicating we are doing a reload and containing all the
necessary information for restoring the compose window to its
previous state. On page load, we check the fragment to see if we
just did a compose-preserving reload, and, if we did, we restore the
compose window (or just try the send again in the case of send
failure). The URI fragment looks like:
(imported from commit af4eeb3930c24118e088057d4da456748fbd2229)
2012-10-16 21:16:06 +02:00
|
|
|
+ ' composing_message composing_stream_message compose_stream_name'
|
|
|
|
+ ' compose_stream_name compose_subject compose_recipient compose_message'
|
|
|
|
+ ' validate_message status_classes'
|
2012-10-04 07:45:44 +02:00
|
|
|
|
|
|
|
// dom_access.js
|
|
|
|
+ ' get_first_visible get_last_visible get_next_visible get_prev_visible'
|
2012-10-10 16:19:46 +02:00
|
|
|
+ ' get_id get_message_row'
|
2012-10-04 07:45:44 +02:00
|
|
|
|
|
|
|
// hotkey.js
|
2012-10-09 19:54:05 +02:00
|
|
|
+ ' process_goto_hotkey process_compose_hotkey process_key_in_input'
|
2012-10-17 18:05:43 +02:00
|
|
|
+ ' set_compose_hotkey'
|
2012-10-04 07:45:44 +02:00
|
|
|
|
|
|
|
// narrow.js
|
2012-10-15 18:57:24 +02:00
|
|
|
+ ' narrow_target_message_id narrowed show_all_messages'
|
2012-10-11 00:01:39 +02:00
|
|
|
+ ' narrow_all_personals narrow_by_recipient narrow_subject'
|
2012-10-04 07:45:44 +02:00
|
|
|
|
|
|
|
// setup.js
|
|
|
|
+ ' loading_spinner templates'
|
|
|
|
|
|
|
|
// subscribe.js
|
2012-10-10 23:26:01 +02:00
|
|
|
+ ' fetch_subs sub_from_home subscribed_to stream_list_hash'
|
|
|
|
+ ' add_to_stream_list'
|
2012-10-04 07:45:44 +02:00
|
|
|
|
|
|
|
// ui.js
|
2012-10-09 16:59:49 +02:00
|
|
|
+ ' register_onclick hide_email show_email'
|
2012-10-17 20:43:20 +02:00
|
|
|
+ ' report_error report_success report_message clicking mouse_moved'
|
2012-10-04 07:45:44 +02:00
|
|
|
+ ' update_autocomplete autocomplete_needs_update'
|
|
|
|
|
|
|
|
// zephyr.js
|
2012-10-15 19:24:34 +02:00
|
|
|
+ ' message_array message_dict selected_message_class'
|
2012-10-12 19:14:59 +02:00
|
|
|
+ ' status_classes clear_table add_to_table subject_dict'
|
2012-10-10 20:20:31 +02:00
|
|
|
+ ' keep_pointer_in_view move_pointer_at_page_top_and_bottom'
|
|
|
|
+ ' respond_to_message'
|
2012-10-09 23:51:45 +02:00
|
|
|
+ ' select_message select_message_by_id'
|
2012-10-04 07:45:44 +02:00
|
|
|
+ ' scroll_to_selected select_and_show_by_id'
|
2012-10-10 16:17:58 +02:00
|
|
|
+ ' selected_message selected_message_id'
|
2012-10-17 20:43:20 +02:00
|
|
|
+ ' reload_app reloading_app reload_app_preserving_compose'
|
2012-10-05 22:29:59 +02:00
|
|
|
+ ' at_top_of_viewport at_bottom_of_viewport'
|
2012-10-16 04:07:52 +02:00
|
|
|
+ ' viewport'
|
2012-10-04 07:45:44 +02:00
|
|
|
;
|
|
|
|
|
|
|
|
|
|
|
|
var jslint_options = {
|
|
|
|
browser: true, // Assume browser environment
|
|
|
|
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.
|
|
|
|
|
|
|
|
predef: globals.split(/\s+/)
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// For each error.raw message, we can return 'true' to ignore
|
|
|
|
// the error.
|
|
|
|
var exceptions = {
|
|
|
|
"Expected '{a}' and instead saw '{b}'." : function (error) {
|
|
|
|
// We allow single-statement 'if' with no brace.
|
|
|
|
// This exception might be overly broad but oh well.
|
|
|
|
return (error.a === '{');
|
|
|
|
},
|
|
|
|
|
|
|
|
"Unexpected 'else' after 'return'." : function () {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
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 19:15:37 +02:00
|
|
|
var js_dir = fs.realpathSync(path.join(__dirname, '../../zephyr/static/js'));
|
2012-10-04 07:45:44 +02:00
|
|
|
|
|
|
|
var exit_code = 0;
|
|
|
|
|
|
|
|
fs.readdirSync(js_dir).forEach(function (filename) {
|
|
|
|
if (filename.slice('-3') !== '.js')
|
|
|
|
return;
|
|
|
|
|
2012-10-04 19:40:29 +02:00
|
|
|
var filepath = path.join(js_dir, filename);
|
|
|
|
var contents = fs.readFileSync(filepath, 'utf8');
|
2012-10-04 07:45:44 +02:00
|
|
|
var messages = [];
|
|
|
|
|
|
|
|
if (!JSLINT(contents, jslint_options)) {
|
|
|
|
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);
|