// Get access to the background window object // This object is used to pass current connectionId to the backround page // so the onClosed event can close the port for us if it was left opened, without this // users can experience weird behavior if they would like to access the serial bus afterwards. chrome.runtime.getBackgroundPage(function(result) { backgroundPage = result; backgroundPage.app_window = window; }); // Google Analytics BEGIN var ga_config; // google analytics config reference var ga_tracking; // global result of isTrackingPermitted var service = analytics.getService('ice_cream_app'); service.getConfig().addCallback(function(config) { ga_config = config; ga_tracking = config.isTrackingPermitted(); }); var ga_tracker = service.getTracker('UA-32728876-6'); ga_tracker.sendAppView('Application Started'); // Google Analytics END $(document).ready(function() { // translate to user-selected language localize(); // alternative - window.navigator.appVersion.match(/Chrome\/([0-9.]*)/)[1]; GUI.log('Running - OS: ' + GUI.operating_system + ', ' + 'Chrome: ' + window.navigator.appVersion.replace(/.*Chrome\/([0-9.]*).*/,"$1") + ', ' + 'Configurator: ' + chrome.runtime.getManifest().version + ''); // notification messages for various operating systems switch (GUI.operating_system) { case 'Windows': break; case 'MacOS': // var main_chromium_version = window.navigator.appVersion.replace(/.*Chrome\/([0-9.]*).*/,"$1").split('.')[0]; break; case 'ChromeOS': break; case 'Linux': break; case 'UNIX': break; } GUI.log('Are you using ESCs with SimonK firmware? Try RapidFlash, our new utility for configuring / flashing / updating firmware.'); // Tabs var tabs = $('#tabs > ul'); $('a', tabs).click(function() { if ($(this).parent().hasClass('active') == false) { // only initialize when the tab isn't already active var self = this; var index = $(self).parent().index(); // if there is no active connection, return if (configuration_received == false) { GUI.log('You need to connect before you can view any of the tabs', 'red'); return; } GUI.tab_switch_cleanup(function() { // disable previously active tab highlight $('li', tabs).removeClass('active'); // get tab class name (there should be only one class listed) var tab = $(self).parent().prop('class'); // Highlight selected tab $(self).parent().addClass('active'); // detach listeners and remove element data $('#content').empty(); switch (tab) { case 'tab_initial_setup': tab_initialize_initial_setup(); break; case 'tab_pid_tuning': tab_initialize_pid_tuning(); break; case 'tab_receiver': tab_initialize_receiver(); break; case 'tab_auxiliary_configuration': tab_initialize_auxiliary_configuration(); break; case 'tab_servos': tab_initialize_servos(); break; case 'tab_gps': tab_initialize_gps(); break; case 'tab_motor_outputs': tab_initialize_motor_outputs(); break; case 'tab_sensors': tab_initialize_sensors(); break; case 'tab_cli': tab_initialize_cli(); break; case 'tab_logging': tab_initialize_logging(); break; } }); } }); tab_initialize_default(); // options $('a#options').click(function() { var el = $(this); if (!el.hasClass('active')) { el.addClass('active'); el.after('
'); $('div#options-window').load('./tabs/options.html', function() { ga_tracker.sendAppView('Options'); // translate to user-selected language localize(); // if notifications are enabled, or wasn't set, check the notifications checkbox chrome.storage.local.get('update_notify', function(result) { if (typeof result.update_notify === 'undefined' || result.update_notify) { $('div.notifications input').prop('checked', true); } }); $('div.notifications input').change(function() { var check = $(this).is(':checked'); chrome.storage.local.set({'update_notify': check}); }); // if tracking is enabled, check the statistics checkbox if (ga_tracking == true) { $('div.statistics input').prop('checked', true); } $('div.statistics input').change(function() { var check = $(this).is(':checked'); ga_tracking = check; ga_config.setTrackingPermitted(check); }); $(this).slideDown(); }); } else { $('div#options-window').slideUp(function() { el.removeClass('active'); $(this).empty().remove(); }); } }); // listen to all input change events and adjust the value within limits if necessary $("#content").on('focus', 'input[type="number"]', function() { var element = $(this); var val = element.val(); if (!isNaN(val)) { element.data('previousValue', parseFloat(val)); } }); $("#content").on('keydown', 'input[type="number"]', function(e) { // whitelist all that we need for numeric control if ((e.keyCode >= 96 && e.keyCode <= 105) || (e.keyCode >= 48 && e.keyCode <= 57)) { // allow numpad and standard number keypad } else if (e.keyCode == 109 || e.keyCode == 189) { // minus on numpad and in standard keyboard } else if (e.keyCode == 8 || e.keyCode == 46) { // backspace and delete } else if (e.keyCode == 190 || e.keyCode == 110) { // allow and decimal point } else if ((e.keyCode >= 37 && e.keyCode <= 40) || e.keyCode == 13) { // allow arrows, enter } else { // block everything else e.preventDefault(); } }); $("#content").on('change', 'input[type="number"]', function() { var element = $(this); var min = parseFloat(element.prop('min')); var max = parseFloat(element.prop('max')); var step = parseFloat(element.prop('step')); var val = parseFloat(element.val()); // only adjust minimal end if bound is set if (element.prop('min')) { if (val < min) element.val(min); } // only adjust maximal end if bound is set if (element.prop('max')) { if (val > max) element.val(max); } // if entered value is illegal use previous value instead if (isNaN(val)) { element.val(element.data('previousValue')); } // if step is not set or step is int and value is float use previous value instead if (isNaN(step) || step % 1 === 0) { if (val % 1 !== 0) { element.val(element.data('previousValue')); } } // if step is set and is float and value is int, convert to float, keep decimal places in float according to step *experimental* if (!isNaN(step) && step % 1 !== 0) { var decimal_places = String(step).split('.')[1].length; if (val % 1 === 0) { element.val(val.toFixed(decimal_places)); } else if (String(val).split('.')[1].length != decimal_places) { element.val(val.toFixed(decimal_places)); } } }); }); function microtime() { var now = new Date().getTime() / 1000; return now; } function millitime() { var now = new Date().getTime(); return now; } /* function add_custom_spinners() { var spinner_element = '