User = { disable_samples: function() { new Ajax.Request("/user/update.json", { parameters: { "user[show_samples]": false }, onComplete: function(resp) { var resp = resp.responseJSON if (resp.success) { $("resized_notice").hide(); $("samples_disabled").show(); Post.highres(); } else { notice("Error: " + resp.reason) } } }) }, destroy: function(id) { notice("Deleting record #" + id) new Ajax.Request("/user_record/destroy.json", { parameters: { "id": id }, onComplete: function(resp) { if (resp.status == 200) { notice("Record deleted") } else { notice("Access denied") } } }) }, current_check: null, cancel_check: function() { current_check = null; }, /* If background is true, this is a request being made as an indirect result of other * input; these can be cancelled (rather, the result is ignord) and are automatically * cancelled if another is started while a previous one is still running. * * If background is false, this is an explicit user action (user submitted the form) * and the action must not be cancelled by unrelated background actions. */ reset_password: function(username, email, func) { var new_check = new Ajax.Request("/user/reset_password.json", { parameters: { "user[name]": username, "user[email]": email }, onComplete: function(resp) { var resp = resp.responseJSON; func(resp); } }); }, check: function(username, password, background, func) { var parameters = { "username": username } if(password) parameters.password = password; var new_check = new Ajax.Request("/user/check.json", { parameters: parameters, onSuccess: function(resp) { if(background && resp.request != current_check) return; current_check = null; var resp = resp.responseJSON; func(resp); } }); if(background) current_check = new_check; }, create: function(username, password, email, func) { var parameters = { "user[name]": username, "user[password]": password } if(email) parameters["user[email]"] = email; var new_check = new Ajax.Request("/user/create.json", { parameters: parameters, onComplete: function(resp) { var resp = resp.responseJSON; func(resp); } }); }, set_login: function(username, pass_hash, user_info) { Cookie.put("login", username) Cookie.put("pass_hash", pass_hash) Cookie.put("user_info", user_info) }, check_name_timer: null, last_username_in_form: null, success_func: null, messages: [], init: function() { $("login-popup-notices").select("SPAN").each(function(e) { User.messages.push(e.id); }); /* * IE makes us jump lots of hoops. We have to watch submit events on every object * instead of just window because IE doesn't support event capturing. We have to * override the submit method in every form to catch programmatic submits, because * IE doesn't seem to support initiating events by firing them. * * Also, since we can't capture events, we need to be sure our submit event is done * before other handlers, so if we cancel the event, we prevent other event handlers * from continuing. However, we need to attach after forms have been created. So, * this needs to be run as an early DOMLoaded event, and any other code that attaches * submit events to code needs to be run in a later DOMLoaded event (or later events). * */ $$("FORM.need-signup").each(function(form) { form.observe("submit", User.run_login_onsubmit); }); /* If you select an item from the history dropdown in IE7, change events never fire, so * use keyup instead. This isn't a problem with password fields, since there's no history * dropdown. */ $("login-popup").observe("submit", function(e) { e.stop(); User.form_submitted(); }); $("login-popup-submit").observe("click", function(e) { e.stop(); User.form_submitted(); }); $("login-popup-cancel").observe("click", function(e) { e.stop(); User.close(false); }); $("login-popup-username").observe("blur", function(e) { User.form_username_blur(); }); $("login-popup-username").observe("focus", function(e) { User.form_username_focus(); }); $("login-popup-username").observe("keyup", function(e) { User.form_username_changed(true); }); $("login-tabs").select("LI").each(function(a) { a.observe("mousedown", function(e) { e.stop(); }); }); $("login-tabs").select("LI").each(function(a) { a.observe("click", function(e) { e.stop(); User.set_tab(a.id); }); }); /* IE and FF are glitchy with form submission: they fail to submit forms unless * there's an somewhere in the form. IE is even worse: * even if there is one, if it's hidden on page load (including if it's a parent * element hidden), it'll never submit the form, even if it's shown later. Don't * rely on this behavior; just catch enter presses and submit the form explicitly. */ OnKey(13, {AllowInputFields: true, Element: $("login-popup")}, function(e) { e.stop(); User.form_submitted(); }); /* Escape closes the login box. */ OnKey(27, {AllowInputFields: true, AlwaysAllowOpera: true}, function(e) { if(!User.success_func) return false; User.close(false); return true; }); }, open: function(success) { if(User.success_func) User.close(false); User.success_func = success; $("login-background").show(); $("login-container").show(); User.set_tab("tab-login"); }, close: function(run_success_func) { if(!User.success_func) return; $("login-background").hide(); $("login-container").hide(); User.active_tab = null; User.check_name_timer = null; var func = User.success_func; User.success_func = null; success_func = null; if(run_success_func) window.setTimeout(func, 0); }, /* Handle login from an onclick. If login is not needed, return true. Otherwise, * start the login, and return false; the object will receive another click when * the login is successful. */ run_login_onclick: function(event) { event = Event.extend(event); /* event.target is not copied by clone_event. */ var target = $(event.target); /* event is not available when we get to the callback in IE7. */ var e = clone_event(event); if(User.run_login(true, function() { if(target.hasClassName("login-button")) { /* This is a login button, and not an action that happened to need login. After * a successful login, don't click the button; that'll just go to the login page. * Instead, just reload the current page. */ Cookie.put("notice", "You have been logged in."); document.location.reload(); return; } target.simulate_anchor_click(e); })) return true; /* Login is running, so stop the event. Don't just return false; call stop(), so * event.stopped is available to the caller if we've been sent this message via * Element.dispatchEvent. */ event.stop(); return false; }, /* Handle login from an onsubmit. If login is needed, stop the event and resubmit * it when the login completes. If login is not needed, return and let the submit * complete normally. */ run_login_onsubmit: function(event) { /* Set skip_complete_on_true, so if we don't need to login, we don't resubmit the * event; we just don't cancel it. */ var target = $(event.target); if(!User.run_login(true, function() { target.simulate_submit(); })) event.stop(); }, /* Handle login. If we're already logged in, run complete (unless only_complete_on_login * is true) and return true. If we need to log in, start the login dialog; it'll call * complete() on successful login. */ run_login: function(only_complete_on_login, complete) { if(Cookie.get("login") != "") { if(!only_complete_on_login) complete(); return true; } User.open(complete); return false; }, active_tab: null, set_tab: function(tab) { if(User.active_tab == tab) return; User.active_tab = tab; User.check_name_timer = null; User.last_username_in_form = null; $("login-tabs").select("LI").each(function(li) { li.removeClassName("selected"); }); $("login-tabs").down("#" + tab).addClassName("selected"); $$(".tab-header-text").each(function(li) { li.hide(); }); $(tab + "-text").show(); if(tab == "tab-login") { /* If the user's browser fills in a username but no password, focus the password. Otherwise, * focus the username. */ if($("login-popup-password").value == "" && $("login-popup-username").value != "") $("login-popup-password").focus(); else $("login-popup-username").focus(); User.set_state("login-blank"); } else if(tab == "tab-reset") { User.set_state("reset-blank"); $("login-popup-username").focus(); } User.form_username_changed(); }, message: function(text) { for (var i = 0, l = User.messages.length; i < l; i++) { var elem = User.messages[i]; $(elem).hide(); } $("login-popup-message").update(text); $("login-popup-message").show(); }, set_state: function(state) { var show = {}; if(state.match(/^login-/)) { show["login-popup-password-box"] = true; if(state == "login-blank") $("login-popup-submit").update("Login"); else if(state == "login-user-exists") $("login-popup-submit").update("Login"); else if(state == "login-confirm-password") { show["login-popup-password-confirm-box"] = true; $("login-popup-submit").update("Create account"); } else if(state == "login-confirm-password-mismatch") $("login-popup-submit").update("Create account"); show["login-popup-" + state] = true; } else if(state.match(/^reset-/)) { show["login-popup-email-box"] = true; $("login-popup-submit").update("Reset password"); show["login-popup-" + state] = true; } var all = ["login-popup-email-box", "login-popup-password-box", "login-popup-password-confirm-box"].concat(User.messages); current_state = state; for (var i = 0, l = all.length; i < l; i++) { var elem = all[i]; if(show[elem]) $(elem).show(); else $(elem).hide(); } }, pending_username: null, form_username_changed: function(keyup) { var username = $("login-popup-username").value; if(username == User.last_username_in_form) return; User.last_username_in_form = username; User.cancel_check(); if(User.check_name_timer) window.clearTimeout(User.check_name_timer); User.pending_username = null; if(username == "") { if(User.active_tab == "tab-login") User.set_state("login-blank"); else if(User.active_tab == "tab-reset") User.set_state("reset-blank"); return; } /* Delay on keyup, so we don't send tons of requests. Don't delay otherwise, * so we don't introduce lag when we don't have to. */ var ms = 500; if(!keyup && User.check_name_timer) ms = 0; /* * Make sure the UI is still usable if this never finished. This way, we don't * lag the interface if these JSON requests are taking longer than usual; you should * be able to click "login" immediately as soon as a username and password are entered. * Entering a username and password and clicking "login" should still behave properly * if the username doesn't exist and the check_name_timer JSON request hasn't come * back yet. * * If the state isn't "blank", the button is already enabled. */ User.check_name_timer = window.setTimeout(function() { User.check_name_timer = null; User.check(username, null, true, function(resp) { if(resp.exists) { /* Update the username to match the actual user's case. If the form contents have * changed since we started this check, don't do this. (We cancel this event if we * see the contents change, but the contents can change without this event firing * at all.) */ var current_username = $("login-popup-username").value; if(current_username == username) { /* If the element doesn't have focus, change the text to match. If it does, wait * until it loses focus, so it doesn't interfere with the user editing it. */ if(!$("login-popup").focused) $("login-popup-username").value = resp.name; else User.pending_username = resp.name; } } if(User.active_tab == "tab-login") { if(!resp.exists) { User.set_state("login-confirm-password"); return; } else User.set_state("login-user-exists"); } else if(User.active_tab == "tab-reset") { if(!resp.exists) User.set_state("reset-blank"); else if(resp.no_email) User.set_state("reset-user-has-no-email"); else User.set_state("reset-user-exists"); } }); }, ms); }, form_username_focus: function() { $("login-popup").focused = true; }, form_username_blur: function() { $("login-popup").focused = false; /* When the username field loses focus, update the username case to match the * result we got back from check(), if any. */ if(User.pending_username) { $("login-popup").username.value = User.pending_username; User.pending_username = null; } /* We watch keyup on the username, because change events are unreliable in IE; update * when focus is lost, too, so we see changes made without using the keyboard. */ User.form_username_changed(false); }, form_submitted: function() { User.cancel_check(); if(User.check_name_timer) window.clearTimeout(User.check_name_timer); var username = $("login-popup-username").value; var password = $("login-popup-password").value; var password_confirm = $("login-popup-password-confirm").value; var email = $("login-popup-email").value; if(username == "") return; if(User.active_tab == "tab-login") { if(password == "") { User.message("Please enter a password."); return; } if(current_state == "login-confirm-password") { if(password != password_confirm) User.message("The passwords you've entered don't match."); else { // create account User.create(username, password, null, function(resp) { if(resp.response == "success") { User.set_login(resp.name, resp.pass_hash, resp.user_info); User.close(true); } else if(resp.response == "error") { User.message(resp.errors.join("
")) } }); } return; } User.check(username, password, false, function(resp) { if(!resp.exists) { User.set_state("login-confirm-password"); return; } /* We've authenticated successfully. Our hash is in password_hash; insert the * login cookies manually. */ if(resp.response == "wrong-password") { notice("Incorrect password"); return; } User.set_login(resp.name, resp.pass_hash, resp.user_info); User.close(true); }); } else if(User.active_tab == "tab-reset") { if(email == "") return; User.reset_password(username, email, function(resp) { if(resp.result == "success") User.set_state("reset-successful"); else if(resp.result == "unknown-user") User.set_state("reset-unknown-user"); else if(resp.result == "wrong-email") User.set_state("reset-user-email-incorrect"); else if(resp.result == "no-email") User.set_state("reset-user-has-no-email"); else if(resp.result == "invalid-email") User.set_state("reset-user-email-invalid"); }); } }, modify_blacklist: function(add, remove, success) { new Ajax.Request("/user/modify_blacklist.json", { parameters: { "add[]": add, "remove[]": remove }, onComplete: function(resp) { var resp = resp.responseJSON; if (resp.success) { if(success) success(resp); } else { notice("Error: " + resp.reason); } } }); }, set_pool_browse_mode: function(browse_mode) { new Ajax.Request("/user/update.json", { parameters: { "user[pool_browse_mode]": browse_mode }, onComplete: function(resp) { var resp = resp.responseJSON; if (resp.success) { window.location.reload(); } else { notice("Error: " + resp.reason); } } }); }, get_current_user_info: function() { var user_info = Cookie.get("user_info"); if(!user_info) return null; return user_info.split(";"); }, get_current_user_info_field: function(idx, def) { var user_info = User.get_current_user_info(); if(!user_info) return def; if(idx >= user_info.length) return def; return user_info[idx]; }, get_current_user_id: function() { return parseInt(User.get_current_user_info_field(0, 0)); }, get_current_user_level: function() { return parseInt(User.get_current_user_info_field(1, 0)); }, get_use_browser: function() { var setting = User.get_current_user_info_field(2, "0"); return setting == "1"; }, is_member_or_higher: function() { return User.get_current_user_level() >= 20; }, is_mod_or_higher: function() { return User.get_current_user_level() >= 40; } }