Skip to content

Commit 819984e

Browse files
committed
bubbles kinda work but not really
1 parent 33b38c4 commit 819984e

File tree

2 files changed

+157
-157
lines changed

2 files changed

+157
-157
lines changed

v5-unity/css/opt-frontend.css

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -186,30 +186,24 @@ button.surveyBtn {
186186
.qtip-content {
187187
padding: 8px 8px;
188188

189-
color: #333;
190189
background-color: #ffffff;
191190

192-
max-width: 250px;
191+
width: 350px;
192+
max-width: 350px;
193193
min-width: 10px;
194194

195-
border: 2px solid #4284D3;
195+
/*border: 2px solid #4284D3;*/
196+
border: 1px solid #e93f34; /* should match brightRed JavaScript variable */
196197

197198
cursor: pointer;
198199

199-
*border-right-width: 2px;
200-
*border-bottom-width: 2px;
201-
202200
-webkit-border-radius: 5px;
203201
-moz-border-radius: 5px;
204202
border-radius: 5px;
205203

206204
-webkit-box-shadow: 2px 2px 3px 0px rgba(0, 0, 0, 0.2);
207205
-moz-box-shadow: 2px 2px 3px 0px rgba(0, 0, 0, 0.2);
208206
box-shadow: 2px 2px 3px 0px rgba(0, 0, 0, 0.2);
209-
210-
-webkit-background-clip: padding-box;
211-
-moz-background-clip: padding;
212-
background-clip: padding-box;
213207
}
214208

215209
#syntaxErrBubbleContents {

v5-unity/js/visualize.ts

Lines changed: 153 additions & 147 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)