@@ -1008,17 +1008,212 @@ AudioTour.prototype.setBackgroundForLines = function (divid, lnum, color) {
10081008 }
10091009} ;
10101010
1011+ //
1012+ //
10111013
1014+ LiveCode . prototype = new ActiveCode ( ) ;
1015+
1016+ function LiveCode ( opts ) {
1017+ if ( opts ) {
1018+ this . init ( opts )
1019+ }
1020+ }
1021+
1022+ LiveCode . prototype . init = function ( opts ) {
1023+ ActiveCode . prototype . init . apply ( this , arguments )
1024+
1025+ var orig = opts . orig ;
1026+ this . stdin = $ ( orig ) . data ( 'stdin' ) ;
1027+ this . datafile = $ ( orig ) . data ( 'datafile' ) ;
1028+ this . sourcefile = $ ( orig ) . data ( 'sourcefile' ) ;
1029+
1030+ this . API_KEY = "67033pV7eUUvqo07OJDIV8UZ049aLEK1"
1031+ this . USE_API_KEY = true ;
1032+ this . JOBE_SERVER = 'http://jobe2.cosc.canterbury.ac.nz' ;
1033+ this . resource = '/jobe/index.php/restapi/runs/' ;
1034+ this . div2id = { }
1035+ if ( this . stdin ) {
1036+ this . createInputElement ( ) ;
1037+ }
1038+ this . createErrorOutput ( ) ;
1039+ } ;
1040+
1041+ LiveCode . prototype . outputfun = function ( a ) { } ;
1042+
1043+ LiveCode . prototype . createInputElement = function ( ) {
1044+
1045+ var label = document . createElement ( 'label' ) ;
1046+ label . for = this . divid + "_stdin" ;
1047+ $ ( label ) . text ( "Input for Program" )
1048+ var input = document . createElement ( 'input' )
1049+ input . id = this . divid + "_stdin" ;
1050+ input . type = "text" ;
1051+ input . size = "35" ;
1052+ input . value = this . stdin ;
1053+ this . outerDiv . appendChild ( label ) ;
1054+ this . outerDiv . appendChild ( input ) ;
1055+ this . stdin_el = input ;
1056+ } ;
1057+
1058+ LiveCode . prototype . createErrorOutput = function ( ) {
1059+
1060+ }
1061+
1062+ LiveCode . prototype . runProg = function ( ) {
1063+ var xhr , stdin ;
1064+ var runspec = { } ;
1065+ var data , host , source , editor ;
1066+ var sfilemap = { java : '' , cpp : 'test.cpp' , c : 'test.c' , python3 : 'test.py' , python2 : 'test.py' }
1067+
1068+ xhr = new XMLHttpRequest ( ) ;
1069+ source = this . editor . getValue ( ) ;
1070+
1071+ if ( this . stdin ) {
1072+ stdin = $ ( this . stdin_el ) . val ( ) ;
1073+ }
1074+
1075+ if ( ! this . sourcefile ) {
1076+ this . sourcefile = sfilemap [ this . language ] ;
1077+ }
1078+
1079+ runspec = {
1080+ language_id : this . language ,
1081+ sourcecode : source ,
1082+ sourcefilename : this . sourcefile
1083+ } ;
1084+
1085+
1086+ if ( stdin ) {
1087+ runspec . input = stdin
1088+ }
1089+
1090+ if ( this . datafile ) {
1091+ runspec [ 'file_list' ] = [ [ this . div2id [ datafile ] , datafile ] ] ;
1092+ }
1093+ data = JSON . stringify ( { 'run_spec' : runspec } ) ;
1094+ host = this . JOBE_SERVER + this . resource
1095+
1096+ var odiv = this . output ;
1097+ $ ( this . runButton ) . attr ( 'disabled' , 'disabled' ) ;
1098+ $ ( this . codeDiv ) . switchClass ( "col-md-12" , "col-md-6" , { duration :500 , queue :false } ) ;
1099+ $ ( this . outDiv ) . show ( { duration :700 , queue :false } ) ;
1100+ $ ( this . errDiv ) . remove ( ) ;
1101+
1102+ xhr . open ( "POST" , host , true ) ;
1103+ xhr . setRequestHeader ( 'Content-type' , 'application/json; charset=utf-8' ) ;
1104+ xhr . setRequestHeader ( 'Accept' , 'application/json' ) ;
1105+ xhr . setRequestHeader ( 'X-API-KEY' , this . API_KEY ) ;
1106+
1107+ xhr . onload = ( function ( ) {
1108+ var logresult ;
1109+ $ ( this . runButton ) . removeAttr ( 'disabled' ) ;
1110+ try {
1111+ var result = JSON . parse ( xhr . responseText ) ;
1112+ } catch ( e ) {
1113+ result = { } ;
1114+ result . outcome = - 1 ;
1115+ }
1116+
1117+ if ( result . outcome === 15 ) {
1118+ logresult = 'success' ;
1119+ } else {
1120+ logresult = result . outcome ;
1121+ }
1122+ logRunEvent ( { 'div_id' : this . divid , 'code' : source , 'errinfo' : logresult , 'event' :'livecode' } ) ;
1123+ switch ( result . outcome ) {
1124+ case 15 :
1125+ $ ( odiv ) . html ( result . stdout . replace ( / \n / g, "<br>" ) ) ;
1126+ break ;
1127+ case 11 : // compiler error
1128+ $ ( odiv ) . html ( "There were errors compiling your code. See below." ) ;
1129+ this . addJobeErrorMessage ( result . cmpinfo ) ;
1130+ break ;
1131+ case 12 : // run time error
1132+ $ ( odiv ) . html ( result . stdout . replace ( / \n / g, "<br>" ) ) ;
1133+ if ( result . stderr ) {
1134+ this . addJobeErrorMessage ( result . stderr ) ;
1135+ }
1136+ break ;
1137+ case 13 : // time limit
1138+ $ ( odiv ) . html ( result . stdout . replace ( / \n / g, "<br>" ) ) ;
1139+ this . addJobeErrorMessage ( "Time Limit Exceeded on your program" ) ;
1140+ break ;
1141+ default :
1142+ if ( result . stderr ) {
1143+ $ ( odiv ) . html ( result . stderr . replace ( / \n / g, "<br>" ) ) ;
1144+ } else {
1145+ this . addJobeErrorMessage ( "A server error occurred: " + xhr . status + " " + xhr . statusText ) ;
1146+ }
1147+ }
1148+
1149+ // todo: handle server busy and timeout errors too
1150+ } ) . bind ( this ) ;
1151+
1152+ ///$("#" + divid + "_errinfo").remove();
1153+ $ ( this . output ) . html ( "Compiling and Running your Code Now..." )
1154+
1155+ xhr . onerror = function ( ) {
1156+ this . addJobeErrorMessage ( "Error communicating with the server." ) ;
1157+ $ ( this . runButton ) . removeAttr ( 'disabled' ) ;
1158+ } ;
1159+
1160+ xhr . send ( data ) ;
1161+ } ;
1162+ LiveCode . prototype . addJobeErrorMessage = function ( err ) {
1163+ var errHead = $ ( '<h3>' ) . html ( 'Error' ) ;
1164+ var eContainer = this . outerDiv . appendChild ( document . createElement ( 'div' ) ) ;
1165+ this . errDiv = eContainer ;
1166+ eContainer . className = 'error alert alert-danger' ;
1167+ eContainer . id = this . divid + '_errinfo' ;
1168+ eContainer . appendChild ( errHead [ 0 ] ) ;
1169+ var errText = eContainer . appendChild ( document . createElement ( 'pre' ) )
1170+ errText . innerHTML = err ;
1171+ } ;
1172+
1173+
1174+ LiveCode . prototype . pushDataFile = function ( datadiv ) {
1175+
1176+ var file_id = 'runestone' + Math . floor ( Math . random ( ) * 100000 ) ;
1177+ var contents = $ ( document . getElementById ( datadiv ) ) . text ( ) ;
1178+ var contentsb64 = btoa ( contents ) ;
1179+ var data = JSON . stringify ( { 'file_contents' : contentsb64 } ) ;
1180+ var resource = '/jobe/index.php/restapi/files/' + file_id
1181+ var host = JOBE_SERVER + resource
1182+ var xhr = new XMLHttpRequest ( ) ;
1183+
1184+ if ( this . div2id [ datadiv ] === undefined ) {
1185+ this . div2id [ datadiv ] = file_id ;
1186+
1187+ xhr . open ( "PUT" , host , true ) ;
1188+ xhr . setRequestHeader ( 'Content-type' , 'application/json' ) ;
1189+ xhr . setRequestHeader ( 'Accept' , 'text/plain' ) ;
1190+ xhr . setRequestHeader ( 'X-API-KEY' , API_KEY ) ;
1191+
1192+ xhr . onload = function ( ) {
1193+ console . log ( "successfully sent file " + xhr . responseText ) ;
1194+ }
1195+
1196+ xhr . onerror = function ( ) {
1197+ console . log ( "error sending file" + xhr . responseText ) ;
1198+ }
1199+
1200+ xhr . send ( data )
1201+ }
1202+ } ;
1203+
1204+ //
10121205
10131206$ ( document ) . ready ( function ( ) {
10141207 $ ( '[data-component=activecode]' ) . each ( function ( index ) {
10151208 if ( $ ( this ) . data ( 'lang' ) === "javascript" ) {
10161209 edList [ this . id ] = new JSActiveCode ( { 'orig' : this } ) ;
10171210 } else if ( $ ( this ) . data ( 'lang' ) === 'htmlmixed' ) {
10181211 edList [ this . id ] = new HTMLActiveCode ( { 'orig' : this } ) ;
1212+ } else if ( [ 'java' , 'cpp' , 'c' , 'python3' , 'python2' ] . includes ( $ ( this ) . data ( 'lang' ) ) ) {
1213+ edList [ this . id ] = new LiveCode ( { 'orig' : this } ) ;
10191214 } else { // default is python
10201215 edList [ this . id ] = new ActiveCode ( { 'orig' : this } ) ;
1021- }
1216+ }
10221217 } ) ;
10231218 } ) ;
10241219
0 commit comments