/* * Common JavaScript functionality for BootStrap-based servlets. */ var minFontSize = parseInt(10); var maxFontSize = parseInt(48); var nbJmri = null; var log = new Logger(); /* * Populate the panels menu with a list of open panels */ function getPanels() { $.ajax({ url: "/panel?format=json", data: {}, success: function (data) { if (!Array.isArray(data)) { data = [data]; } $(".navbar-panel-item").remove(); if (data.length !== 0) { $("#empty-panel-list").addClass("hidden").removeClass("show"); $.each(data, function (index, value) { $("#navbar-panels").append("
  • " + value.data.userName + "
  • "); }); } else { $("#empty-panel-list").addClass("show").removeClass("hidden"); } } }); } function getRosterGroups() { $.ajax({ url: "/json/rosterGroups", data: {}, success: function (data) { if (!Array.isArray(data)) { data = [data]; } $(".navbar-roster-group-item").remove(); if (data.length !== 0) { $.each(data, function (index, value) { $("#navbar-roster-groups").append("
  • " + value.data.length + "" + value.data.name + "
  • "); }); } } }); } /* * Get list of in-use network services and hide or show elements as appropriate */ function getNetworkServices() { $.ajax({ url: "/json/networkServices", data: {}, success: function (data) { if (!Array.isArray(data)) { data = [data]; } // show all hidden when service is available elements $(".hidden-jmri_jmri-json").addClass("show").removeClass("hidden"); $(".hidden-jmri_jmri-locormi").addClass("show").removeClass("hidden"); $(".hidden-jmri_jmri-simple").addClass("show").removeClass("hidden"); $(".hidden-jmri_srcp").addClass("show").removeClass("hidden"); $(".hidden-jmri_withrottle").addClass("show").removeClass("hidden"); // hide all visible when service is available elements $(".visible-jmri_jmri-json").addClass("hidden").removeClass("show"); $(".visible-jmri_jmri-locormi").addClass("hidden").removeClass("show"); $(".visible-jmri_jmri-simple").addClass("hidden").removeClass("show"); $(".visible-jmri_srcp").addClass("hidden").removeClass("show"); $(".visible-jmri_withrottle").addClass("hidden").removeClass("show"); if (data.length !== 0) { $.each(data, function (index, value) { var service = value.data.type.split(".")[0]; $(".visible-jmri" + service).addClass("show").removeClass("hidden"); $(".hidden-jmri" + service).addClass("hidden").removeClass("show"); }); } } }); } /* * Find a parameter in the URL by name */ function getParameterByName(name) { var match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search); return match && match[1]; } /* * Set the title to the parameter + railroad name * This also returns the new title should it be needed elsewhere */ function setTitle(value) { var title = $("html").data("railroad"); if (value) { title = value + " | " + title; } $(document).attr("title", title); return title; } /* * Set every element matching the selector to the height of the tallest element */ function equalHeight(selector) { tallest = 0; selector.each(function () { thisHeight = $(this).height(); if (thisHeight > tallest) { tallest = thisHeight; } }); selector.each(function () { $(this).height(tallest); }); } /* * Increment/Decrement the text size */ function setFontSize(change) { change = parseInt(change); size = parseInt($("body").css("fontSize").replace("px", "").trim()); if (change === 0) { if (window.localStorage.getItem("jmri.css.font-size.body")) { size = parseInt(window.localStorage.getItem("jmri.css.font-size.body")); } $("#font-size-smaller").click(function () { setFontSize(-1); return false; }); $("#font-size-larger").click(function () { setFontSize(1); return false; }); } else if (change === 1 && size < maxFontSize) { size++; $("#font-size-smaller").parent().removeClass("disabled"); } else if (change === -1 && size > minFontSize) { size--; $("#font-size-larger").parent().removeClass("disabled"); } else if (change === 14) { size = 14; $("#font-size-smaller").parent().removeClass("disabled"); $("#font-size-larger").parent().removeClass("disabled"); } $("body").css("fontSize", size + "px"); window.localStorage.setItem("jmri.css.font-size.body", size); $("#font-size-value").text(size + "px"); if (size >= maxFontSize) { $("#font-size-larger").parent().addClass("disabled"); } if (size <= minFontSize) { $("#font-size-smaller").parent().addClass("disabled"); } console.log("Body font size is " + $("body").css("fontSize")); } /* * Allow users to fix the navbar to the browser window. First use after page * loads should pass a null value as its parameter to read either localStorage * or page parameters. * * The parameter jmri.css.navbar.fixed=0 can be appended to the URL to set the * default value to false if it has not already been set in localStorage. * * @param {type} fixed true if navbar should be fixed * @returns {undefined} */ function setNavbarFixed(fixed) { if (fixed === null) { if (window.localStorage.getItem("jmri.css.navbar.fixed") !== null) { fixed = (parseInt(window.localStorage.getItem("jmri.css.navbar.fixed")) === 1); } $("#navbar-fixed-position").change(function () { setNavbarFixed($(this).prop("checked")); }); } if (fixed === null) { if (getParameterByName("jmri.css.navbar.fixed") !== null) { fixed = (parseInt(getParameterByName("jmri.css.navbar.fixed")) === 1); } else { fixed = true; } } if (fixed === true) { $(".navbar").removeClass("navbar-static-top").addClass("navbar-fixed-top"); $("body").css("padding-top", "50px"); } else { $(".navbar").removeClass("navbar-fixed-top").addClass("navbar-static-top"); $("body").css("padding-top", "0px"); } $("#navbar-fixed-position").prop("checked", (fixed === true) ? "checked" : ""); window.localStorage.setItem("jmri.css.navbar.fixed", ((fixed === true) ? 1 : 0)); console.log("Navbar is " + ((fixed === true) ? "fixed" : "floating")); } /* * Define localStorage for the retention of data if not already defined. * From https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Storage#localStorage */ if (!window.localStorage) { Object.defineProperty(window, "localStorage", new (function () { var aKeys = [], oStorage = {}; Object.defineProperty(oStorage, "getItem", { value: function (sKey) { return sKey ? this[sKey] : null; }, writable: false, configurable: false, enumerable: false }); Object.defineProperty(oStorage, "key", { value: function (nKeyId) { return aKeys[nKeyId]; }, writable: false, configurable: false, enumerable: false }); Object.defineProperty(oStorage, "setItem", { value: function (sKey, sValue) { if (!sKey) { return; } document.cookie = escape(sKey) + "=" + escape(sValue) + "; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/"; }, writable: false, configurable: false, enumerable: false }); Object.defineProperty(oStorage, "length", { get: function () { return aKeys.length; }, configurable: false, enumerable: false }); Object.defineProperty(oStorage, "removeItem", { value: function (sKey) { if (!sKey) { return; } document.cookie = escape(sKey) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/"; }, writable: false, configurable: false, enumerable: false }); this.get = function () { var iThisIndx; for (var sKey in oStorage) { iThisIndx = aKeys.indexOf(sKey); if (iThisIndx === -1) { oStorage.setItem(sKey, oStorage[sKey]); } else { aKeys.splice(iThisIndx, 1); } delete oStorage[sKey]; } for (aKeys; aKeys.length > 0; aKeys.splice(0, 1)) { oStorage.removeItem(aKeys[0]); } for (var aCouple, iKey, nIdx = 0, aCouples = document.cookie.split(/\s*;\s*/); nIdx < aCouples.length; nIdx++) { aCouple = aCouples[nIdx].split(/\s*=\s*/); if (aCouple.length > 1) { oStorage[iKey = unescape(aCouple[0])] = unescape(aCouple[1]); aKeys.push(iKey); } } return oStorage; }; this.configurable = false; this.enumerable = true; })()); } //insert jquery if not available //if (!window.jQuery) { // console.log("inserting jQuery"); // var script = document.createElement('script'); // script.src = '/js/jquery-2.2.4.min.js'; // // document.getElementsByTagName('head')[0].appendChild(script); //} //insert logger.js if not available //if (!window.Logger) { // var script = document.createElement('script'); // script.src = '/js/logger.js'; // // document.getElementsByTagName('head')[0].appendChild(script); // log.log("inserting Logger"); //} //-----------------------------------------javascript processing starts here (main) --------------------------------------------- // perform tasks that all BootStrap-based servlets need $(document).ready(function () { getNetworkServices(); // hide or show and network service specific elements getPanels(); // complete the panels menu getRosterGroups(); // list roster groups in menu setFontSize(0); // get the user's prefered font size setNavbarFixed(null); // make the navbar floating or fixed $("#reset-local-preferences").click(function () { window.localStorage.removeItem("jmri.css.navbar.fixed"); // remove user preference setNavbarFixed(null); // reset to default or passed in parameter setFontSize(14); // reset to default return false; }); // note: the functions and parameter names must match exactly those in jquery.jmri.js nbJmri = $.JMRI({ open: function () { nbJmri.getPower(); }, hello: function(data) { nbJmri.getList("rosterGroups"); // request updates to the rosterGroups via websocket }, rosterGroups: function (name, data) { getRosterGroups(); // refresh the roster groups in menu }, power: function (state) { $('#navbar-power').data('power', state); disabled = ($('#navbar-power button').hasClass('disabled')) ? " - Setting power disabled" : ""; switch (state) { case nbJmri.UNKNOWN: $('#navbar-power button').addClass('btn-warning').removeClass('btn-success').removeClass('btn-danger'); $('#navbar-power button').prop('title', "Layout power unknown" + disabled); $('#navbar-power a').text("Layout Power Unknown"); break; case nbJmri.POWER_ON: $('#navbar-power button').addClass('btn-success').removeClass('btn-danger').removeClass('btn-warning'); $('#navbar-power button').prop('title', "Layout power on" + disabled); $('#navbar-power a').text("Layout Power On"); break; case nbJmri.POWER_OFF: $('#navbar-power button').addClass('btn-danger').removeClass('btn-success').removeClass('btn-warning'); $('#navbar-power button').prop('title', "Layout power off" + disabled); $('#navbar-power a').text("Layout Power Off"); break; } $('#navbar-power-modal-label').text($('#navbar-power a').text()); } }); nbJmri.connect(); if ($('#navbar-power').data('power') === 'readwrite') { $('#navbar-power').removeClass('disabled'); $('#navbar-power button').removeClass('disabled'); $('#navbar-power button').click(function (event) { $('#navbar-power-modal').modal('show'); }); $('#navbar-power-modal-on').click(function (event) { nbJmri.setPower(nbJmri.POWER_ON); $('#navbar-power-modal').modal('hide'); }); $('#navbar-power-modal-off').click(function (event) { nbJmri.setPower(nbJmri.POWER_OFF); $('#navbar-power-modal').modal('hide'); }); $('#navbar-power a').click(function (event) { $('#navbar-power-modal').modal('show'); }); $('#navbar-power-modal').on('show.bs.modal', function () { $('#navbar-power-modal-label').text($('#navbar-power a').text()); $('.navbar-collapse').collapse('hide'); $('#navbar-power-modal').css("z-index", "1500"); }); } });