@@ -30,6 +30,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
3030// Massive refactoring notes:
3131// - does jsPlumb have a notion of "sets" of connectors so that we can reset a particular
3232// set rather than ALL connections?
33+ // - or maybe each ExecutionVisualizer instance needs to keep track
34+ // of its own set of jsPlumb elements ...
3335
3436
3537function ExecutionVisualizer ( inputCode , traceData , startingInstruction , domRootID ) {
@@ -84,15 +86,15 @@ ExecutionVisualizer.prototype.render = function() {
8486 this . domRoot . html (
8587 '<table border="0">\
8688 <tr>\
87- <td valign="top">\
89+ <td valign="top" id="left_pane" >\
8890 <center>\
8991 <div id="pyCodeOutputDiv"/>\
9092 <div id="editCodeLinkDiv">\
9193 <button id="editBtn" class="medBtn" type="button">Edit code</button>\
9294 </div>\
9395 <div id="executionSliderCaption">\
94- Click here to focus and then use the left and right arrow keys to step through execution. \
95- <br/> Click on lines of code to set breakpoints.\
96+ Hover here to focus and then use the left and right arrow keys to<br/> \
97+ step through execution. Click on lines of code to set breakpoints.\
9698 </div>\
9799 <div id="executionSlider"/>\
98100 <div id="executionSliderFooter"/>\
@@ -138,7 +140,7 @@ ExecutionVisualizer.prototype.render = function() {
138140 // executed ...
139141 if ( evt . originalEvent ) {
140142 myViz . curInstr = ui . value ;
141- myViz . updateOutput ( true ) ; // need to pass 'true' here to prevent infinite loop
143+ myViz . updateOutput ( ) ;
142144 }
143145 } ) ;
144146
@@ -244,14 +246,22 @@ ExecutionVisualizer.prototype.render = function() {
244246
245247
246248
247- // Set keyboard event listeners for domRoot.
248- // Note that if domRoot is a div, it must have a 'tabindex="0"' attribute set
249- // before it can receive focus and thus receive keyboard events. Set it here:
250- this . domRoot . attr ( 'tabindex' , '0' ) ;
251- this . domRoot . css ( 'outline' , 'none' ) ; // don't display a tacky border when focused
252-
249+ // Set keyboard event listeners for td#left_pane. Note that it must
250+ // have a 'tabindex="0"' attribute set before it can receive focus and
251+ // thus receive keyboard events. Set it here:
252+ var leftTablePane = this . domRoot . find ( 'td#left_pane' ) ;
253253
254- this . domRoot . keydown ( function ( k ) {
254+ leftTablePane . attr ( 'tabindex' , '0' ) ;
255+ leftTablePane . css ( 'outline' , 'none' ) ; // don't display a tacky border when focused
256+
257+ // focus on mouse entering td#left_pane (so that the user doesn't need
258+ // to click to focus)
259+ leftTablePane . mouseenter ( function ( ) {
260+ leftTablePane . focus ( ) ;
261+ } ) ;
262+
263+
264+ leftTablePane . keydown ( function ( k ) {
255265 if ( ! myViz . keyStuckDown ) {
256266 if ( k . keyCode == 37 ) { // left arrow
257267 if ( myViz . curInstr > 0 ) {
@@ -294,15 +304,12 @@ ExecutionVisualizer.prototype.render = function() {
294304 }
295305 } ) ;
296306
297- this . domRoot . keyup ( function ( k ) {
307+ leftTablePane . keyup ( function ( k ) {
298308 myViz . keyStuckDown = false ;
299309 } ) ;
300310
301311
302- this . renderPyCodeOutput ( ) ;
303-
304-
305- // must postprocess traceData prior to running precomputeCurTraceLayouts() ...
312+ // must post-process traceData prior to running precomputeCurTraceLayouts() ...
306313 var lastEntry = this . curTrace [ this . curTrace . length - 1 ] ;
307314
308315 this . instrLimitReached = ( lastEntry . event == 'instruction_limit_reached' ) ;
@@ -321,7 +328,23 @@ ExecutionVisualizer.prototype.render = function() {
321328 }
322329
323330
324- this . precomputeCurTraceLayouts ( ) ; // almost there!!!
331+ this . domRoot . find ( '#executionSlider' ) . slider ( {
332+ min : 0 ,
333+ max : this . curTrace . length - 1 ,
334+ step : 1 ,
335+ } ) ;
336+
337+ //disable keyboard actions on the slider itself (to prevent double-firing of events)
338+ this . domRoot . find ( "#executionSlider .ui-slider-handle" ) . unbind ( 'keydown' ) ;
339+ // make skinnier and taller
340+ this . domRoot . find ( "#executionSlider .ui-slider-handle" ) . css ( 'width' , '0.8em' ) ;
341+ this . domRoot . find ( "#executionSlider .ui-slider-handle" ) . css ( 'height' , '1.4em' ) ;
342+ this . domRoot . find ( ".ui-widget-content" ) . css ( 'font-size' , '0.9em' ) ;
343+
344+
345+ this . precomputeCurTraceLayouts ( ) ;
346+
347+ this . renderPyCodeOutput ( ) ;
325348
326349 this . updateOutput ( ) ;
327350
@@ -559,29 +582,14 @@ ExecutionVisualizer.prototype.renderPyCodeOutput = function() {
559582 } ) ;
560583
561584
562-
563- this . domRoot . find ( '#executionSlider' ) . slider ( {
564- min : 0 ,
565- max : this . curTrace . length - 1 ,
566- step : 1 ,
567- } ) ;
568-
569- //disable keyboard actions on the slider itself (to prevent double-firing of events)
570- this . domRoot . find ( "#executionSlider .ui-slider-handle" ) . unbind ( 'keydown' ) ;
571- // make skinnier and taller
572- this . domRoot . find ( "#executionSlider .ui-slider-handle" ) . css ( 'width' , '0.8em' ) ;
573- this . domRoot . find ( "#executionSlider .ui-slider-handle" ) . css ( 'height' , '1.4em' ) ;
574- this . domRoot . find ( ".ui-widget-content" ) . css ( 'font-size' , '0.9em' ) ;
575-
576-
577585 renderSliderBreakpoints ( ) ; // renders breakpoints written in as code comments
578586}
579587
580588
581589ExecutionVisualizer . prototype . updateOutput = function ( ) {
582590 var myViz = this ; // to prevent confusion of 'this' inside of nested functions
583591
584- this . domRoot . focus ( ) ; // grab focus so that keyboard shortcuts can work
592+ this . domRoot . find ( 'td#left_pane' ) . focus ( ) ; // to start accepting keyboard inputs
585593
586594 assert ( this . curTrace ) ;
587595
@@ -593,6 +601,7 @@ ExecutionVisualizer.prototype.updateOutput = function() {
593601 // render VCR controls:
594602 var totalInstrs = this . curTrace . length ;
595603
604+
596605 // to be user-friendly, if we're on the LAST instruction, print "Program has terminated"
597606 // and DON'T highlight any lines of code in the code display
598607 if ( this . curInstr == ( totalInstrs - 1 ) ) {
@@ -604,7 +613,9 @@ ExecutionVisualizer.prototype.updateOutput = function() {
604613 }
605614 }
606615 else {
607- myViz . domRoot . find ( "#vcrControls #curInstr" ) . html ( "About to run step " + ( this . curInstr + 1 ) + " of " + ( totalInstrs - 1 ) ) ;
616+ myViz . domRoot . find ( "#vcrControls #curInstr" ) . html ( "About to run step " +
617+ String ( this . curInstr + 1 ) +
618+ " of " + String ( totalInstrs - 1 ) ) ;
608619 }
609620
610621
@@ -657,22 +668,20 @@ ExecutionVisualizer.prototype.updateOutput = function() {
657668 myViz . domRootD3 . selectAll ( '#pyCodeOutputDiv td.lineNo' )
658669 . attr ( 'id' , function ( d ) { return 'lineNo' + d . lineNumber ; } )
659670 . style ( 'color' , function ( d )
660- { return d . breakpointHere ? breakpointColor : ( myViz . visitedLinesSet . has ( d . lineNumber ) ? visitedLineColor : null ) ; } )
671+ { return d . breakpointHere ? breakpointColor :
672+ ( myViz . visitedLinesSet . has ( d . lineNumber ) ? visitedLineColor : null ) ;
673+ } )
661674 . style ( 'font-weight' , function ( d )
662- { return d . breakpointHere ? 'bold' : ( myViz . visitedLinesSet . has ( d . lineNumber ) ? 'bold' : null ) ; } ) ;
675+ { return d . breakpointHere ? 'bold' :
676+ ( myViz . visitedLinesSet . has ( d . lineNumber ) ? 'bold' : null ) ;
677+ } ) ;
678+
663679
664680 myViz . domRootD3 . selectAll ( '#pyCodeOutputDiv td.cod' )
665681 . style ( 'background-color' , function ( d ) {
666682 if ( d . lineNumber == curEntry . line ) {
667- if ( hasError ) {
668- d . backgroundColor = errorColor ;
669- }
670- else if ( isTerminated ) {
671- d . backgroundColor = lightBlue ;
672- }
673- else {
674- d . backgroundColor = lightLineColor ;
675- }
683+ d . backgroundColor = hasError ? errorColor :
684+ ( isTerminated ? lightBlue : lightLineColor ) ;
676685 }
677686 else {
678687 d . backgroundColor = null ;
@@ -682,7 +691,7 @@ ExecutionVisualizer.prototype.updateOutput = function() {
682691 } )
683692 . style ( 'border-top' , function ( d ) {
684693 if ( ( d . lineNumber == curEntry . line ) && ! hasError && ! isTerminated ) {
685- return '1px solid #F87D76' ;
694+ return '1px solid ' + errorColor ;
686695 }
687696 else {
688697 // put a default white top border to keep space usage consistent
@@ -691,7 +700,6 @@ ExecutionVisualizer.prototype.updateOutput = function() {
691700 } ) ;
692701
693702
694-
695703 // returns True iff lineNo is visible in pyCodeOutputDiv
696704 function isOutputLineVisible ( lineNo ) {
697705 var lineNoTd = myViz . domRoot . find ( '#lineNo' + lineNo ) ;
0 commit comments