2010-07-12 22:04:42 +08:00
|
|
|
$(document).ready(function() {
|
2011-07-06 19:32:00 +08:00
|
|
|
setup_global_vars();
|
2010-10-08 00:23:11 +08:00
|
|
|
setup_constant_events();
|
|
|
|
update_vhosts();
|
2011-01-18 02:06:02 +08:00
|
|
|
update_interval();
|
2011-05-06 01:30:45 +08:00
|
|
|
setup_extensions();
|
|
|
|
});
|
|
|
|
|
2011-05-06 21:39:09 +08:00
|
|
|
function dispatcher_add(fun) {
|
|
|
|
dispatcher_modules.push(fun);
|
2011-05-06 23:01:20 +08:00
|
|
|
if (dispatcher_modules.length == extension_count) {
|
2011-05-06 21:39:09 +08:00
|
|
|
start_app();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function dispatcher() {
|
|
|
|
for (var i in dispatcher_modules) {
|
|
|
|
dispatcher_modules[i](this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-05-06 01:30:45 +08:00
|
|
|
function start_app() {
|
|
|
|
app = $.sammy(dispatcher);
|
2010-08-23 23:32:17 +08:00
|
|
|
app.run();
|
2010-07-13 20:03:36 +08:00
|
|
|
var url = this.location.toString();
|
2010-08-23 23:32:17 +08:00
|
|
|
if (url.indexOf('#') == -1) {
|
|
|
|
this.location = url + '#/';
|
|
|
|
}
|
2011-05-06 01:30:45 +08:00
|
|
|
}
|
2010-07-12 22:04:42 +08:00
|
|
|
|
2010-10-08 00:23:11 +08:00
|
|
|
function setup_constant_events() {
|
|
|
|
$('#update-every').change(function() {
|
|
|
|
var interval = $(this).val();
|
2011-01-18 02:06:02 +08:00
|
|
|
store_pref('interval', interval);
|
2011-01-14 19:33:34 +08:00
|
|
|
if (interval == '')
|
|
|
|
interval = null;
|
|
|
|
else
|
|
|
|
interval = parseInt(interval);
|
2010-10-08 00:23:11 +08:00
|
|
|
set_timer_interval(interval);
|
|
|
|
});
|
|
|
|
$('#show-vhost').change(function() {
|
|
|
|
current_vhost = $(this).val();
|
2011-01-18 01:23:54 +08:00
|
|
|
store_pref('vhost', current_vhost);
|
2010-10-08 00:23:11 +08:00
|
|
|
update();
|
|
|
|
});
|
2010-11-09 19:42:43 +08:00
|
|
|
if (!vhosts_interesting) {
|
|
|
|
$('#vhost-form').hide();
|
|
|
|
}
|
2010-10-08 00:23:11 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
function update_vhosts() {
|
|
|
|
var vhosts = JSON.parse(sync_get('/vhosts'));
|
2010-11-09 19:42:43 +08:00
|
|
|
vhosts_interesting = vhosts.length > 1;
|
|
|
|
if (vhosts_interesting)
|
|
|
|
$('#vhost-form').show();
|
|
|
|
else
|
|
|
|
$('#vhost-form').hide();
|
2010-10-08 00:23:11 +08:00
|
|
|
var select = $('#show-vhost').get(0);
|
|
|
|
select.options.length = vhosts.length + 1;
|
|
|
|
var index = 0;
|
|
|
|
for (var i = 0; i < vhosts.length; i++) {
|
|
|
|
var vhost = vhosts[i].name;
|
2011-01-18 21:32:47 +08:00
|
|
|
select.options[i + 1] = new Option(vhost, vhost);
|
2010-10-08 00:23:11 +08:00
|
|
|
if (vhost == current_vhost) index = i + 1;
|
|
|
|
}
|
|
|
|
select.selectedIndex = index;
|
2011-01-18 21:32:47 +08:00
|
|
|
current_vhost = select.options[index].value;
|
2011-01-18 01:32:26 +08:00
|
|
|
store_pref('vhost', current_vhost);
|
2010-10-08 00:23:11 +08:00
|
|
|
}
|
|
|
|
|
2011-05-06 01:30:45 +08:00
|
|
|
function setup_extensions() {
|
|
|
|
var extensions = JSON.parse(sync_get('/extensions'));
|
|
|
|
for (var i in extensions) {
|
|
|
|
var extension = extensions[i];
|
2011-05-06 18:20:59 +08:00
|
|
|
dynamic_load(extension.javascript);
|
2011-05-06 01:30:45 +08:00
|
|
|
}
|
2011-05-06 21:39:09 +08:00
|
|
|
extension_count = extensions.length;
|
2011-05-06 01:30:45 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
function dynamic_load(filename) {
|
|
|
|
var element = document.createElement('script');
|
|
|
|
element.setAttribute('type', 'text/javascript');
|
|
|
|
element.setAttribute('src', 'js/' + filename);
|
|
|
|
document.getElementsByTagName("head")[0].appendChild(element);
|
|
|
|
}
|
|
|
|
|
2011-01-18 02:06:02 +08:00
|
|
|
function update_interval() {
|
2011-01-21 19:20:01 +08:00
|
|
|
var intervalStr = get_pref('interval');
|
|
|
|
var interval;
|
|
|
|
|
|
|
|
if (intervalStr == null) interval = 5000;
|
|
|
|
else if (intervalStr == '') interval = null;
|
|
|
|
else interval = parseInt(intervalStr);
|
|
|
|
|
|
|
|
if (isNaN(interval)) interval = null; // Prevent DoS if cookie malformed
|
|
|
|
|
2011-01-18 02:06:02 +08:00
|
|
|
set_timer_interval(interval);
|
|
|
|
|
|
|
|
var select = $('#update-every').get(0);
|
|
|
|
var opts = select.options;
|
|
|
|
for (var i = 0; i < opts.length; i++) {
|
2011-01-21 19:20:01 +08:00
|
|
|
if (opts[i].value == intervalStr) {
|
2011-01-18 02:06:02 +08:00
|
|
|
select.selectedIndex = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2010-10-08 00:23:11 +08:00
|
|
|
}
|
|
|
|
|
2010-08-24 01:32:33 +08:00
|
|
|
function go_to(url) {
|
|
|
|
this.location = url;
|
|
|
|
}
|
|
|
|
|
2010-09-29 22:59:39 +08:00
|
|
|
function set_timer_interval(interval) {
|
|
|
|
timer_interval = interval;
|
2010-10-14 20:15:26 +08:00
|
|
|
reset_timer();
|
|
|
|
}
|
|
|
|
|
|
|
|
function reset_timer() {
|
2010-09-29 22:59:39 +08:00
|
|
|
clearInterval(timer);
|
|
|
|
if (timer_interval != null) {
|
2010-09-29 23:56:03 +08:00
|
|
|
timer = setInterval('partial_update()', timer_interval);
|
2010-09-29 22:59:39 +08:00
|
|
|
}
|
|
|
|
}
|
2010-07-13 00:11:42 +08:00
|
|
|
|
2010-08-23 23:32:17 +08:00
|
|
|
function render(reqs, template, highlight) {
|
|
|
|
current_template = template;
|
|
|
|
current_reqs = reqs;
|
|
|
|
current_highlight = highlight;
|
2010-09-29 23:56:03 +08:00
|
|
|
update();
|
2010-09-29 22:59:39 +08:00
|
|
|
}
|
|
|
|
|
2010-09-29 23:56:03 +08:00
|
|
|
function update() {
|
2010-09-29 22:59:39 +08:00
|
|
|
clearInterval(timer);
|
2010-10-08 00:23:11 +08:00
|
|
|
with_update(function(html) {
|
2010-09-29 22:59:39 +08:00
|
|
|
replace_content('main', html);
|
|
|
|
postprocess();
|
2010-10-12 00:05:06 +08:00
|
|
|
postprocess_partial();
|
2011-01-27 20:15:23 +08:00
|
|
|
maybe_scroll();
|
2010-10-14 20:15:26 +08:00
|
|
|
reset_timer();
|
2010-09-29 22:59:39 +08:00
|
|
|
});
|
2010-07-13 20:03:36 +08:00
|
|
|
}
|
|
|
|
|
2010-09-29 23:56:03 +08:00
|
|
|
function partial_update() {
|
2010-09-29 22:59:39 +08:00
|
|
|
if ($('.updatable').length > 0) {
|
2011-01-27 20:15:23 +08:00
|
|
|
if (update_counter >= 200) {
|
|
|
|
update_counter = 0;
|
|
|
|
full_refresh();
|
|
|
|
return;
|
|
|
|
}
|
2010-10-08 00:23:11 +08:00
|
|
|
with_update(function(html) {
|
2011-01-27 20:15:23 +08:00
|
|
|
update_counter++;
|
2010-09-29 22:59:39 +08:00
|
|
|
replace_content('scratch', html);
|
|
|
|
var befores = $('#main .updatable');
|
|
|
|
var afters = $('#scratch .updatable');
|
|
|
|
if (befores.length != afters.length) {
|
|
|
|
throw("before/after mismatch");
|
|
|
|
}
|
|
|
|
for (var i = 0; i < befores.length; i++) {
|
2011-01-28 19:11:02 +08:00
|
|
|
$(befores[i]).replaceWith(afters[i]);
|
2010-09-29 22:59:39 +08:00
|
|
|
}
|
2011-05-26 21:49:06 +08:00
|
|
|
replace_content('scratch', '');
|
2010-10-12 00:05:06 +08:00
|
|
|
postprocess_partial();
|
2010-09-29 22:59:39 +08:00
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-01-27 20:15:23 +08:00
|
|
|
function full_refresh() {
|
|
|
|
store_pref('position', x_position() + ',' + y_position());
|
|
|
|
location.reload();
|
|
|
|
}
|
|
|
|
|
|
|
|
function maybe_scroll() {
|
|
|
|
var pos = get_pref('position');
|
|
|
|
if (pos) {
|
|
|
|
clear_pref('position');
|
|
|
|
var xy = pos.split(",");
|
|
|
|
window.scrollTo(parseInt(xy[0]), parseInt(xy[1]));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function x_position() {
|
|
|
|
return window.pageXOffset ?
|
|
|
|
window.pageXOffset :
|
|
|
|
document.documentElement.scrollLeft ?
|
|
|
|
document.documentElement.scrollLeft :
|
|
|
|
document.body.scrollLeft;
|
|
|
|
}
|
|
|
|
|
|
|
|
function y_position() {
|
|
|
|
return window.pageYOffset ?
|
|
|
|
window.pageYOffset :
|
|
|
|
document.documentElement.scrollTop ?
|
|
|
|
document.documentElement.scrollTop :
|
|
|
|
document.body.scrollTop;
|
|
|
|
}
|
|
|
|
|
2010-10-08 00:23:11 +08:00
|
|
|
function with_update(fun) {
|
2010-10-12 00:05:06 +08:00
|
|
|
with_reqs(apply_state(current_reqs), [], function(json) {
|
2010-09-08 23:27:34 +08:00
|
|
|
json.statistics_level = statistics_level;
|
2010-08-23 23:32:17 +08:00
|
|
|
var html = format(current_template, json);
|
2010-09-29 22:59:39 +08:00
|
|
|
fun(html);
|
2010-08-31 23:44:12 +08:00
|
|
|
update_status('ok');
|
2010-08-24 01:32:33 +08:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2010-10-12 00:05:06 +08:00
|
|
|
function apply_state(reqs) {
|
|
|
|
var reqs2 = {};
|
|
|
|
for (k in reqs) {
|
|
|
|
var req = reqs[k];
|
|
|
|
var req2;
|
|
|
|
if (req in VHOST_QUERIES && current_vhost != '') {
|
|
|
|
req2 = req + '/' + esc(current_vhost);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
req2 = req;
|
2010-10-08 00:23:11 +08:00
|
|
|
}
|
|
|
|
|
2010-10-12 00:05:06 +08:00
|
|
|
var qs = '';
|
|
|
|
if (req in SORT_QUERIES && current_sort != null) {
|
|
|
|
qs = '?sort=' + current_sort +
|
|
|
|
'&sort_reverse=' + current_sort_reverse;
|
|
|
|
}
|
|
|
|
|
|
|
|
reqs2[k] = req2 + qs;
|
2010-10-08 00:23:11 +08:00
|
|
|
}
|
2010-10-12 00:05:06 +08:00
|
|
|
return reqs2;
|
2010-10-08 00:23:11 +08:00
|
|
|
}
|
|
|
|
|
2011-01-17 21:25:21 +08:00
|
|
|
function show_popup(type, text) {
|
2010-10-16 01:11:42 +08:00
|
|
|
var cssClass = '.form-popup-' + type;
|
2010-10-15 01:09:36 +08:00
|
|
|
function hide() {
|
2010-10-16 01:11:42 +08:00
|
|
|
$(cssClass).slideUp(200, function() {
|
2010-10-15 01:09:36 +08:00
|
|
|
$(this).remove();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
hide();
|
2010-10-16 01:11:42 +08:00
|
|
|
$('h1').after(format('error-popup', {'type': type, 'text': text}));
|
|
|
|
$(cssClass).center().slideDown(200);
|
|
|
|
$(cssClass + ' span').click(hide);
|
2010-09-09 01:00:32 +08:00
|
|
|
}
|
|
|
|
|
2010-08-24 01:32:33 +08:00
|
|
|
function postprocess() {
|
|
|
|
$('a').removeClass('selected');
|
|
|
|
$('a[href="' + current_highlight + '"]').addClass('selected');
|
2010-08-24 17:24:50 +08:00
|
|
|
$('form.confirm').submit(function() {
|
|
|
|
return confirm("Are you sure? This object cannot be recovered " +
|
|
|
|
"after deletion.");
|
|
|
|
});
|
2010-08-24 17:57:19 +08:00
|
|
|
$('div.section h2, div.section-hidden h2').click(function() {
|
2011-01-18 01:12:03 +08:00
|
|
|
toggle_visibility($(this));
|
2010-08-24 17:57:19 +08:00
|
|
|
});
|
2010-08-25 17:46:08 +08:00
|
|
|
$('label').map(function() {
|
|
|
|
if ($(this).attr('for') == '') {
|
|
|
|
var id = 'auto-label-' + Math.floor(Math.random()*1000000000);
|
|
|
|
var input = $(this).parents('tr').first().find('input, select');
|
2010-09-29 20:22:46 +08:00
|
|
|
if (input.attr('id') == '') {
|
|
|
|
$(this).attr('for', id);
|
|
|
|
input.attr('id', id);
|
|
|
|
}
|
2010-08-25 17:46:08 +08:00
|
|
|
}
|
|
|
|
});
|
2011-10-13 23:32:55 +08:00
|
|
|
$('#download-definitions').click(function() {
|
|
|
|
var path = 'api/definitions?download=' +
|
2010-09-29 20:22:46 +08:00
|
|
|
esc($('#download-filename').val());
|
2010-10-01 01:28:28 +08:00
|
|
|
window.location = path;
|
|
|
|
setTimeout('app.run()');
|
2010-09-29 20:22:46 +08:00
|
|
|
return false;
|
|
|
|
});
|
2011-01-28 01:18:21 +08:00
|
|
|
$('input, select').die();
|
2010-10-12 21:08:17 +08:00
|
|
|
$('.multifield input').live('blur', function() {
|
|
|
|
update_multifields();
|
|
|
|
});
|
2011-05-25 22:50:31 +08:00
|
|
|
$('.controls-appearance').change(function() {
|
2012-01-05 19:15:42 +08:00
|
|
|
var controls = $(this).attr('controls-divs');
|
2010-12-09 01:40:10 +08:00
|
|
|
if ($(this).val() == 'true') {
|
2011-05-25 22:50:31 +08:00
|
|
|
$('#' + controls + '-yes').slideDown(100);
|
|
|
|
$('#' + controls + '-no').slideUp(100);
|
2010-12-09 01:40:10 +08:00
|
|
|
} else {
|
2011-05-25 22:50:31 +08:00
|
|
|
$('#' + controls + '-yes').slideUp(100);
|
|
|
|
$('#' + controls + '-no').slideDown(100);
|
2010-12-09 01:40:10 +08:00
|
|
|
}
|
|
|
|
});
|
2011-01-18 01:12:03 +08:00
|
|
|
setup_visibility();
|
2011-01-17 21:25:21 +08:00
|
|
|
$('.help').die().live('click', function() {
|
|
|
|
help($(this).attr('id'))
|
|
|
|
});
|
2011-01-28 01:18:21 +08:00
|
|
|
$('input, select').live('focus', function() {
|
|
|
|
update_counter = 0; // If there's interaction, reset the counter.
|
|
|
|
});
|
2010-09-30 20:19:54 +08:00
|
|
|
if (! user_administrator) {
|
|
|
|
$('.administrator-only').remove();
|
|
|
|
}
|
2010-10-12 21:08:17 +08:00
|
|
|
update_multifields();
|
2010-08-07 00:52:26 +08:00
|
|
|
}
|
|
|
|
|
2010-10-12 00:05:06 +08:00
|
|
|
function postprocess_partial() {
|
|
|
|
$('.sort').click(function() {
|
|
|
|
var sort = $(this).attr('sort');
|
|
|
|
if (current_sort == sort) {
|
|
|
|
current_sort_reverse = ! current_sort_reverse;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
current_sort = sort;
|
|
|
|
current_sort_reverse = false;
|
|
|
|
}
|
|
|
|
update();
|
|
|
|
});
|
2011-01-17 21:25:21 +08:00
|
|
|
$('.help').html('(?)');
|
2010-10-12 00:05:06 +08:00
|
|
|
}
|
|
|
|
|
2010-10-12 21:08:17 +08:00
|
|
|
function update_multifields() {
|
|
|
|
$('.multifield').each(function(index) {
|
|
|
|
var largest_id = 0;
|
|
|
|
var empty_found = false;
|
|
|
|
var name = $(this).attr('id');
|
2011-02-25 22:17:27 +08:00
|
|
|
$('#' + name + ' input[name$="_mfkey"]').each(function(index) {
|
2010-10-12 21:08:17 +08:00
|
|
|
var match = $(this).attr('name').
|
|
|
|
match(/[a-z]*_([0-9]*)_mfkey/);
|
|
|
|
var id = parseInt(match[1]);
|
|
|
|
largest_id = Math.max(id, largest_id);
|
|
|
|
var key = $(this).val();
|
|
|
|
var value = $(this).next('input').val();
|
|
|
|
if (key == '' && value == '') {
|
|
|
|
if (empty_found) {
|
|
|
|
$(this).parent().remove();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
empty_found = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
if (!empty_found) {
|
2012-05-02 00:52:04 +08:00
|
|
|
var prefix = name + '_' + (largest_id + 1);
|
|
|
|
var type_part;
|
|
|
|
if ($(this).hasClass('string-only')) {
|
|
|
|
type_part = '<input type="hidden" name="' + prefix +
|
|
|
|
'_mftype" value="string"/>';
|
|
|
|
} else {
|
|
|
|
type_part = '<select name="' + prefix +
|
|
|
|
'_mftype">' +
|
|
|
|
'<option value="string">String</option>' +
|
|
|
|
'<option value="number">Number</option>' +
|
|
|
|
'<option value="boolean">Boolean</option>' +
|
|
|
|
'</select>';
|
|
|
|
}
|
|
|
|
$(this).append('<p><input type="text" name="' + prefix +
|
2010-10-12 21:08:17 +08:00
|
|
|
'_mfkey" value=""/> = ' +
|
2012-05-02 00:52:04 +08:00
|
|
|
'<input type="text" name="' + prefix +
|
|
|
|
'_mfvalue" value=""/> ' + type_part + '</p>');
|
2010-10-12 21:08:17 +08:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2011-01-18 01:12:03 +08:00
|
|
|
function setup_visibility() {
|
|
|
|
$('div.section,div.section-hidden').each(function(_index) {
|
|
|
|
var pref = section_pref(current_template,
|
|
|
|
$(this).children('h2').text());
|
|
|
|
var show = get_pref(pref);
|
|
|
|
if (show == null) {
|
|
|
|
show = $(this).hasClass('section');
|
|
|
|
}
|
|
|
|
else {
|
2011-01-18 02:13:00 +08:00
|
|
|
show = show == 't';
|
2011-01-18 01:12:03 +08:00
|
|
|
}
|
|
|
|
if (show) {
|
|
|
|
$(this).addClass('section-visible');
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
$(this).addClass('section-invisible');
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function toggle_visibility(item) {
|
|
|
|
var hider = item.next();
|
|
|
|
var all = item.parent();
|
|
|
|
var pref = section_pref(current_template, item.text());
|
|
|
|
item.next().slideToggle(100);
|
|
|
|
if (all.hasClass('section-visible')) {
|
|
|
|
if (all.hasClass('section'))
|
2011-01-18 02:13:00 +08:00
|
|
|
store_pref(pref, 'f');
|
2011-01-18 01:12:03 +08:00
|
|
|
else
|
|
|
|
clear_pref(pref);
|
|
|
|
all.removeClass('section-visible');
|
|
|
|
all.addClass('section-invisible');
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (all.hasClass('section-hidden'))
|
2011-01-18 02:13:00 +08:00
|
|
|
store_pref(pref, 't');
|
2011-01-18 01:12:03 +08:00
|
|
|
else
|
|
|
|
clear_pref(pref);
|
|
|
|
all.removeClass('section-invisible');
|
|
|
|
all.addClass('section-visible');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-02-25 22:17:27 +08:00
|
|
|
function publish_msg(params0) {
|
|
|
|
var params = params_magic(params0);
|
2011-02-24 01:59:34 +08:00
|
|
|
var path = fill_path_template('/exchanges/:vhost/:name/publish', params);
|
2011-02-25 22:17:27 +08:00
|
|
|
params['payload_encoding'] = 'string';
|
|
|
|
params['properties'] = {};
|
2011-02-25 22:27:09 +08:00
|
|
|
params['properties']['delivery_mode'] = parseInt(params['delivery_mode']);
|
2011-02-25 22:17:27 +08:00
|
|
|
if (params['headers'] != '')
|
|
|
|
params['properties']['headers'] = params['headers'];
|
2011-02-25 22:27:09 +08:00
|
|
|
var props = ['content_type', 'content_encoding', 'priority', 'correlation_id', 'reply_to', 'expiration', 'message_id', 'timestamp', 'type', 'user_id', 'app_id', 'cluster_id'];
|
2011-02-25 22:17:27 +08:00
|
|
|
for (var i in props) {
|
|
|
|
var p = props[i];
|
|
|
|
if (params['props'][p] != '')
|
|
|
|
params['properties'][p] = params['props'][p];
|
|
|
|
}
|
2011-02-24 01:59:34 +08:00
|
|
|
with_req('POST', path, JSON.stringify(params), function(resp) {
|
|
|
|
var result = jQuery.parseJSON(resp.responseText);
|
|
|
|
if (result.routed) {
|
|
|
|
show_popup('info', 'Message published.');
|
|
|
|
} else {
|
|
|
|
show_popup('warn', 'Message published, but not routed.');
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2011-02-22 22:00:20 +08:00
|
|
|
function get_msgs(params) {
|
|
|
|
var path = fill_path_template('/queues/:vhost/:name/get', params);
|
|
|
|
with_req('POST', path, JSON.stringify(params), function(resp) {
|
|
|
|
var msgs = jQuery.parseJSON(resp.responseText);
|
|
|
|
if (msgs.length == 0) {
|
|
|
|
show_popup('info', 'Queue is empty');
|
|
|
|
} else {
|
|
|
|
$('#msg-wrapper').slideUp(200);
|
|
|
|
replace_content('msg-wrapper', format('messages', {'msgs': msgs}));
|
|
|
|
$('#msg-wrapper').slideDown(200);
|
|
|
|
}
|
2011-02-22 02:20:33 +08:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2010-08-07 00:52:26 +08:00
|
|
|
function with_reqs(reqs, acc, fun) {
|
2010-09-02 19:58:34 +08:00
|
|
|
if (keys(reqs).length > 0) {
|
|
|
|
var key = keys(reqs)[0];
|
2011-02-22 22:00:20 +08:00
|
|
|
with_req('GET', reqs[key], null, function(resp) {
|
2010-08-31 23:44:12 +08:00
|
|
|
acc[key] = jQuery.parseJSON(resp.responseText);
|
|
|
|
var remainder = {};
|
|
|
|
for (var k in reqs) {
|
|
|
|
if (k != key) remainder[k] = reqs[k];
|
|
|
|
}
|
|
|
|
with_reqs(remainder, acc, fun);
|
2010-08-07 00:52:26 +08:00
|
|
|
});
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
fun(acc);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-07-13 00:31:16 +08:00
|
|
|
function replace_content(id, html) {
|
2011-01-28 19:12:29 +08:00
|
|
|
$("#" + id).html(html);
|
2010-07-13 00:31:16 +08:00
|
|
|
}
|
|
|
|
|
2010-07-12 22:04:42 +08:00
|
|
|
function format(template, json) {
|
|
|
|
try {
|
2010-08-27 23:18:41 +08:00
|
|
|
var tmpl = new EJS({url: 'js/tmpl/' + template + '.ejs'});
|
2010-07-17 00:38:06 +08:00
|
|
|
return tmpl.render(json);
|
2010-07-12 22:04:42 +08:00
|
|
|
} catch (err) {
|
2010-09-29 22:59:39 +08:00
|
|
|
clearInterval(timer);
|
2010-08-23 23:32:17 +08:00
|
|
|
debug(err['name'] + ": " + err['message']);
|
2010-07-12 22:04:42 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-08-31 23:44:12 +08:00
|
|
|
function update_status(status) {
|
2010-07-13 00:31:16 +08:00
|
|
|
var text;
|
|
|
|
if (status == 'ok')
|
2011-01-14 19:45:45 +08:00
|
|
|
text = "Last update: " + fmt_date(new Date());
|
2011-01-14 19:33:34 +08:00
|
|
|
else if (status == 'error') {
|
|
|
|
var next_try = new Date(new Date().getTime() + timer_interval);
|
|
|
|
text = "Error: could not connect to server since " +
|
2011-01-14 19:45:45 +08:00
|
|
|
fmt_date(last_successful_connect) + ".<br/>Will retry at " +
|
|
|
|
fmt_date(next_try) + ".";
|
2011-01-14 19:33:34 +08:00
|
|
|
}
|
2010-09-29 22:59:39 +08:00
|
|
|
else
|
|
|
|
throw("Unknown status " + status);
|
2010-07-13 00:31:16 +08:00
|
|
|
|
2010-07-17 00:38:06 +08:00
|
|
|
var html = format('status', {status: status, text: text});
|
2010-07-13 00:31:16 +08:00
|
|
|
replace_content('status', html);
|
|
|
|
}
|
|
|
|
|
2011-02-22 22:00:20 +08:00
|
|
|
function with_req(method, path, body, fun) {
|
2010-07-12 22:04:42 +08:00
|
|
|
var json;
|
2010-09-03 20:23:04 +08:00
|
|
|
var req = xmlHttpRequest();
|
2011-06-08 00:25:00 +08:00
|
|
|
req.open(method, 'api' + path, true );
|
2010-07-12 22:04:42 +08:00
|
|
|
req.onreadystatechange = function () {
|
|
|
|
if (req.readyState == 4) {
|
2011-03-16 19:34:55 +08:00
|
|
|
if (check_bad_response(req, true)) {
|
2011-01-14 19:33:34 +08:00
|
|
|
last_successful_connect = new Date();
|
2010-08-31 23:44:12 +08:00
|
|
|
fun(req);
|
2010-07-12 22:04:42 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
2011-02-22 22:00:20 +08:00
|
|
|
req.send(body);
|
2010-07-12 22:04:42 +08:00
|
|
|
}
|
2010-07-13 20:03:36 +08:00
|
|
|
|
2010-09-08 23:27:34 +08:00
|
|
|
function sync_get(path) {
|
|
|
|
return sync_req('GET', [], path);
|
|
|
|
}
|
|
|
|
|
2010-08-25 01:46:30 +08:00
|
|
|
function sync_put(sammy, path_template) {
|
2010-09-09 01:00:32 +08:00
|
|
|
return sync_req('PUT', sammy.params, path_template);
|
2010-08-25 01:46:30 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
function sync_delete(sammy, path_template) {
|
2010-09-09 01:00:32 +08:00
|
|
|
return sync_req('DELETE', sammy.params, path_template);
|
2010-08-25 01:46:30 +08:00
|
|
|
}
|
|
|
|
|
2010-09-02 00:26:51 +08:00
|
|
|
function sync_post(sammy, path_template) {
|
2010-09-09 01:00:32 +08:00
|
|
|
return sync_req('POST', sammy.params, path_template);
|
2010-09-02 00:26:51 +08:00
|
|
|
}
|
|
|
|
|
2010-10-12 21:08:17 +08:00
|
|
|
function sync_req(type, params0, path_template) {
|
2011-03-09 02:43:14 +08:00
|
|
|
var params;
|
2010-10-15 01:09:36 +08:00
|
|
|
var path;
|
|
|
|
try {
|
2011-03-09 02:43:14 +08:00
|
|
|
params = params_magic(params0);
|
2010-10-15 01:09:36 +08:00
|
|
|
path = fill_path_template(path_template, params);
|
|
|
|
} catch (e) {
|
2011-01-17 21:25:21 +08:00
|
|
|
show_popup('warn', e);
|
2010-10-15 01:09:36 +08:00
|
|
|
return false;
|
|
|
|
}
|
2010-09-03 20:23:04 +08:00
|
|
|
var req = xmlHttpRequest();
|
2011-06-08 00:25:00 +08:00
|
|
|
req.open(type, 'api' + path, false);
|
2010-08-24 01:32:33 +08:00
|
|
|
req.setRequestHeader('content-type', 'application/json');
|
2010-09-03 20:23:04 +08:00
|
|
|
try {
|
2010-09-29 14:18:23 +08:00
|
|
|
if (type == 'GET')
|
|
|
|
req.send(null);
|
|
|
|
else
|
|
|
|
req.send(JSON.stringify(params));
|
2010-09-03 20:23:04 +08:00
|
|
|
}
|
|
|
|
catch (e) {
|
|
|
|
if (e.number == 0x80004004) {
|
|
|
|
// 0x80004004 means "Operation aborted."
|
|
|
|
// http://support.microsoft.com/kb/186063
|
|
|
|
// MSIE6 appears to do this in response to HTTP 204.
|
|
|
|
}
|
|
|
|
}
|
2010-08-24 01:32:33 +08:00
|
|
|
|
2011-03-16 19:34:55 +08:00
|
|
|
if (check_bad_response(req, false)) {
|
2011-03-16 19:11:13 +08:00
|
|
|
if (type == 'GET')
|
|
|
|
return req.responseText;
|
|
|
|
else
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else {
|
2010-09-09 01:00:32 +08:00
|
|
|
return false;
|
|
|
|
}
|
2011-03-16 19:11:13 +08:00
|
|
|
}
|
2010-09-09 01:00:32 +08:00
|
|
|
|
2011-03-16 19:34:55 +08:00
|
|
|
function check_bad_response(req, full_page_404) {
|
2010-09-03 20:23:04 +08:00
|
|
|
// 1223 == 204 - see http://www.enhanceie.com/ie/bugs.asp
|
|
|
|
// MSIE7 and 8 appear to do this in response to HTTP 204.
|
2011-03-16 19:11:13 +08:00
|
|
|
if ((req.status >= 200 && req.status < 300) || req.status == 1223) {
|
|
|
|
return true;
|
|
|
|
}
|
2011-03-16 19:34:55 +08:00
|
|
|
else if (req.status == 404 && full_page_404) {
|
|
|
|
var html = format('404', {});
|
|
|
|
replace_content('main', html);
|
|
|
|
}
|
|
|
|
else if (req.status >= 400 && req.status <= 404) {
|
2011-03-16 19:11:13 +08:00
|
|
|
var reason = JSON.parse(req.responseText).reason;
|
|
|
|
if (typeof(reason) != 'string') reason = JSON.stringify(reason);
|
|
|
|
show_popup('warn', reason);
|
|
|
|
}
|
|
|
|
else if (req.status == 408) {
|
|
|
|
update_status('timeout');
|
|
|
|
}
|
|
|
|
else if (req.status == 0) { // Non-MSIE: could not connect
|
|
|
|
update_status('error');
|
|
|
|
}
|
|
|
|
else if (req.status > 12000) { // MSIE: could not connect
|
|
|
|
update_status('error');
|
|
|
|
}
|
2011-08-12 01:21:48 +08:00
|
|
|
else if (req.status == 503) { // Proxy: could not connect
|
|
|
|
update_status('error');
|
|
|
|
}
|
2011-03-16 19:11:13 +08:00
|
|
|
else {
|
2010-08-25 00:13:47 +08:00
|
|
|
debug("Got response code " + req.status + " with body " +
|
|
|
|
req.responseText);
|
2011-03-16 19:11:13 +08:00
|
|
|
clearInterval(timer);
|
2010-08-24 01:32:33 +08:00
|
|
|
}
|
2010-09-08 23:27:34 +08:00
|
|
|
|
2011-03-16 19:11:13 +08:00
|
|
|
return false;
|
2010-08-24 01:32:33 +08:00
|
|
|
}
|
2010-07-13 20:03:36 +08:00
|
|
|
|
2010-08-25 01:46:30 +08:00
|
|
|
function fill_path_template(template, params) {
|
|
|
|
var re = /:[a-zA-Z_]*/g;
|
|
|
|
return template.replace(re, function(m) {
|
2010-10-15 01:09:36 +08:00
|
|
|
var str = esc(params[m.substring(1)]);
|
|
|
|
if (str == '') {
|
|
|
|
throw(m.substring(1) + " is required");
|
|
|
|
}
|
|
|
|
return str;
|
2010-08-25 01:46:30 +08:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2010-12-09 01:40:10 +08:00
|
|
|
function params_magic(params) {
|
2011-03-09 02:43:14 +08:00
|
|
|
return check_password(
|
2011-05-25 22:50:31 +08:00
|
|
|
add_known_arguments(
|
|
|
|
maybe_remove_fields(
|
2011-05-25 20:51:05 +08:00
|
|
|
collapse_multifields(params))));
|
2010-12-09 01:40:10 +08:00
|
|
|
}
|
|
|
|
|
2010-10-12 21:08:17 +08:00
|
|
|
function collapse_multifields(params0) {
|
|
|
|
var params = {};
|
|
|
|
for (key in params0) {
|
|
|
|
var match = key.match(/([a-z]*)_([0-9]*)_mfkey/);
|
|
|
|
var match2 = key.match(/[a-z]*_[0-9]*_mfvalue/);
|
|
|
|
if (match == null && match2 == null) {
|
|
|
|
params[key] = params0[key];
|
|
|
|
}
|
|
|
|
else if (match == null) {
|
|
|
|
// Do nothing, value is handled below
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
var name = match[1];
|
|
|
|
var id = match[2];
|
|
|
|
if (params[name] == undefined) {
|
|
|
|
params[name] = {};
|
|
|
|
}
|
|
|
|
if (params0[key] != "") {
|
|
|
|
var k = params0[key];
|
|
|
|
var v = params0[name + '_' + id + '_mfvalue'];
|
2012-05-02 00:39:07 +08:00
|
|
|
var t = params0[name + '_' + id + '_mftype'];
|
|
|
|
if (t == 'boolean') {
|
|
|
|
if (v != 'true' && v != 'false')
|
|
|
|
throw(k + ' must be "true" or "false"; got ' + v);
|
|
|
|
params[name][k] = (v == 'true');
|
|
|
|
}
|
|
|
|
else if (t == 'number') {
|
|
|
|
var n = parseFloat(v);
|
|
|
|
if (isNaN(n))
|
|
|
|
throw(k + ' must be a number; got ' + v);
|
|
|
|
params[name][k] = n;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
params[name][k] = v;
|
|
|
|
}
|
2010-10-12 21:08:17 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return params;
|
|
|
|
}
|
|
|
|
|
2011-05-25 20:51:05 +08:00
|
|
|
function add_known_arguments(params) {
|
|
|
|
for (var k in KNOWN_ARGS) {
|
|
|
|
var v = params[k];
|
|
|
|
if (v != undefined && v != '') {
|
|
|
|
var type = KNOWN_ARGS[k].type;
|
|
|
|
if (type == 'int') {
|
|
|
|
v = parseInt(v);
|
2011-08-19 00:14:51 +08:00
|
|
|
if (isNaN(v)) {
|
|
|
|
throw(k + " must be an integer.");
|
|
|
|
}
|
2011-05-25 20:51:05 +08:00
|
|
|
}
|
2011-05-25 22:50:31 +08:00
|
|
|
else if (type == 'array' && typeof(v) == 'string') {
|
2011-05-25 20:51:05 +08:00
|
|
|
v = v.split(' ');
|
|
|
|
}
|
|
|
|
params.arguments[k] = v;
|
|
|
|
}
|
2011-05-25 22:50:31 +08:00
|
|
|
delete params[k];
|
2011-05-25 20:51:05 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return params;
|
|
|
|
}
|
|
|
|
|
2011-03-09 02:43:14 +08:00
|
|
|
function check_password(params) {
|
|
|
|
if (params['password'] != undefined) {
|
2012-03-08 21:17:16 +08:00
|
|
|
if (params['password'] == '') {
|
|
|
|
throw("Please specify a password.");
|
|
|
|
}
|
2011-03-09 02:43:14 +08:00
|
|
|
if (params['password'] != params['password_confirm']) {
|
|
|
|
throw("Passwords do not match.");
|
|
|
|
}
|
|
|
|
delete params['password_confirm'];
|
|
|
|
}
|
|
|
|
|
|
|
|
return params;
|
|
|
|
}
|
|
|
|
|
2011-05-25 22:50:31 +08:00
|
|
|
function maybe_remove_fields(params) {
|
|
|
|
$('.controls-appearance').each(function(index) {
|
|
|
|
if ($(this).val() == 'false') {
|
|
|
|
delete params[$(this).attr('param-name')];
|
|
|
|
delete params[$(this).attr('name')];
|
|
|
|
}
|
|
|
|
});
|
2010-12-09 01:40:10 +08:00
|
|
|
return params;
|
|
|
|
}
|
|
|
|
|
2010-07-13 20:03:36 +08:00
|
|
|
function debug(str) {
|
|
|
|
$('<p>' + str + '</p>').appendTo('#debug');
|
2010-09-02 19:58:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
function keys(obj) {
|
|
|
|
var ks = [];
|
|
|
|
for (var k in obj) {
|
|
|
|
ks.push(k);
|
|
|
|
}
|
|
|
|
return ks;
|
2010-09-03 20:23:04 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Don't use the jQuery AJAX support, it seemss to have trouble reporting
|
|
|
|
// server-down type errors.
|
|
|
|
function xmlHttpRequest() {
|
|
|
|
var res;
|
|
|
|
try {
|
|
|
|
res = new XMLHttpRequest();
|
|
|
|
}
|
|
|
|
catch(e) {
|
|
|
|
res = new ActiveXObject("Microsoft.XMLHttp");
|
|
|
|
}
|
|
|
|
return res;
|
2010-09-09 01:00:32 +08:00
|
|
|
}
|
2010-10-16 01:11:42 +08:00
|
|
|
|
|
|
|
(function($){
|
|
|
|
$.fn.extend({
|
|
|
|
center: function () {
|
|
|
|
return this.each(function() {
|
|
|
|
var top = ($(window).height() - $(this).outerHeight()) / 2;
|
|
|
|
var left = ($(window).width() - $(this).outerWidth()) / 2;
|
|
|
|
$(this).css({margin:0, top: (top > 0 ? top : 0)+'px', left: (left > 0 ? left : 0)+'px'});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
})(jQuery);
|