From 39dc175b88fe7e76770708c96bad9915c1eaa893 Mon Sep 17 00:00:00 2001 From: Aaron LI Date: Mon, 28 Nov 2016 12:28:12 +0800 Subject: webui: Some JavaScript cleanups and refactors Credit: "JavaScript: The Good Parts" by Douglas Crockford --- fg21sim/webui/static/js/configs.js | 220 ++++++++++++++++++----------------- fg21sim/webui/static/js/console.js | 91 +++++++-------- fg21sim/webui/static/js/main.js | 10 +- fg21sim/webui/static/js/products.js | 125 ++++++++++---------- fg21sim/webui/static/js/websocket.js | 56 +++++---- 5 files changed, 258 insertions(+), 244 deletions(-) (limited to 'fg21sim/webui/static/js') diff --git a/fg21sim/webui/static/js/configs.js b/fg21sim/webui/static/js/configs.js index a3d3be6..5dcd026 100644 --- a/fg21sim/webui/static/js/configs.js +++ b/fg21sim/webui/static/js/configs.js @@ -22,7 +22,7 @@ * @param {String} error - The custom error message to be set for the field */ var setFormConfigErrorSingle = function (name, error) { - var selector = null; + var selector; if (name === "userconfig") { selector = "input[name=configfile]"; } else { @@ -57,11 +57,11 @@ var clearFormConfigErrors = function () { /** * Reset the configuration form to its defaults as written in the HTML. + * + * Credit: http://stackoverflow.com/a/6364313 */ var resetFormConfigs = function () { - // Credit: http://stackoverflow.com/a/6364313 $("#conf-form")[0].reset(); - // Clear previously marked errors clearFormConfigErrors(); }; @@ -77,9 +77,9 @@ var resetFormConfigs = function () { * + `undefined` if the field does not exists */ var getFormConfigSingle = function (name) { - var value = null; + var value = undefined; if (! name) { - // do nothing + console.error("Invalid name:", name); } else if (name === "userconfig") { value = joinPath($("input[name=workdir]").val(), $("input[name=configfile]").val()); @@ -285,10 +285,11 @@ var showModalConfigs = function (data) { */ var getServerConfigs = function (url, keys) { keys = typeof keys !== "undefined" ? keys : null; - return $.getJSONUncached(url, {action: "get", keys: JSON.stringify(keys)}, - function (response) { - setFormConfigs(response.data, {}); - }); + return $.getJSONUncached( + url, {action: "get", keys: JSON.stringify(keys)}, + function (response) { + setFormConfigs(response.data, {}); + }); }; @@ -297,10 +298,11 @@ var getServerConfigs = function (url, keys) { * and mark the corresponding form fields to be invalid with details. */ var validateServerConfigs = function (url) { - return $.getJSONUncached(url, {action: "validate"}, - function (response) { - setFormConfigs({}, response.errors); - }); + return $.getJSONUncached( + url, {action: "validate"}, + function (response) { + setFormConfigs({}, response.errors); + }); }; @@ -320,19 +322,19 @@ var resetConfigs = function (url) { // Update the configuration status label updateFormConfigStatus(); // Popup a modal notification - var modalData = {}; - modalData.icon = "check-circle"; - modalData.contents = "Reset and synchronized the configurations."; - showModalConfigs(modalData); + showModalConfigs({ + icon: "check-circle", + contents: "Reset and synchronized the configurations." + }); }); }) .fail(function (jqxhr) { - var modalData = {}; - modalData.icon = "times-circle"; - modalData.contents = "Failed to reset the configurations!"; - modalData.code = jqxhr.status; - modalData.reason = jqxhr.statusText; - showModalConfigs(modalData); + showModalConfigs({ + icon: "times-circle", + contents: "Failed to reset the configurations!", + code: jqxhr.status, + reason: jqxhr.statusText + }); }); }; @@ -351,17 +353,18 @@ var resetConfigs = function (url) { */ var setServerConfigs = function (url, data) { data = typeof data !== "undefined" ? data : {}; - return $.postJSON(url, {action: "set", data: data}, - function (response) { - setFormConfigs(response.data, response.errors); - }) + return $.postJSON( + url, {action: "set", data: data}, + function (response) { + setFormConfigs(response.data, response.errors); + }) .fail(function (jqxhr) { - var modalData = {}; - modalData.icon = "times-circle"; - modalData.contents = "Failed to update/set the configuration data!"; - modalData.code = jqxhr.status; - modalData.reason = jqxhr.statusText; - showModalConfigs(modalData); + showModalConfigs({ + icon: "times-circle", + contents: "Failed to update/set the configuration data!", + code: jqxhr.status, + reason: jqxhr.statusText + }); }); }; @@ -380,12 +383,12 @@ var loadServerConfigFile = function (url, userconfig) { } return $.postJSON(url, {action: "load", userconfig: userconfig}) .fail(function (jqxhr) { - var modalData = {}; - modalData.icon = "times-circle"; - modalData.contents = "Failed to load the user configuration file!"; - modalData.code = jqxhr.status; - modalData.reason = jqxhr.statusText; - showModalConfigs(modalData); + showModalConfigs({ + icon: "times-circle", + contents: "Failed to load the user configuration file!", + code: jqxhr.status, + reason: jqxhr.statusText + }); }); }; @@ -399,9 +402,11 @@ var loadServerConfigFile = function (url, userconfig) { var saveServerConfigFile = function (url, clobber) { clobber = typeof clobber !== "undefined" ? clobber : false; var userconfig = getFormConfigSingle("userconfig"); - var data = {action: "save", - outfile: userconfig, - clobber: clobber}; + var data = { + action: "save", + outfile: userconfig, + clobber: clobber + }; return $.postJSON(url, data) .done(function () { var modalData = {}; @@ -413,17 +418,17 @@ var saveServerConfigFile = function (url, clobber) { // Configurations is currently invalid! modalData.icon = "warning"; modalData.contents = ("Configurations saved to file. " + - "But there exist some invalid values!"); + "But there exist some invalid values!"); } showModalConfigs(modalData); }) .fail(function (jqxhr) { - var modalData = {}; - modalData.icon = "times-circle"; - modalData.contents = "Failed to save the configurations!"; - modalData.code = jqxhr.status; - modalData.reason = jqxhr.statusText; - showModalConfigs(modalData); + showModalConfigs({ + icon: "times-circle", + contents: "Failed to save the configurations!", + code: jqxhr.status, + reason: jqxhr.statusText + }); }); }; @@ -432,17 +437,19 @@ var saveServerConfigFile = function (url, clobber) { * Check whether the specified file already exists on the server? */ var existsServerFile = function (url, filepath, callback) { - var data = {action: "exists", - filepath: JSON.stringify(filepath)}; + var data = { + action: "exists", + filepath: JSON.stringify(filepath) + }; return $.getJSONUncached(url, data, callback) .fail(function (jqxhr) { - var modalData = {}; - modalData.icon = "times-circle"; - modalData.contents = ("Failed to check the existence " + - "of the user configuration file!"); - modalData.code = jqxhr.status; - modalData.reason = jqxhr.statusText; - showModalConfigs(modalData); + showModalConfigs({ + icon: "times-circle", + contents: ("Failed to check the existence " + + "of the user configuration file!"), + code: jqxhr.status, + reason: jqxhr.statusText + }); }); }; @@ -469,30 +476,30 @@ $(document).ready(function () { $("#conf-recheck").on("click", function () { var data = getFormConfigAll(); setServerConfigs(ajax_url, data) - .then(function () { validateServerConfigs(ajax_url); }) + .then(function () { return validateServerConfigs(ajax_url); }) .done(function () { updateFormConfigStatus(); }); }); // Reset both server-side and client-side configurations to the defaults $("#reset-defaults").on("click", function () { - var modalData = {}; - modalData.icon = "warning"; - modalData.contents = ("Are you sure to reset the configurations?"); - modalData.buttons = [ - { - text: "Cancel", - click: function () { $.modal.close(); } - }, - { - text: "Reset!", - "class": "button-warning", - click: function () { - $.modal.close(); - resetConfigs(ajax_url); + showModalConfigs({ + icon: "warning", + contents: "Are you sure to reset the configurations?", + buttons: [ + { + text: "Cancel", + click: function () { $.modal.close(); } + }, + { + text: "Reset!", + "class": "button-warning", // NOTE: "class" is a preserved keyword + click: function () { + $.modal.close(); + resetConfigs(ajax_url); + } } - }, - ]; - showModalConfigs(modalData); + ] + }); }); // Load the configurations from the specified user configuration file @@ -506,10 +513,10 @@ $(document).ready(function () { // Update the configuration status label updateFormConfigStatus(); // Popup a modal notification - var modalData = {}; - modalData.icon = "check-circle"; - modalData.contents = "Loaded the configurations from file."; - showModalConfigs(modalData); + showModalConfigs({ + icon: "check-circle", + contents: "Loaded the configurations from file." + }); }); }); @@ -520,26 +527,26 @@ $(document).ready(function () { if (response.data.exists) { // The specified configuration file already exists // Confirm to overwrite - var modalData = {}; - modalData.icon = "warning"; - modalData.contents = ("Configuration file already exists! Overwrite?"); - modalData.buttons = [ - { - text: "Cancel", - rel: "modal:close", - click: function () { $.modal.close(); } - }, - { - text: "Overwrite!", - "class": "button-warning", - rel: "modal:close", - click: function () { - $.modal.close(); - saveServerConfigFile(ajax_url, true); + showModalConfigs({ + icon: "warning", + contents: "Configuration file already exists! Overwrite?", + buttons: [ + { + text: "Cancel", + rel: "modal:close", + click: function () { $.modal.close(); } + }, + { + text: "Overwrite!", + "class": "button-warning", + rel: "modal:close", + click: function () { + $.modal.close(); + saveServerConfigFile(ajax_url, true); + } } - }, - ]; - showModalConfigs(modalData); + ] + }); } else { saveServerConfigFile(ajax_url, false); } @@ -548,8 +555,7 @@ $(document).ready(function () { // Sync changed field to server, validate and update form $("#conf-form input").on("change", function (e) { - console.log("Element changed:", e); - var name = $(e.target).attr("name"); + var name = e.target.name; var value = getFormConfigSingle(name); // Synchronize the changed form configuration to the server // NOTE: @@ -565,10 +571,11 @@ $(document).ready(function () { // Update the resolution note for field "common/nside" when press "Enter" $("#conf-form input[name='common/nside']").on("keypress", function (e) { + var nside, resolution; if (e.which === 13) { - var nside = parseInt($(this).val()); + nside = parseInt($(this).val(), 10); // Update the resolution note (unit: arcmin) - var resolution = Math.sqrt(3/Math.PI) * 3600 / nside; + resolution = Math.sqrt(3/Math.PI) * 3600 / nside; $(this).closest(".form-group").find(".note > .value") .text(resolution.toFixed(2)); } @@ -576,11 +583,12 @@ $(document).ready(function () { // Update the maximum multiple "common/lmax" when "common/nside" changed $("#conf-form input[name='common/nside']").on("change", function (e) { + var nside, lmax; // Update the resolution note $(this).trigger($.Event("keypress", {which: 13})); - var nside = parseInt($(this).val()); - if (! isNaN(nside)) { - var lmax = 3 * nside - 1; + nside = parseInt($(this).val(), 10); + if (isFinite(nside)) { + lmax = 3 * nside - 1; $("#conf-form input[name='common/lmax']").val(lmax).trigger("change"); } }); diff --git a/fg21sim/webui/static/js/console.js b/fg21sim/webui/static/js/console.js index 5100c7a..1e2a638 100644 --- a/fg21sim/webui/static/js/console.js +++ b/fg21sim/webui/static/js/console.js @@ -27,7 +27,7 @@ var showModalConsole = function (data) { var updateTaskStatus = function (status) { var running = status.running; var finished = status.finished; - var ts = null; + var ts; if (!running && !finished) { ts = "Not started"; $("#task-status").removeClass("label-success label-warning label-danger") @@ -102,14 +102,14 @@ var appendLogMessage = function (msg) { */ var toggleLogMessages = function (level) { var valid_levels = ["debug", "info", "warning", "error", "critical"]; - var status = null; + var status, logbox; if (! level) { console.error("toggleLogMessages: level not specified"); } else if ($.inArray(level.toLowerCase(), valid_levels) == -1) { console.error("toggleLogMessages: invalid level:", level); } else { level = level.toLowerCase(); - var logbox = $("#log-messages"); + logbox = $("#log-messages"); if (typeof logbox.data(level) === "undefined") { // No stored display status, assuming true: show status = true; @@ -147,12 +147,12 @@ var deleteLogMessages = function () { var getServerTaskStatus = function (url) { return $.getJSONUncached(url) .fail(function (jqxhr) { - var modalData = {}; - modalData.icon = "times-circle"; - modalData.contents = "Failed to get the task status!"; - modalData.code = jqxhr.status; - modalData.reason = jqxhr.statusText; - showModalConsole(modalData); + showModalConsole({ + icon: "times-circle", + contents: "Failed to get the task status!", + code: jqxhr.status, + reason: jqxhr.statusText + }); }); }; @@ -170,12 +170,12 @@ var startServerTask = function (url, task, kwargs) { var data = {action: "start", task: task, kwargs: kwargs}; return $.postJSON(url, data) .fail(function (jqxhr) { - var modalData = {}; - modalData.icon = "times-circle"; - modalData.contents = "Failed to start the task!"; - modalData.code = jqxhr.status; - modalData.reason = jqxhr.statusText; - showModalConsole(modalData); + showModalConsole({ + icon: "times-circle", + contents: "Failed to start the task!", + code: jqxhr.status, + reason: jqxhr.statusText + }); }); }; @@ -205,31 +205,26 @@ $(document).ready(function () { var button = $(this); if ($("#conf-status").data("validity")) { button.disable(true); - console.log("Disable button:", button[0]); updateTaskStatus({running: true, finished: false}); startServerTask(ajax_url) - .always(function () { - button.disable(false); - console.log("Enable button:", button[0]); - }) + .always(function () { button.disable(false); }) .done(function () { getServerTaskStatus(ajax_url) .done(function (response) { updateTaskStatus(response.status); - // Popup a modal notification - var modalData = {}; - modalData.icon = "check-circle"; - modalData.contents = "Simulation task successfully finished."; - showModalConfigs(modalData); + showModalConsole({ + icon: "check-circle", + contents: "Simulation task successfully finished." + }); }); }); } else { - var modalData = {}; - modalData.icon = "times-circle"; - modalData.contents = ("Exist invalid configuration values! " + - "Please correct the configurations " + - "before starting the task"); - showModalConsole(modalData); + showModalConsole({ + icon: "times-circle", + contents: ("Exist invalid configuration values! " + + "Please correct the configurations " + + "before starting the task") + }); console.error("Exist invalid configuration values!"); } }); @@ -255,23 +250,23 @@ $(document).ready(function () { $(this).fadeTo("fast", status ? 1.0 : 0.5); }); $("#log-delete").on("click", function () { - var modalData = {}; - modalData.icon = "warning"; - modalData.contents = "Are you sure to delete all logging messages?"; - modalData.buttons = [ - { - text: "Cancel", - click: function () { $.modal.close(); } - }, - { - text: "Delete!", - "class": "button-warning", - click: function () { - $.modal.close(); - deleteLogMessages(); + showModalConsole({ + icon: "warning", + contents: "Are you sure to delete all logging messages?", + buttons: [ + { + text: "Cancel", + click: function () { $.modal.close(); } + }, + { + text: "Delete!", + "class": "button-warning", + click: function () { + $.modal.close(); + deleteLogMessages(); + } } - }, - ]; - showModalConsole(modalData); + ] + }); }); }); diff --git a/fg21sim/webui/static/js/main.js b/fg21sim/webui/static/js/main.js index c725803..0383365 100644 --- a/fg21sim/webui/static/js/main.js +++ b/fg21sim/webui/static/js/main.js @@ -37,7 +37,7 @@ var dirname = function (path) { * FIXME: only support "/" as the path separator */ var joinPath = function (path1, path2) { - var p = null; + var p; // Strip the trailing path separator path1 = path1.replace(/\/$/, ""); if (path1 === "") { @@ -47,8 +47,8 @@ var joinPath = function (path1, path2) { } // Both "path1" and "path2" are empty if (p === "/") { - console.error("Both 'path1' and 'path2' are empty"); p = null; + console.error("Both 'path1' and 'path2' are empty"); } return p; }; @@ -203,10 +203,11 @@ var toggleBlock = function (toggle, targetBlock) { * To close the modal, use `$.modal.close()` */ var showModal = function (modalBox, data) { + var p; modalBox = $(modalBox); // Empty previous contents modalBox.html(""); - var p = $("

"); + p = $("

"); if (data.icon) { $("").addClass("icon fa") .addClass("fa-" + data.icon).appendTo(p); @@ -271,10 +272,11 @@ $(document).ready(function () { toggleBlock(toggle, body); }); - // Prevent from submitting form by "Enter" + // Prevent from submitting form on "Enter" keypress // Credit; https://stackoverflow.com/a/11235672/4856091 $("form").on("keypress", function (e) { if (e.which === 13) { + // Disable the default submit action e.preventDefault(); return false; } diff --git a/fg21sim/webui/static/js/products.js b/fg21sim/webui/static/js/products.js index 2cbd400..16303c7 100644 --- a/fg21sim/webui/static/js/products.js +++ b/fg21sim/webui/static/js/products.js @@ -76,17 +76,16 @@ var makeManifestTableCell = function (data, localhost) { var loadManifestToTable = function (manifest, localhost) { localhost = typeof localhost !== "undefined" ? localhost : false; - var frequency = manifest.frequency; - var components = Object.keys(manifest); + var frequency, components, table, row, cell, tbody; + frequency = manifest.frequency; + components = Object.keys(manifest); // Remove the `frequency` element components.splice(components.indexOf("frequency"), 1); // Reset the table first resetManifestTable(); - var table = $("table#products-manifest"); - var row; - var cell; + table = $("table#products-manifest"); // Table head row = $(""); row.append($("").text("Frequency (" + frequency.unit + ")")); @@ -96,7 +95,7 @@ var loadManifestToTable = function (manifest, localhost) { table.children("thead").append(row); // Table body - var tbody = table.children("tbody"); + tbody = table.children("tbody"); frequency.id.forEach(function (freqID) { // One table row for each frequency row = $(""); @@ -140,12 +139,12 @@ var loadServerManifest = function (url, manifestfile) { var data = {action: "load", manifestfile: manifestfile}; return $.postJSON(url, data) .fail(function (jqxhr) { - var modalData = {}; - modalData.icon = "times-circle"; - modalData.contents = "Failed to load the products manifest!"; - modalData.code = jqxhr.status; - modalData.reason = jqxhr.statusText; - showModalProducts(modalData); + showModalProducts({ + icon: "times-circle", + contents: "Failed to load the products manifest!", + code: jqxhr.status, + reason: jqxhr.statusText + }); }); }; @@ -158,21 +157,25 @@ var loadServerManifest = function (url, manifestfile) { var saveServerManifest = function (url, clobber) { clobber = typeof clobber !== "undefined" ? clobber : false; var outfile = $("input#products-manifest").val(); - var data = {action: "save", outfile: outfile, clobber: clobber}; + var data = { + action: "save", + outfile: outfile, + clobber: clobber + }; return $.postJSON(url, data) .done(function () { - var modalData = {}; - modalData.icon = "check-circle"; - modalData.contents = "Current products manifest saved."; - showModalProducts(modalData); + showModalProducts({ + icon: "check-circle", + contents: "Current products manifest saved." + }); }) .fail(function (jqxhr) { - var modalData = {}; - modalData.icon = "times-circle"; - modalData.contents = "Failed to save current products manifest!"; - modalData.code = jqxhr.status; - modalData.reason = jqxhr.statusText; - showModalProducts(modalData); + showModalProducts({ + icon: "times-circle", + contents: "Failed to save current products manifest!", + code: jqxhr.status, + reason: jqxhr.statusText + }); }); }; @@ -183,12 +186,12 @@ var saveServerManifest = function (url, clobber) { var getServerManifest = function (url) { return $.getJSONUncached(url) .fail(function (jqxhr) { - var modalData = {}; - modalData.icon = "times-circle"; - modalData.contents = "Failed to load the products manifest!"; - modalData.code = jqxhr.status; - modalData.reason = jqxhr.statusText; - showModalProducts(modalData); + showModalProducts({ + icon: "times-circle", + contents: "Failed to load the products manifest!", + code: jqxhr.status, + reason: jqxhr.statusText + }); }); }; @@ -211,19 +214,18 @@ var resetManifest = function (url) { return $.postJSON(url, {action: "reset"}) .done(function () { resetManifestTable(); - // Popup a modal notification - var modalData = {}; - modalData.icon = "check-circle"; - modalData.contents = "Reset the products manifest."; - showModalProducts(modalData); + showModalProducts({ + icon: "check-circle", + contents: "Reset the products manifest." + }); }) .fail(function (jqxhr) { - var modalData = {}; - modalData.icon = "times-circle"; - modalData.contents = "Failed to reset the products manifest on server!"; - modalData.code = jqxhr.status; - modalData.reason = jqxhr.statusText; - showModalProducts(modalData); + showModalProducts({ + icon: "times-circle", + contents: "Failed to reset the products manifest on server!", + code: jqxhr.status, + reason: jqxhr.statusText + }); }); }; @@ -237,12 +239,12 @@ var resetManifest = function (url) { var convertProductHPX = function (url, compID, freqID) { return $.postJSON(url, {action: "convert", compID: compID, freqID: freqID}) .fail(function (jqxhr) { - var modalData = {}; - modalData.icon = "times-circle"; - modalData.contents = "Failed to convert the HEALPix map to HPX image!"; - modalData.code = jqxhr.status; - modalData.reason = jqxhr.statusText; - showModalProducts(modalData); + showModalProducts({ + icon: "times-circle", + contents: "Failed to convert the HEALPix map to HPX image!", + code: jqxhr.status, + reason: jqxhr.statusText + }); }); }; @@ -281,7 +283,8 @@ $(document).ready(function () { // Update the products manifest file path $("#conf-form input[name='workdir'], " + - "#conf-form input[name='common/manifest']").on("change", function (e) { + "#conf-form input[name='common/manifest']") + .on("change", function (e) { var workdir = $("#conf-form input[name='workdir']").val(); var manifest = $("#conf-form input[name='output/manifest']").val(); $("input#products-manifest").val(joinPath(workdir, manifest)); @@ -305,21 +308,20 @@ $(document).ready(function () { // Get and load products manifest into table $("#load-products").on("click", function () { loadServerManifest(ajax_url) - .then(function () { - return getServerManifest(ajax_url); - }) + .then(function () { return getServerManifest(ajax_url); }) .done(function (response) { console.log("GET products response:", response); - var modalData = {}; if ($.isEmptyObject(response.manifest)) { - modalData.icon = "warning"; - modalData.contents = "Products manifest not loaded on the server."; - showModalProducts(modalData); + showModalProducts({ + icon: "warning", + contents: "Products manifest not loaded on the server." + }); } else { loadManifestToTable(response.manifest, response.localhost); - modalData.icon = "check-circle"; - modalData.contents = "Loaded products manifest to table."; - showModalProducts(modalData); + showModalProducts({ + icon: "check-circle", + contents: "Loaded products manifest to table." + }); } }); }); @@ -376,12 +378,13 @@ $(document).ready(function () { // Open the HPX FITS image // NOTE: Only allowed when accessing the Web UI from localhost $(document).on("click", "td.product > .hpx.hpx-open", function () { + var cell = $(this).closest("td"); + var compID = cell.data("compID"); + var freqID = cell.data("freqID"); var input_viewer = $("input#products-fitsviewer"); + var viewer; if (input_viewer.data("validity")) { - var cell = $(this).closest("td"); - var compID = cell.data("compID"); - var freqID = cell.data("freqID"); - var viewer = input_viewer.val(); + viewer = input_viewer.val(); openProductHPX(ajax_url, compID, freqID, viewer) .done(function (response) { showModalProducts({ diff --git a/fg21sim/webui/static/js/websocket.js b/fg21sim/webui/static/js/websocket.js index 4cd8b8d..8060874 100644 --- a/fg21sim/webui/static/js/websocket.js +++ b/fg21sim/webui/static/js/websocket.js @@ -28,6 +28,24 @@ var getWebSocketURL = function (uri) { }; +/** + * Toggle the visibility of element "#ws-status". + */ +var toggleWSReconnect = function (action) { + action = typeof action !== "undefined" ? action : "toggle"; + var target = $("#ws-reconnect"); + if (action === "toggle") { + target.toggle(); + } else if (action === "show") { + target.show(); + } else if (action === "hide") { + target.hide(); + } else { + console.error("toggleWSReconnect: Unknown action:", action); + } +}; + + /** * Update the contents of element "#ws-status" according to the current * WebSocket status. @@ -66,6 +84,7 @@ var updateWSStatus = function (action) { $("#ws-status .icon").removeClass("fa-question-circle") .addClass("fa-times-circle"); $("#ws-status .text").text("Unsupported!!"); + toggleWSReconnect("hide"); } else { console.error("updateWSStatus: Unknown action:", action); @@ -73,28 +92,6 @@ var updateWSStatus = function (action) { }; -/** - * Toggle the visibility of element "#ws-status". - */ -var toggleWSReconnect = function (action) { - /** - * Function default parameters: https://stackoverflow.com/a/894877/4856091 - */ - action = typeof action !== "undefined" ? action : "toggle"; - - var target = $("#ws-reconnect"); - if (action === "toggle") { - target.toggle(); - } else if (action === "show") { - target.show(); - } else if (action === "hide") { - target.hide(); - } else { - console.error("toggleWSReconnect: Unknown action:", action); - } -}; - - /** * Connect to WebSocket and bind functions to events */ @@ -145,7 +142,7 @@ var connectWebSocket = function (url) { $(document).ready(function () { /** - * Check `WebSocket` support + * Check "WebSocket" support */ if (window.WebSocket) { // WebSocket supported @@ -161,10 +158,19 @@ $(document).ready(function () { console.log("Manually reconnect the WebSocket:", ws_url); connectWebSocket(ws_url); }); - } else { // WebSocket NOT supported - console.error("Oops, WebSocket is NOT supported!"); + console.warn("Oops, WebSocket is NOT supported!"); updateWSStatus("unsupported"); + // Create a modal box and show a warning + var modalBox = $("

").addClass("modal").attr("id", "modal-websocket"); + $("body").append(modalBox); + showModal(modalBox, { + icon: "warning", + title: "WebSocket is NOT supported by the browser!", + contents: ("The necessary functionalities do NOT " + + "depend on WebSocket. However, the user experience may be " + + "affected due to the missing WebSocket functionalities.") + }); } }); -- cgit v1.2.2