/** * Copyright (c) 2016 Weitian LI * MIT license * * JavaScript codes for the Web UI of "fg21sim" */ "use strict"; /** * jQuery settings */ jQuery.ajaxSetup({ error: function (error) { console.error("AJAX request failed: code:", error.status, ", reason:", error.statusText); } }); /** * Common functions that will be used by other scripts */ /** * Get the value of a key stored in the cookie * * @param {String} name - Name of the key * * @return {String} - The value of the key; `undefined` if the key not exists * * Credit: * http://www.tornadoweb.org/en/stable/guide/security.html */ var getCookie = function (name) { var m = document.cookie.match("\\b" + name + "=([^;]*)\\b"); return m ? m[1] : undefined; }; /** * jQuery extension for easier AJAX JSON post * * NOTE: The XSRF token is extracted from the cookie and posted together. * * @param {String} url - The URL that handles the AJAX requests * @param {Object} data - Data of key-value pairs to be posted * @param {Function} callback - Function to be called when AJAX succeeded */ jQuery.postJSON = function (url, data, callback) { return jQuery.ajax({ url: url, type: "POST", contentType: "application/json; charset=utf-8", // Tornado: `check_xsrf_cookie()` // Credit: https://stackoverflow.com/a/28924601/4856091 headers: {"X-XSRFToken": getCookie("_xsrf")}, data: JSON.stringify(data), success: function (response) { if (callback) { callback(response); } } }); }; /** * Scroll the page to adjust for the fixed navigation banner */ var scrollTarget = function (height) { if ($(":target").length) { var offset = $(":target").offset(); var scroll_to = offset.top - height * 1.2; $("html, body").animate({scrollTop: scroll_to}, 100); } }; /** * Toggle the display of the target block */ var toggleBlock = function (toggle, targetBlock) { if (targetBlock.is(":visible")) { targetBlock.slideUp("fast"); toggle.removeClass("fa-chevron-circle-up") .addClass("fa-chevron-circle-down") .attr("title", "Expand contents"); } else { targetBlock.slideDown("fast"); toggle.removeClass("fa-chevron-circle-down") .addClass("fa-chevron-circle-up") .attr("title", "Collapse contents"); } }; /** * Compose the notification contents and shown them in the modal box. * * The input `modalBox` may be a jQuery object or a jQuery selector of the * target modal box. * * The input `data` may have the following attributes: * - `icon` : FontAwesome icon (specified without the beginning `fa-`) * - `message` : Main summary message * - `code` : Error code if it is an error notification * - `reason` : Reason of the error * - `buttons` : A list of buttons, which have these attributes: * + `text` : Button name * + `class` : {String} Button classes * + `click` : {Function} Function called on click. * To close the modal, use `$.modal.close()` */ var showModal = function (modalBox, data) { modalBox = $(modalBox); // Empty previous contents modalBox.html(""); var p = $("

"); if (data.icon) { $("").addClass("fa fa-2x").addClass("fa-" + data.icon).appendTo(p); } if (data.message) { $("").text(" " + data.message).appendTo(p); } modalBox.append(p); if (data.code) { modalBox.append($("

Error Code:

") .append($("") .addClass("label label-warning") .text(data.code))); } if (data.reason) { modalBox.append($("

Reason:

") .append($("") .addClass("label label-warning") .text(data.reason))); } if (data.buttons) { p = $("

").addClass("button-group"); data.buttons.forEach(function (btn) { $("