mirror of
https://github.com/sensebox/blockly-app
synced 2025-02-23 16:23:59 +01:00
342 lines
12 KiB
JavaScript
342 lines
12 KiB
JavaScript
/**
|
|
* @license Licensed under the Apache License, Version 2.0 (the "License"):
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* @fileoverview Ajax calls to the Ardublockly Server python program.
|
|
*/
|
|
'use strict';
|
|
|
|
/** Create a name space for the application. */
|
|
var ArdublocklyServer = {};
|
|
|
|
/**
|
|
* Reads JSON data from the server and forwards formatted JavaScript object.
|
|
* @param {!string} url Location for the JSON data.
|
|
* @param {!function} jsonDataCb Callback with JSON object or null for error.
|
|
*/
|
|
ArdublocklyServer.getJson = function(url, callback) {
|
|
ArdublocklyServer.sendRequest(url, 'GET', 'application/json', null, callback);
|
|
};
|
|
|
|
/**
|
|
* Sends JSON data to the ArduBlocklyServer.
|
|
* @param {!string} url Requestor URL.
|
|
* @param {!string} json JSON string.
|
|
* @param {!function} callback Request callback function.
|
|
*/
|
|
ArdublocklyServer.putJson = function(url, json, callback) {
|
|
ArdublocklyServer.sendRequest(url, 'PUT', 'application/json', json, callback);
|
|
};
|
|
|
|
/**
|
|
* Sends a request to the Ardubloockly Server that returns a JSON response.
|
|
* @param {!string} url Requestor URL.
|
|
* @param {!string} method HTTP method.
|
|
* @param {!string} contentType HTTP content type.
|
|
* @param {string} jsonObjSend JavaScript object to be parsed into JSON to send.
|
|
* @param {!function} cb Request callback function, takes a single input for a
|
|
* parsed JSON object.
|
|
*/
|
|
ArdublocklyServer.sendRequest = function(
|
|
url, method, contentType, jsonObjSend, cb) {
|
|
var request = ArdublocklyServer.createRequest();
|
|
|
|
// The data received is JSON, so it needs to be converted into the right
|
|
// format to be displayed in the page.
|
|
var onReady = function() {
|
|
if (request.readyState == 4) {
|
|
if (request.status == 200) {
|
|
var jsonObjReceived = null;
|
|
try {
|
|
jsonObjReceived = JSON.parse(request.responseText);
|
|
} catch(e) {
|
|
console.error('Incorrectly formatted JSON data from ' + url);
|
|
throw e;
|
|
}
|
|
cb(jsonObjReceived);
|
|
} else {
|
|
// return a null element which will be dealt with in the front end
|
|
cb(null);
|
|
}
|
|
}
|
|
};
|
|
|
|
try {
|
|
request.open(method, url, true);
|
|
request.setRequestHeader('Content-type', contentType);
|
|
request.onreadystatechange = onReady;
|
|
request.send(JSON.stringify(jsonObjSend));
|
|
} catch (e) {
|
|
// Nullify callback to indicate error
|
|
cb(null);
|
|
throw e;
|
|
}
|
|
};
|
|
|
|
/** @return {XMLHttpRequest} An XML HTTP Request multi-browser compatible. */
|
|
ArdublocklyServer.createRequest = function() {
|
|
var request = null;
|
|
try {
|
|
// Firefox, Chrome, IE7+, Opera, Safari
|
|
request = new XMLHttpRequest();
|
|
}
|
|
catch (e) {
|
|
// IE6 and earlier
|
|
try {
|
|
request = new ActiveXObject('Msxml2.XMLHTTP');
|
|
}
|
|
catch (e) {
|
|
try {
|
|
request = new ActiveXObject('Microsoft.XMLHTTP');
|
|
}
|
|
catch (e) {
|
|
throw 'Your browser does not support AJAX. You will not be able to' +
|
|
'use all of Ardublockly features.';
|
|
request = null;
|
|
}
|
|
}
|
|
}
|
|
return request;
|
|
};
|
|
|
|
/**
|
|
* Creates an HTML element based on the JSON data received from the server.
|
|
* @param {!string} json_data A string containing the JSON data to be parsed.
|
|
* @return {!element} An HTML element, which type depends on the JSON 'element'
|
|
* key (currently only text input or drop down).
|
|
*/
|
|
ArdublocklyServer.jsonToIdeModal = function(jsonObj) {
|
|
if (!jsonObj) return null;
|
|
|
|
var elTitle = document.createElement('h4');
|
|
elTitle.className = (jsonObj && jsonObj.success) ? 'arduino_dialog_success' :
|
|
'arduino_dialog_failure';
|
|
var elStdOp = document.createElement('span');
|
|
elStdOp.className = 'arduino_dialog_out';
|
|
var elErrOp = document.createElement('span');
|
|
elErrOp.className = 'arduino_dialog_out_error';
|
|
|
|
// Add the Standard and Error outputs
|
|
var ideData = jsonObj.ide_data;
|
|
if (ideData && (ideData.std_output !== undefined) &&
|
|
(ideData.err_output !== undefined)) {
|
|
elStdOp.innerHTML = ideData.std_output.split('\n').join('<br />');
|
|
elErrOp.innerHTML = ideData.err_output.split('\n').join('<br />');
|
|
} else {
|
|
console.error(jsonObj);
|
|
console.error('The IDE out JSON response does not have valid "ide_data".');
|
|
}
|
|
|
|
if (jsonObj.errors) {
|
|
// Prepare error message
|
|
elTitle.innerHTML = Ardublockly.getLocalStr('arduinoOpErrorTitle');
|
|
var errStr = [];
|
|
for (var i = 0; i < jsonObj.errors.length; i++) {
|
|
var errorContext = 'Unrecognised error.';
|
|
try {
|
|
errorContext = Ardublockly.getLocalStr(
|
|
'arduinoOpErrorIdContext_' + jsonObj.errors[i].id);
|
|
} catch (e) {
|
|
// Swallow the exception, could be expanded to try to figure out issue
|
|
}
|
|
errStr.push('\nError id ' + jsonObj.errors[i].id + ': ' + errorContext);
|
|
}
|
|
elErrOp.innerHTML += '<br />' + errStr.join('<br />');
|
|
} else if (jsonObj.success && jsonObj.ide_mode) {
|
|
// Format a successful response
|
|
if (jsonObj.ide_mode == 'upload') {
|
|
elTitle.innerHTML = Ardublockly.getLocalStr('arduinoOpUploadedTitle');
|
|
} else if (jsonObj.ide_mode == 'verify') {
|
|
elTitle.innerHTML = Ardublockly.getLocalStr('arduinoOpVerifiedTitle');
|
|
} else if (jsonObj.ide_mode == 'open') {
|
|
elTitle.innerHTML = Ardublockly.getLocalStr('arduinoOpOpenedTitle');
|
|
// This is a corner case where we also add to the stand out
|
|
elStdOp.innerHTML += Ardublockly.getLocalStr('arduinoOpOpenedBody');
|
|
} else {
|
|
elTitle.innerHTML = Ardublockly.getLocalStr('arduinoOpErrorTitle');
|
|
}
|
|
} else {
|
|
console.error(jsonObj);
|
|
console.error('Unexpected response format, printed above.');
|
|
}
|
|
|
|
var element = document.createElement('div');
|
|
element.appendChild(elTitle);
|
|
element.appendChild(elStdOp);
|
|
element.appendChild(elErrOp);
|
|
return element;
|
|
};
|
|
|
|
ArdublocklyServer.jsonToHtmlTextInput = function(jsonObj) {
|
|
var element = null;
|
|
if (jsonObj) {
|
|
// Simple text input
|
|
element = document.createElement('input');
|
|
element.setAttribute('type', 'text');
|
|
element.style.cssText = '';
|
|
if (jsonObj.errors) {
|
|
element.setAttribute('value', '');
|
|
element.style.cssText = 'border-bottom: 1px solid #f75c51;' +
|
|
'box-shadow: 0 1px 0 0 #d73c30;';
|
|
} else {
|
|
element.setAttribute('value', jsonObj.selected || '');
|
|
}
|
|
}
|
|
return element;
|
|
};
|
|
|
|
ArdublocklyServer.jsonToHtmlDropdown = function(jsonObj) {
|
|
var element = null;
|
|
if (!jsonObj) {
|
|
console.error('Invalid JSON received from server.');
|
|
} else if(jsonObj.errors) {
|
|
console.error('There are errors in the JSON response from server.');
|
|
console.error(jsonObj);
|
|
} else {
|
|
// Drop down list of unknown length with a selected item
|
|
element = document.createElement('select');
|
|
element.name = jsonObj.settings_type;
|
|
for (var i = 0; i < jsonObj.options.length; i++) {
|
|
if (jsonObj.options[i].value && jsonObj.options[i].display_text) {
|
|
var option = document.createElement('option');
|
|
option.value = jsonObj.options[i].value;
|
|
option.text = jsonObj.options[i].display_text;
|
|
// Check selected option and mark it
|
|
if (jsonObj.selected) {
|
|
option.selected = jsonObj.options[i].value == jsonObj.selected;
|
|
}
|
|
element.appendChild(option);
|
|
} else {
|
|
console.error('Missing required JSON keys for Drop Down conversion.');
|
|
}
|
|
}
|
|
}
|
|
return element;
|
|
};
|
|
|
|
/**
|
|
* Gets the current Compiler location from the ArdublocklyServer settings.
|
|
* @param {!function} callback Callback function for the server request, must
|
|
* have one argument to receive the JSON response.
|
|
*/
|
|
ArdublocklyServer.requestCompilerLocation = function(callback) {
|
|
ArdublocklyServer.getJson('/settings/compiler', callback);
|
|
};
|
|
|
|
/**
|
|
* Sends a string to the Ardublockly Server for a the Arduino IDE executable
|
|
* path.
|
|
* @param {!function} callback Callback function for the server request, must
|
|
* have one argument to receive the JSON response.
|
|
*/
|
|
ArdublocklyServer.setCompilerLocation = function(new_path, callback) {
|
|
ArdublocklyServer.putJson(
|
|
'/settings/compiler', {"new_value": new_path}, callback);
|
|
};
|
|
|
|
/**
|
|
* Gets the current Sketch location from the Ardublockly Server settings.
|
|
* @param {!function} callback Callback function for the server request, must
|
|
* have one argument to receive the JSON response.
|
|
*/
|
|
ArdublocklyServer.requestSketchLocation = function(callback) {
|
|
ArdublocklyServer.getJson('/settings/sketch', callback);
|
|
};
|
|
|
|
/**
|
|
* Sends a string to the Ardublockly Server for a the Arduino sketch folder.
|
|
* @param {!string} new_path New Sketch location path..
|
|
* @param {!function} callback Callback function for the server request, must
|
|
* have one argument to receive the JSON response.
|
|
*/
|
|
ArdublocklyServer.setSketchLocation = function(new_path, callback) {
|
|
ArdublocklyServer.putJson(
|
|
'/settings/sketch', {"new_value": new_path}, callback);
|
|
};
|
|
|
|
/**
|
|
* Request to the Ardublockly Server to return JSON data containing all
|
|
* available target Arduino Boards, and the selected one in the settings.
|
|
* The data is then processed into an HTML element and sent to the callback
|
|
* function as an argument.
|
|
* @param {!function} callback Callback function for the server request, must
|
|
* have one argument to receive the JSON response.
|
|
*/
|
|
ArdublocklyServer.requestArduinoBoards = function(callback) {
|
|
ArdublocklyServer.getJson('/settings/board', callback);
|
|
};
|
|
|
|
/**
|
|
* Sends the inputted Arduino Board type to the Ardublockly Server Settings.
|
|
* The new settings menu for the Board type is then processed into an HTML
|
|
* element and sent to the callback function as an argument.
|
|
* @param {!string} new_board Indicates which board has been selected.
|
|
* @param {!function} callback Callback function for the server request, must
|
|
* have one argument to receive the JSON response.
|
|
*/
|
|
ArdublocklyServer.setArduinoBoard = function(new_board, callback) {
|
|
ArdublocklyServer.putJson(
|
|
'/settings/board', {"new_value": new_board}, callback);
|
|
};
|
|
|
|
/**
|
|
* Request to the Ardublockly Server to return JSON data containing all
|
|
* available serial ports in the computer, and the selected one in the
|
|
* settings. The data is then processed into an HTML element and sent to the
|
|
* callback function as an argument.
|
|
* @param {!function} callback Callback function for the server request, must
|
|
* have one argument to receive the JSON response.
|
|
*/
|
|
ArdublocklyServer.requestSerialPorts = function(callback) {
|
|
ArdublocklyServer.getJson('/settings/serial', callback);
|
|
};
|
|
|
|
/**
|
|
* Sends the inputted Serial Port to the Ardublockly Server Settings. The new
|
|
* settings menu for the Serial Port is then processed into an HTML element
|
|
* and sent to the callback function as an argument.
|
|
* @param {!string} new_port Indicates which port has been selected.
|
|
* @param {!function} callback Callback function for the server request, must
|
|
* have one argument to receive the JSON response.
|
|
*/
|
|
ArdublocklyServer.setSerialPort = function(new_port, callback) {
|
|
ArdublocklyServer.putJson(
|
|
'/settings/serial', {"new_value": new_port}, callback);
|
|
};
|
|
|
|
/**
|
|
* Gets the current IDE setting from the Ardublockly Server settings. The new
|
|
* settings menu for the IDE options is then processed into an HTML element
|
|
* and sent to the callback function as an argument.
|
|
* @param {!function} callback Callback function for the server request, must
|
|
* have one argument to receive the JSON response.
|
|
*/
|
|
ArdublocklyServer.requestIdeOptions = function(callback) {
|
|
ArdublocklyServer.getJson('/settings/ide', callback);
|
|
};
|
|
|
|
/**
|
|
* Sends the inputted IDE option to the Ardublockly Server Settings. The new
|
|
* settings menu for the IDE options is then processed into an HTML element
|
|
* and sent to the callback function as an argument.
|
|
* @param {!string} ide_option Indicates which option has been selected.
|
|
* @param {!function} callback Callback function for the server request, must
|
|
* have one argument to receive the JSON response.
|
|
*/
|
|
ArdublocklyServer.setIdeOptions = function(ide_option, callback) {
|
|
ArdublocklyServer.putJson(
|
|
'/settings/ide', {"new_value": ide_option}, callback);
|
|
};
|
|
|
|
|
|
/**
|
|
* Sends the Arduino code to the ArdublocklyServer to be processed as defined
|
|
* by the settings.
|
|
* @param {!string} code Arduino code in a single string format.
|
|
* @param {!function} callback Callback function for the server request, must
|
|
* have one argument to receive the JSON response.
|
|
*/
|
|
ArdublocklyServer.sendSketchToServer = function(code, callback) {
|
|
ArdublocklyServer.sendRequest(
|
|
'/code', 'POST', 'application/json', {"sketch_code": code}, callback);
|
|
};
|