/**
* @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 = {};
/**
* Sends Form data to the ArduBlocklyServer using Ajax.
* @param {!string} url Requestor URL.
* @param {!string} params Form parameters in the 'var=x&var2=y' format.
* @param {!function} callback Request callback function.
*/
ArdublocklyServer.ajaxPostForm = function(url, params, callback) {
var request = ArdublocklyServer.createAjaxRequest();
try {
request.open('POST', url, true);
request.setRequestHeader(
'Content-type', 'application/x-www-form-urlencoded');
} catch (e) {
// The request will fail if opening the html directly on a browser, so
// let's just send the callback nullified and the front end will deal.
callback(null);
}
// The data received is JSON, so it needs to be converted into the right
// format to be displayed in the page.
request.onreadystatechange = function() {
if (request.readyState == 4) {
if (request.status == 200) {
callback(request.responseText);
} else if (request.status == 405) {
// return a null element which will be dealt with in the front end
callback(null);
}
}
};
// Send the data
try {
request.send(params);
} catch (e) {
// Nullify callback to indicate error
callback(null);
}
};
/**
* Sends plain data to the ArduBlocklyServer using Ajax.
* @param {!string} url Requester URL.
* @param {!string} data Plain text currently used to send Arduino code only.
* @param {!function} callback Request callback function.
*/
ArdublocklyServer.ajaxPostPlain = function(url, data, callback) {
var request = ArdublocklyServer.createAjaxRequest();
request.open('POST', url, true);
request.setRequestHeader('Content-type', 'text/plain');
// The data received is JSON, so it needs to be converted into the right
// format to be displayed in the page.
request.onreadystatechange = function() {
if (request.readyState == 4) {
if (request.status == 200) {
callback(request.responseText);
} else if (request.status == 405) {
// return a null element which will be dealt with in the front end
callback(null);
}
}
};
// Send the data
try {
request.send(data);
} catch (e) {
// The request will fail if opening the html directly on a browser, so
// let's just send the callback nullified and the front end will deal.
callback(null);
}
};
/**
* Reads JSON data from the server and forwards formatted JavaScript object.
* @param {!string} fileLocation Location for the JSON data.
* @param {!function} jsonDataCb Callback with JSON object or null for error.
*/
Ardublockly.getJsonData = function(fileLocation, jsonDataCb) {
var request = ArdublocklyServer.createAjaxRequest();
request.overrideMimeType("application/json");
var requestCb = function() {
if (request.readyState == 4) {
if (request.status == 200) {
var jsonObj = null;
try {
jsonObj = JSON.parse(request.responseText);
} catch(e) {
console.error('Incorrectly formatted JSON data from ' + fileLocation);
throw e;
}
jsonDataCb(jsonObj);
} else {
jsonDataCb(null);
}
}
};
try {
request.open('GET', fileLocation, true);
request.onreadystatechange = requestCb;
request.send(null);
} catch (e) {
jsonDataCb(null);
}
};
/** @return {XMLHttpRequest} An XML HTTP Request multi-browser compatible. */
ArdublocklyServer.createAjaxRequest = function() {
var request = false;
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.createElementFromJson = function(json_data) {
var parsed_json = JSON.parse(json_data);
var element = null;
if (parsed_json.element == 'text_input') {
// Simple text input
element = document.createElement('input');
element.setAttribute('type', 'text');
element.setAttribute('value', parsed_json.display_text);
} else if (parsed_json.element == 'dropdown') {
// Drop down list of unknown length with a selected item
element = document.createElement('select');
element.name = parsed_json.response_type;
for (var i = 0; i < parsed_json.options.length; i++) {
var option = document.createElement('option');
option.value = parsed_json.options[i].value;
option.text = parsed_json.options[i].display_text;
// Check selected option and mark it
if (parsed_json.options[i].value == parsed_json.selected) {
option.selected = true;
}
element.appendChild(option);
}
} else if (parsed_json.element == 'div_ide_output') {
// Formatted text for the Arduino IDE CLI output
var el_title = document.createElement('h4');
el_title.innerHTML = Ardublockly.getLocalStr(parsed_json.conclusion);
if (parsed_json.success == true) {
el_title.className = 'arduino_dialog_success';
} else {
el_title.className = 'arduino_dialog_failure';
}
var el_out = document.createElement('span');
el_out.className = 'arduino_dialog_out';
// If larger than 50 characters then don't bother looking for language key
if (parsed_json.output.length < 50) {
el_out.innerHTML = Ardublockly.getLocalStr(parsed_json.output) ||
parsed_json.output.split('\n').join('
');
} else {
el_out.innerHTML = parsed_json.output.split('\n').join('
');
}
element = document.createElement('div');
element.appendChild(el_title);
element.appendChild(el_out);
// Only ouput error message if it was not successful
if (parsed_json.success == false) {
var el_err = document.createElement('span');
el_err.className = 'arduino_dialog_out_error';
// If larger than 50 characters then don't bother looking for language key
if (parsed_json.output.length < 50) {
el_err.innerHTML = Ardublockly.getLocalStr(parsed_json.error_output) ||
parsed_json.error_output.split('\n').join('
');
} else {
el_err.innerHTML = parsed_json.error_output.split('\n').join('
');
}
element.appendChild(el_err);
}
} else {
//TODO: Not recognised, alert the user/developer somehow
}
return element;
};