@@ -147,7 +147,7 @@ ExecutionVisualizer.prototype.render = function() {
147147 </div>\
148148 <div id="executionSliderCaption">\
149149 Click here to focus and then use the left and right arrow keys to<br/>\
150- step through execution. Click on lines of code to set breakpoints.\
150+ step through execution. Click on lines of code to set/unset breakpoints.\
151151 </div>\
152152 <div id="executionSlider"/>\
153153 <div id="executionSliderFooter"/>\
@@ -229,17 +229,11 @@ ExecutionVisualizer.prototype.render = function() {
229229 } ) ;
230230
231231 this . domRoot . find ( "#jmpStepBack" ) . click ( function ( ) {
232- if ( myViz . curInstr > 0 ) {
233- myViz . curInstr -= 1 ;
234- myViz . updateOutput ( ) ;
235- }
232+ myViz . stepBack ( ) ;
236233 } ) ;
237234
238235 this . domRoot . find ( "#jmpStepFwd" ) . click ( function ( ) {
239- if ( myViz . curInstr < myViz . curTrace . length - 1 ) {
240- myViz . curInstr += 1 ;
241- myViz . updateOutput ( ) ;
242- }
236+ myViz . stepForward ( ) ;
243237 } ) ;
244238
245239 // disable controls initially ...
@@ -314,58 +308,109 @@ ExecutionVisualizer.prototype.render = function() {
314308} ;
315309
316310
311+ // find the previous/next breakpoint to c or return -1 if it doesn't exist
312+ ExecutionVisualizer . prototype . findPrevBreakpoint = function ( ) {
313+ var myViz = this ;
314+ var c = myViz . curInstr ;
317315
318- ExecutionVisualizer . prototype . setKeyboardBindings = function ( ) {
319- var myViz = this ; // to prevent confusion of 'this' inside of nested functions
320-
321- // find the previous/next breakpoint to c or return -1 if it doesn't exist
322- function findPrevBreakpoint ( c ) {
323- if ( myViz . sortedBreakpointsList . length == 0 ) {
324- return - 1 ;
316+ if ( myViz . sortedBreakpointsList . length == 0 ) {
317+ return - 1 ;
318+ }
319+ else {
320+ for ( var i = 1 ; i < myViz . sortedBreakpointsList . length ; i ++ ) {
321+ var prev = myViz . sortedBreakpointsList [ i - 1 ] ;
322+ var cur = myViz . sortedBreakpointsList [ i ] ;
323+ if ( c <= prev )
324+ return - 1 ;
325+ if ( cur >= c )
326+ return prev ;
325327 }
326- else {
327- for ( var i = 1 ; i < myViz . sortedBreakpointsList . length ; i ++ ) {
328- var prev = myViz . sortedBreakpointsList [ i - 1 ] ;
329- var cur = myViz . sortedBreakpointsList [ i ] ;
330- if ( c <= prev )
331- return - 1 ;
332- if ( cur >= c )
333- return prev ;
334- }
335328
336- // final edge case:
337- var lastElt = myViz . sortedBreakpointsList [ myViz . sortedBreakpointsList . length - 1 ] ;
338- return ( lastElt < c ) ? lastElt : - 1 ;
339- }
329+ // final edge case:
330+ var lastElt = myViz . sortedBreakpointsList [ myViz . sortedBreakpointsList . length - 1 ] ;
331+ return ( lastElt < c ) ? lastElt : - 1 ;
340332 }
333+ }
334+
335+ ExecutionVisualizer . prototype . findNextBreakpoint = function ( ) {
336+ var myViz = this ;
337+ var c = myViz . curInstr ;
341338
342- function findNextBreakpoint ( c ) {
343- if ( myViz . sortedBreakpointsList . length == 0 ) {
344- return - 1 ;
339+ if ( myViz . sortedBreakpointsList . length == 0 ) {
340+ return - 1 ;
341+ }
342+ // usability hack: if you're currently on a breakpoint, then
343+ // single-step forward to the next execution point, NOT the next
344+ // breakpoint. it's often useful to see what happens when the line
345+ // at a breakpoint executes.
346+ else if ( $ . inArray ( c , myViz . sortedBreakpointsList ) >= 0 ) {
347+ return c + 1 ;
348+ }
349+ else {
350+ for ( var i = 0 ; i < myViz . sortedBreakpointsList . length - 1 ; i ++ ) {
351+ var cur = myViz . sortedBreakpointsList [ i ] ;
352+ var next = myViz . sortedBreakpointsList [ i + 1 ] ;
353+ if ( c < cur )
354+ return cur ;
355+ if ( cur <= c && c < next ) // subtle
356+ return next ;
345357 }
346- // usability hack: if you're currently on a breakpoint, then
347- // single-step forward to the next execution point, NOT the next
348- // breakpoint. it's often useful to see what happens when the line
349- // at a breakpoint executes.
350- else if ( $ . inArray ( c , myViz . sortedBreakpointsList ) >= 0 ) {
351- return c + 1 ;
358+
359+ // final edge case:
360+ var lastElt = myViz . sortedBreakpointsList [ myViz . sortedBreakpointsList . length - 1 ] ;
361+ return ( lastElt > c ) ? lastElt : - 1 ;
362+ }
363+ }
364+
365+
366+ // returns true if action successfully taken
367+ ExecutionVisualizer . prototype . stepForward = function ( ) {
368+ var myViz = this ;
369+
370+ if ( myViz . curInstr < myViz . curTrace . length - 1 ) {
371+ // if there is a next breakpoint, then jump to it ...
372+ if ( myViz . sortedBreakpointsList . length > 0 ) {
373+ var nextBreakpoint = myViz . findNextBreakpoint ( ) ;
374+ if ( nextBreakpoint != - 1 )
375+ myViz . curInstr = nextBreakpoint ;
376+ else
377+ myViz . curInstr += 1 ; // prevent "getting stuck" on a solitary breakpoint
352378 }
353379 else {
354- for ( var i = 0 ; i < myViz . sortedBreakpointsList . length - 1 ; i ++ ) {
355- var cur = myViz . sortedBreakpointsList [ i ] ;
356- var next = myViz . sortedBreakpointsList [ i + 1 ] ;
357- if ( c < cur )
358- return cur ;
359- if ( cur <= c && c < next ) // subtle
360- return next ;
361- }
380+ myViz . curInstr += 1 ;
381+ }
382+ myViz . updateOutput ( ) ;
383+ return true ;
384+ }
362385
363- // final edge case:
364- var lastElt = myViz . sortedBreakpointsList [ myViz . sortedBreakpointsList . length - 1 ] ;
365- return ( lastElt > c ) ? lastElt : - 1 ;
386+ return false ;
387+ }
388+
389+ // returns true if action successfully taken
390+ ExecutionVisualizer . prototype . stepBack = function ( ) {
391+ var myViz = this ;
392+
393+ if ( myViz . curInstr > 0 ) {
394+ // if there is a prev breakpoint, then jump to it ...
395+ if ( myViz . sortedBreakpointsList . length > 0 ) {
396+ var prevBreakpoint = myViz . findPrevBreakpoint ( ) ;
397+ if ( prevBreakpoint != - 1 )
398+ myViz . curInstr = prevBreakpoint ;
399+ else
400+ myViz . curInstr -= 1 ; // prevent "getting stuck" on a solitary breakpoint
401+ }
402+ else {
403+ myViz . curInstr -= 1 ;
366404 }
405+ myViz . updateOutput ( ) ;
406+ return true ;
367407 }
368408
409+ return false ;
410+ }
411+
412+ ExecutionVisualizer . prototype . setKeyboardBindings = function ( ) {
413+ var myViz = this ; // to prevent confusion of 'this' inside of nested functions
369414
370415
371416 // Set keyboard event listeners for td#left_pane. Note that it must
@@ -379,39 +424,13 @@ ExecutionVisualizer.prototype.setKeyboardBindings = function() {
379424 leftTablePane . keydown ( function ( k ) {
380425 if ( ! myViz . keyStuckDown ) {
381426 if ( k . keyCode == 37 ) { // left arrow
382- if ( myViz . curInstr > 0 ) {
383- // if there is a prev breakpoint, then jump to it ...
384- if ( myViz . sortedBreakpointsList . length > 0 ) {
385- var prevBreakpoint = findPrevBreakpoint ( myViz . curInstr ) ;
386- if ( prevBreakpoint != - 1 )
387- myViz . curInstr = prevBreakpoint ;
388- else
389- myViz . curInstr -= 1 ; // prevent keyboard keys from "getting stuck" on a solitary breakpoint
390- }
391- else {
392- myViz . curInstr -= 1 ;
393- }
394- myViz . updateOutput ( ) ;
395-
427+ if ( myViz . stepBack ( ) ) {
396428 k . preventDefault ( ) ; // don't horizontally scroll the display
397429 myViz . keyStuckDown = true ;
398430 }
399431 }
400432 else if ( k . keyCode == 39 ) { // right arrow
401- if ( myViz . curInstr < myViz . curTrace . length - 1 ) {
402- // if there is a next breakpoint, then jump to it ...
403- if ( myViz . sortedBreakpointsList . length > 0 ) {
404- var nextBreakpoint = findNextBreakpoint ( myViz . curInstr ) ;
405- if ( nextBreakpoint != - 1 )
406- myViz . curInstr = nextBreakpoint ;
407- else
408- myViz . curInstr += 1 ; // prevent keyboard keys from "getting stuck" on a solitary breakpoint
409- }
410- else {
411- myViz . curInstr += 1 ;
412- }
413- myViz . updateOutput ( ) ;
414-
433+ if ( myViz . stepForward ( ) ) {
415434 k . preventDefault ( ) ; // don't horizontally scroll the display
416435 myViz . keyStuckDown = true ;
417436 }
0 commit comments