@@ -28,26 +28,13 @@ declare var initCodeopticon: any; // FIX later when porting Codeopticon
2828
2929*/
3030
31- var qtipShared = {
32- show : {
33- ready : true , // show on document.ready instead of on mouseenter
34- delay : 0 ,
35- event : null ,
36- effect : function ( ) { $ ( this ) . show ( ) ; } , // don't do any fancy fading because it screws up with scrolling
37- } ,
38- hide : {
39- fixed : true ,
40- event : null ,
41- effect : function ( ) { $ ( this ) . hide ( ) ; } , // don't do any fancy fading because it screws up with scrolling
42- } ,
43- } ;
44-
4531
4632// TODO: refactor into ES6 class format
4733
4834// domID is the ID of the element to attach to (without the leading '#' sign)
49- function SyntaxErrorSurveyBubble ( parentViz , domID ) {
35+ function SyntaxErrorSurveyBubble ( parentViz , domID , offendingLine ) {
5036 this . parentViz = parentViz ;
37+ this . offendingLine = offendingLine ;
5138
5239 this . domID = domID ;
5340 this . hashID = '#' + domID ;
@@ -242,22 +229,24 @@ export class OptFrontendWithTestcases extends OptFrontendSharedSessions {
242229 // is no longer available
243230 if ( codelineIDs . length === 1 ) {
244231 var codLineId = codelineIDs [ 0 ] ;
232+ console . log ( 'codLineId' , codLineId ) ;
233+
234+ var bub = new SyntaxErrorSurveyBubble ( this . myVisualizer , codLineId , offendingLine ) ;
245235
246- var bub = new SyntaxErrorSurveyBubble ( this . myVisualizer , codLineId ) ;
236+ // for debugging
247237 window . bub = bub ;
248238 window . $ = $ ;
249239
250240 // if pyCodeOutputDiv is narrower than the current line, then
251241 // adjust the x position of the pop-up bubble accordingly to be
252242 // flush with the right of pyCodeOutputDiv
253- var pcodWidth = this . myVisualizer . domRoot . find ( '#pyCodeOutputDiv' ) . width ( ) ;
243+ var pcodWidth = this . myVisualizer . domRoot . find ( "#codeDisplayDiv" ) . width ( ) ;
254244 var codLineWidth = this . myVisualizer . domRoot . find ( '#' + codLineId ) . parent ( ) . width ( ) ; // get enclosing 'tr'
255245 var adjustX = 0 ; // default
256246
257- // actually nix this for now to keep things simple ...
258- //if (pcodWidth < codLineWidth) {
259- // adjustX = pcodWidth - codLineWidth; // should be negative!
260- //}
247+ if ( pcodWidth < codLineWidth ) {
248+ adjustX = pcodWidth - codLineWidth ; // should be negative!
249+ }
261250
262251 // Wording of the survey bubble:
263252 /*
@@ -299,152 +288,169 @@ export class OptFrontendWithTestcases extends OptFrontendSharedSessions {
299288 <div id="syntaxErrQuestion">\
300289 Please help us improve error messages for future users.\
301290 If you think the above message wasn\'t helpful, what would have been the best message for you here?<br/>\
302- <input type="text" id="syntaxErrTxtInput" size=60 maxlength=150/><br/>\
291+ <input type="text" id="syntaxErrTxtInput" size=50 maxlength=150/><br/>\
303292 <button id="syntaxErrSubmitBtn" type="button">Submit</button>\
304293 <button id="syntaxErrCloseBtn" type="button">Close</button>\
305294 <a href="#" id="syntaxErrHideAllLink">Hide all of these pop-ups</a>\
306295 </div>\
307296 </div>'
308297
309- // destroy then create a new tip:
310- bub . destroyQTip ( ) ;
311- $ ( bub . hashID ) . qtip ( $ . extend ( { } , qtipShared , {
298+ $ ( bub . hashID ) . qtip ( {
299+
300+ show : {
301+ ready : true , // show on document.ready instead of on mouseenter
302+ delay : 0 ,
303+ event : null ,
304+ effect : function ( ) { $ ( this ) . show ( ) ; } , // don't do any fancy fading because it screws up with scrolling
305+ } ,
306+ hide : {
307+ fixed : true ,
308+ event : null ,
309+ effect : function ( ) { $ ( this ) . hide ( ) ; } , // don't do any fancy fading because it screws up with scrolling
310+ } ,
311+
312312 content : surveyBubbleHTML ,
313+
313314 id : bub . domID ,
315+
314316 position : {
315317 my : bub . my ,
316318 at : bub . at ,
317319 adjust : {
318320 x : adjustX ,
319321 } ,
320- effect : null , // disable all cutesy animations
322+ effect : null , // disable all animations
321323 } ,
324+
322325 style : {
323326 classes : 'qtip-light' ,
324- }
325- } ) ) ;
326-
327- // unbind first, then bind a new one
328- this . myVisualizer . domRoot . find ( '#pyCodeOutputDiv' )
329- . unbind ( 'scroll' )
330- . scroll ( function ( ) {
331- bub . redrawCodelineBubble ( ) ;
332- } ) ;
333-
334- $ ( bub . qTipContentID ( ) + ' #syntaxErrSubmitBtn' ) . click ( ( ) => {
335- var res = $ ( bub . qTipContentID ( ) + ' #syntaxErrTxtInput' ) . val ( ) ;
336- var resObj = { appState : this . getAppState ( ) ,
337- exc : prevExecutionExceptionObj , // note that this.prevExecutionExceptionObjLst is BLOWN AWAY by now
338- opt_uuid : this . userUUID ,
339- session_uuid : this . sessionUUID ,
340- reply : res ,
341- type : 'submit' ,
342- v : version } ;
343- $ . get ( 'syntax_err_survey.py' , { arg : JSON . stringify ( resObj ) } , function ( dat ) { } ) ;
344-
345- bub . destroyQTip ( ) ;
346- } ) ;
347-
348- $ ( bub . qTipContentID ( ) + ' #syntaxErrCloseBtn' ) . click ( ( ) => {
349- // grab the value anyways in case the learner wrote something decent ...
350- var res = $ ( bub . qTipContentID ( ) + ' #syntaxErrTxtInput' ) . val ( ) ;
351- var resObj = { appState : this . getAppState ( ) ,
352- exc : prevExecutionExceptionObj , // note that this.prevExecutionExceptionObjLst is BLOWN AWAY by now
353- opt_uuid : this . userUUID ,
354- session_uuid : this . sessionUUID ,
355- reply : res ,
356- type : 'close' ,
357- v : version } ;
358-
359- //console.log(resObj);
360- $ . get ( 'syntax_err_survey.py' , { arg : JSON . stringify ( resObj ) } , function ( dat ) { } ) ;
361-
362- bub . destroyQTip ( ) ;
363- } ) ;
327+ } ,
364328
365- $ ( bub . qTipContentID ( ) + ' #syntaxErrHideAllLink' ) . click ( ( ) => {
366- // grab the value anyways in case the learner wrote something decent ...
367- var res = $ ( bub . qTipContentID ( ) + ' #syntaxErrTxtInput' ) . val ( ) ;
368- var resObj = { appState : this . getAppState ( ) ,
369- exc : prevExecutionExceptionObj , // note that this.prevExecutionExceptionObjLst is BLOWN AWAY by now
370- opt_uuid : this . userUUID ,
371- session_uuid : this . sessionUUID ,
372- reply : res ,
373- type : 'killall' ,
374- v : version } ;
375-
376- this . activateSyntaxErrorSurvey = false ;
377- $ . get ( 'syntax_err_survey.py' , { arg : JSON . stringify ( resObj ) } , function ( dat ) { } ) ;
378- bub . destroyQTip ( ) ;
379- return false ; // otherwise the 'a href' will trigger a page reload, ergh!
329+ events : {
330+ render : ( event , api ) => {
331+ var bubbleAceEditor = ace . edit ( 'syntaxErrCodeDisplay' ) ;
332+ bubbleAceEditor . $blockScrolling = Infinity ; // kludgy to shut up weird warnings
333+ bubbleAceEditor . setOptions ( { minLines : 1 , maxLines : 5 } ) ; // keep this SMALL
334+ bubbleAceEditor . setValue ( prevExecutionExceptionObj . myAppState . code . rtrim ( ) /* kill trailing spaces */ ,
335+ - 1 /* do NOT select after setting text */ ) ;
336+ bubbleAceEditor . setHighlightActiveLine ( false ) ;
337+ bubbleAceEditor . setShowPrintMargin ( false ) ;
338+ bubbleAceEditor . setBehavioursEnabled ( false ) ;
339+ bubbleAceEditor . setFontSize ( '10px' ) ;
340+ bubbleAceEditor . setReadOnly ( true ) ;
341+
342+ var s = bubbleAceEditor . getSession ( ) ;
343+ // tab -> 4 spaces
344+ s . setTabSize ( 4 ) ;
345+ s . setUseSoftTabs ( true ) ;
346+ // disable extraneous indicators:
347+ s . setFoldStyle ( 'manual' ) ; // no code folding indicators
348+ s . getDocument ( ) . setNewLineMode ( 'unix' ) ; // canonicalize all newlines to unix format
349+ // don't do real-time syntax checks:
350+ // https://github.com/ajaxorg/ace/wiki/Syntax-validation
351+ s . setOption ( "useWorker" , false ) ;
352+
353+ $ ( '#syntaxErrCodeDisplay' ) . css ( 'width' , '320px' ) ;
354+ $ ( '#syntaxErrCodeDisplay' ) . css ( 'height' , '90px' ) ; // VERY IMPORTANT so that it works on I.E., ugh!
355+
356+ var lang = prevExecutionExceptionObj . myAppState . py ;
357+ var mod = 'python' ;
358+ if ( lang === 'java' ) {
359+ mod = 'java' ;
360+ } else if ( lang === 'js' ) {
361+ mod = 'javascript' ;
362+ } else if ( lang === 'ts' ) {
363+ mod = 'typescript' ;
364+ } else if ( lang === 'ruby' ) {
365+ mod = 'ruby' ;
366+ } else if ( lang === 'c' || lang === 'cpp' ) {
367+ mod = 'c_cpp' ;
368+ }
369+ s . setMode ( "ace/mode/" + mod ) ;
370+
371+ s . setAnnotations ( [ { row : offendingLine - 1 /* zero-indexed */ ,
372+ column : null , // for TS typechecking
373+ type : 'error' ,
374+ text : prevExecutionExceptionObj . killerException . exception_msg } ] ) ;
375+
376+ window . bubbleAceEditor = bubbleAceEditor ; // for debugging
377+
378+ // don't forget htmlspecialchars
379+ $ ( "#syntaxErrMsg" ) . html ( htmlspecialchars ( prevExecutionExceptionObj . killerException . exception_msg ) ) ;
380+
381+ bubbleAceEditor . scrollToLine ( offendingLine - 1 , true /* center */ , true , ( ) => { } ) ;
382+
383+
384+ // unbind first, then bind a new one
385+ this . myVisualizer . domRoot . find ( '#pyCodeOutputDiv' )
386+ . unbind ( 'scroll' )
387+ . scroll ( function ( ) {
388+ bub . redrawCodelineBubble ( ) ;
389+ } ) ;
390+
391+ $ ( bub . qTipContentID ( ) + ' #syntaxErrSubmitBtn' ) . click ( ( ) => {
392+ var res = $ ( bub . qTipContentID ( ) + ' #syntaxErrTxtInput' ) . val ( ) ;
393+ var resObj = { appState : this . getAppState ( ) ,
394+ exc : prevExecutionExceptionObj , // note that this.prevExecutionExceptionObjLst is BLOWN AWAY by now
395+ opt_uuid : this . userUUID ,
396+ session_uuid : this . sessionUUID ,
397+ reply : res ,
398+ type : 'submit' ,
399+ v : version } ;
400+ $ . get ( 'syntax_err_survey.py' , { arg : JSON . stringify ( resObj ) } , function ( dat ) { } ) ;
401+
402+ bub . destroyQTip ( ) ;
403+ } ) ;
404+
405+ $ ( bub . qTipContentID ( ) + ' #syntaxErrCloseBtn' ) . click ( ( ) => {
406+ // grab the value anyways in case the learner wrote something decent ...
407+ var res = $ ( bub . qTipContentID ( ) + ' #syntaxErrTxtInput' ) . val ( ) ;
408+ var resObj = { appState : this . getAppState ( ) ,
409+ exc : prevExecutionExceptionObj , // note that this.prevExecutionExceptionObjLst is BLOWN AWAY by now
410+ opt_uuid : this . userUUID ,
411+ session_uuid : this . sessionUUID ,
412+ reply : res ,
413+ type : 'close' ,
414+ v : version } ;
415+
416+ //console.log(resObj);
417+ $ . get ( 'syntax_err_survey.py' , { arg : JSON . stringify ( resObj ) } , function ( dat ) { } ) ;
418+
419+ bub . destroyQTip ( ) ;
420+ } ) ;
421+
422+ $ ( bub . qTipContentID ( ) + ' #syntaxErrHideAllLink' ) . click ( ( ) => {
423+ // grab the value anyways in case the learner wrote something decent ...
424+ var res = $ ( bub . qTipContentID ( ) + ' #syntaxErrTxtInput' ) . val ( ) ;
425+ var resObj = { appState : this . getAppState ( ) ,
426+ exc : prevExecutionExceptionObj , // note that this.prevExecutionExceptionObjLst is BLOWN AWAY by now
427+ opt_uuid : this . userUUID ,
428+ session_uuid : this . sessionUUID ,
429+ reply : res ,
430+ type : 'killall' ,
431+ v : version } ;
432+
433+ this . activateSyntaxErrorSurvey = false ;
434+ $ . get ( 'syntax_err_survey.py' , { arg : JSON . stringify ( resObj ) } , function ( dat ) { } ) ;
435+ bub . destroyQTip ( ) ;
436+ return false ; // otherwise the 'a href' will trigger a page reload, ergh!
437+ } ) ;
438+
439+ // log an event whenever this bubble is show (i.e., an 'impression')
440+ // NB: it might actually be hidden if it appears on a line that
441+ // isn't initially visible to the user, but whatevers ...
442+ var impressionObj = { appState : this . getAppState ( ) ,
443+ exceptionLst : this . prevExecutionExceptionObjLst ,
444+ opt_uuid : this . userUUID ,
445+ session_uuid : this . sessionUUID ,
446+ type : 'show' ,
447+ v : version } ;
448+ $ . get ( 'syntax_err_survey.py' , { arg : JSON . stringify ( impressionObj ) } , function ( dat ) { } ) ;
449+ }
450+ } ,
380451 } ) ;
381452
382-
383- var bubbleAceEditor = ace . edit ( 'syntaxErrCodeDisplay' ) ;
384- // set the size and value ASAP to get alignment working well ...
385- bubbleAceEditor . setOptions ( { minLines : 1 , maxLines : 5 } ) ; // keep this SMALL
386- bubbleAceEditor . setValue ( prevExecutionExceptionObj . myAppState . code . rtrim ( ) /* kill trailing spaces */ ,
387- - 1 /* do NOT select after setting text */ ) ;
388-
389- var s = bubbleAceEditor . getSession ( ) ;
390- // tab -> 4 spaces
391- s . setTabSize ( 4 ) ;
392- s . setUseSoftTabs ( true ) ;
393- // disable extraneous indicators:
394- s . setFoldStyle ( 'manual' ) ; // no code folding indicators
395- s . getDocument ( ) . setNewLineMode ( 'unix' ) ; // canonicalize all newlines to unix format
396- bubbleAceEditor . setHighlightActiveLine ( false ) ;
397- bubbleAceEditor . setShowPrintMargin ( false ) ;
398- bubbleAceEditor . setBehavioursEnabled ( false ) ;
399- bubbleAceEditor . setFontSize ( '10px' ) ;
400- bubbleAceEditor . $blockScrolling = Infinity ; // kludgy to shut up weird warnings
401-
402- $ ( '#syntaxErrCodeDisplay' ) . css ( 'width' , '320px' ) ;
403- $ ( '#syntaxErrCodeDisplay' ) . css ( 'height' , '90px' ) ; // VERY IMPORTANT so that it works on I.E., ugh!
404-
405- // don't do real-time syntax checks:
406- // https://github.com/ajaxorg/ace/wiki/Syntax-validation
407- s . setOption ( "useWorker" , false ) ;
408-
409- var lang = prevExecutionExceptionObj . myAppState . py ;
410- var mod = 'python' ;
411- if ( lang === 'java' ) {
412- mod = 'java' ;
413- } else if ( lang === 'js' ) {
414- mod = 'javascript' ;
415- } else if ( lang === 'ts' ) {
416- mod = 'typescript' ;
417- } else if ( lang === 'ruby' ) {
418- mod = 'ruby' ;
419- } else if ( lang === 'c' || lang === 'cpp' ) {
420- mod = 'c_cpp' ;
421- }
422- s . setMode ( "ace/mode/" + mod ) ;
423-
424- bubbleAceEditor . setReadOnly ( true ) ;
425-
426- s . setAnnotations ( [ { row : offendingLine - 1 /* zero-indexed */ ,
427- column : null , // for TS typechecking
428- type : 'error' ,
429- text : prevExecutionExceptionObj . killerException . exception_msg } ] ) ;
430- ( bubbleAceEditor as any ) . scrollToLine ( offendingLine , true /* try to center */ ) ;
431-
432- // don't forget htmlspecialchars
433- $ ( "#syntaxErrMsg" ) . html ( htmlspecialchars ( prevExecutionExceptionObj . killerException . exception_msg ) ) ;
434-
435- // TODO: not quite working all the time, eerrrrgghhhh
436- bub . redrawCodelineBubble ( ) ; // do an initial redraw to align everything
437-
438- // log an event whenever this bubble is show (i.e., an 'impression')
439- // NB: it might actually be hidden if it appears on a line that
440- // isn't initially visible to the user, but whatevers ...
441- var impressionObj = { appState : this . getAppState ( ) ,
442- exceptionLst : this . prevExecutionExceptionObjLst ,
443- opt_uuid : this . userUUID ,
444- session_uuid : this . sessionUUID ,
445- type : 'show' ,
446- v : version } ;
447- $ . get ( 'syntax_err_survey.py' , { arg : JSON . stringify ( impressionObj ) } , function ( dat ) { } ) ;
453+ $ ( bub . qTipID ( ) ) . css ( 'border' , '0px' ) ; // get rid of "double" border
448454 }
449455 }
450456 }
0 commit comments