Skip to content

Commit 3cf05ad

Browse files
committed
Merge branch 'master' into feature/jsp-support
Conflicts: codepulse/src/main/scala/com/secdec/codepulse/tracer/TraceManager.scala codepulse/src/main/scala/com/secdec/codepulse/tracer/TraceUploadData.scala
2 parents f9e2cc7 + 3f7353d commit 3cf05ad

21 files changed

+394
-266
lines changed

codepulse/src/main/resources/toserve/pages/TraceSwitcher/TraceSwitcher.js

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -148,9 +148,7 @@ template html.
148148
onUploadError(e.responseText)
149149
},
150150
progress: function(e, data){
151-
// The actual upload will appear like 90% of the progress.
152-
// The remaining 10% is for the server to parse the file and respond.
153-
updateProgress(0.9 * +data.loaded / +data.total)
151+
updateProgress(+data.loaded / +data.total)
154152
}
155153
})
156154

@@ -178,10 +176,6 @@ template html.
178176
error: function(xhr, status){ onUploadError(xhr.responseText) },
179177
success: function(data){ onUploadDone(data) }
180178
})
181-
// TraceAPI.uploadFilePath(path, function(data, err){
182-
// if(err) onUploadError(err)
183-
// else onUploadDone(data)
184-
// })
185179
}
186180

187181
function updateProgress(ratio){

codepulse/src/main/resources/toserve/pages/traces/TraceStatus.js

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -48,21 +48,17 @@
4848
/*
4949
* Watch for `tracer-state-change` events to update the trace status
5050
*/
51-
$(document).on('tracer-state-change', function(event, params){
52-
switch(params['state']){
53-
case 'connecting':
54-
statusBus.push('connecting')
55-
break
56-
case 'started':
57-
statusBus.push('running')
58-
break
59-
case 'finished':
60-
statusBus.push('idle')
61-
break
62-
}
63-
})
51+
$(document).on('tracer-state-change', function(event, state){ statusBus.push(state) })
6452

65-
Trace.status = statusProp.noLazy()
53+
Trace.status = statusProp.noLazy().log('Trace State:')
6654
Trace.running = runningProp.noLazy()
6755

56+
Trace.ready = function(f){
57+
$(document).ready(function(){
58+
Trace.status
59+
.takeWhile(function(status){ return status == 'loading' })
60+
.onEnd(f)
61+
})
62+
}
63+
6864
})(this.Trace || (this.Trace = {}))

codepulse/src/main/resources/toserve/pages/traces/TraceTreeData.js

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,23 +26,28 @@
2626
treeDataReady = false,
2727
treeDataReadyCallbacks = []
2828

29-
TraceAPI.loadTreemap(function(d){
29+
// Load the treemap data once the trace's status is no longer 'loading'
30+
Trace.ready(function(){
31+
console.log('Trace finished loading. Time to load the treemap data')
3032

31-
treeProjector = new TreeProjector(d)
33+
TraceAPI.loadTreemap(function(d){
3234

33-
fullTree = treeProjector.projectFullTree(true /* generate self nodes for packages */)
35+
treeProjector = new TreeProjector(d)
3436

35-
fullTree.forEachNode(true, function(n){
36-
coverageSets[n.id] = d3.set()
37-
if(n.kind == 'method') totalNumMethods++
38-
})
37+
fullTree = treeProjector.projectFullTree(true /* generate self nodes for packages */)
3938

40-
treeDataReady = true
39+
fullTree.forEachNode(true, function(n){
40+
coverageSets[n.id] = d3.set()
41+
if(n.kind == 'method') totalNumMethods++
42+
})
4143

42-
treeDataReadyCallbacks.forEach(function(callback){
43-
callback()
44-
})
44+
treeDataReady = true
4545

46+
treeDataReadyCallbacks.forEach(function(callback){
47+
callback()
48+
})
49+
50+
})
4651
})
4752

4853
Trace.__defineGetter__('totalNumMethods', function(){

codepulse/src/main/resources/toserve/pages/traces/editable.js

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,13 @@ place.
4646

4747
function saveEditor(){
4848
var txt = $input.val().trim()
49-
$content.text(txt)
50-
setEditing(false)
51-
$elem.trigger('edited', txt)
49+
if(!txt){
50+
closeEditor()
51+
} else {
52+
$content.text(txt)
53+
setEditing(false)
54+
$elem.trigger('editable.save', txt)
55+
}
5256
}
5357

5458
function closeEditor(){
@@ -57,6 +61,7 @@ place.
5761
} else {
5862
setEditing(false)
5963
}
64+
$elem.trigger('editable.cancel')
6065
}
6166

6267
$input.keydown(function(e){
@@ -80,6 +85,8 @@ place.
8085

8186
this.open = function(){ setEditing(true) }
8287

88+
this.getText = function(){ return $content.text().trim() }
89+
8390
//$elem.on('click', ':not(.editing)', function(){ setEditing(true) })
8491
$content.on('click', function(){
8592
setEditing(true)
@@ -102,6 +109,10 @@ place.
102109
e.open()
103110
}
104111

112+
if(action == 'getText'){
113+
return e.getText()
114+
}
115+
105116
return this
106117
}
107118

codepulse/src/main/resources/toserve/pages/traces/trace-recording-controls.js

Lines changed: 41 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -459,77 +459,55 @@
459459
controlsContainer.find('.recording-adder-button'),
460460
controlsContainer.find('.recordingsList'))
461461

462-
// Load any existing user-created recordings from the server, adding them to the UI
463-
TraceAPI.requestRecordings(function(recordings, error){
464-
if(error){ console.error('failed to load recordings') }
465-
else {
466-
recordings.forEach(function(rec){ customRecordingAdder.addNewRecording(rec, false) })
467-
}
462+
// Load any existing user-created recordings from the server, adding them to the UI.
463+
// Don't actually do it until the trace is 'ready' (i.e. the state isn't 'loading').
464+
Trace.ready(function(){
465+
TraceAPI.requestRecordings(function(recordings, error){
466+
if(error){ console.error('failed to load recordings') }
467+
else {
468+
recordings.forEach(function(rec){ customRecordingAdder.addNewRecording(rec, false) })
469+
}
470+
})
468471
})
469472

470473
// assign the 'trace-running' attribute to the controlsContainer, depending on the trace state
471474
Trace.running.assign(controlsContainer, 'attr', 'trace-running')
472475

473-
/*
474-
* Load the current trace status and set the UI accordingly.
475-
* (Don't use animations; just instantly show/hide things.)
476-
*/
477-
TraceAPI.requestStatus(function(status, error){
478-
if(error) console.error('failed to load tracer status from server')
479-
else switch(status){
480-
case 'idle':
481-
newTraceButton.show()
482-
connectionWaitingText.hide()
483-
endTraceButton.hide().overlay('ready')
484-
break
485-
case 'connecting':
486-
newTraceButton.hide()
487-
connectionWaitingText.show()
488-
endTraceButton.hide().overlay('ready')
489-
break
490-
case 'running':
491-
newTraceButton.hide()
492-
connectionWaitingText.hide()
493-
endTraceButton.show().overlay('ready')
494-
break
495-
case 'ending':
496-
newTraceButton.hide()
497-
connectionWaitingText.hide()
498-
endTraceButton.show().overlay('wait')
499-
break
476+
// Update the state of the newTraceArea based on the Trace's state.
477+
;(function(){
478+
function togglerFunc($elem){
479+
return function(show, animate){
480+
if(animate) $elem[show? 'slideDown': 'slideUp']()
481+
else $elem[show? 'show': 'hide']()
482+
}
500483
}
501-
})
484+
var toggleNewTraceButton = togglerFunc(newTraceButton),
485+
toggleConnectingText = togglerFunc(connectionWaitingText),
486+
toggleEndTraceButton = togglerFunc(endTraceButton)
502487

503-
/*
504-
* React to `tracer-state-change` events by showing and hiding
505-
* the appropriate elements using nice animations.
506-
*/
507-
$(document).on('tracer-state-change', function(event, params){
508-
switch(params['state']){
509-
case 'connecting':
510-
newTraceButton.slideUp()
511-
connectionWaitingText.slideDown()
512-
endTraceButton.hide()
513-
break
514-
case 'connected':
515-
// ...nothing?
516-
break
517-
case 'started':
518-
newTraceButton.hide()
519-
connectionWaitingText.slideUp()
520-
endTraceButton.slideDown()
521-
break
522-
case 'finished':
523-
newTraceButton.slideDown()
524-
connectionWaitingText.hide()
525-
endTraceButton.slideUp()
526-
endTraceButton.overlay('ready')
527-
break
528-
case 'deleted':
529-
alert('This trace has been deleted. You will be redirected to the home screen')
530-
window.location.href = '/'
488+
function toggleFinishing(finishing){ endTraceButton.overlay(finishing ? 'wait': 'ready') }
489+
490+
function onStateChange(state, animate){
491+
toggleNewTraceButton(state == 'idle', animate)
492+
toggleConnectingText(state == 'connecting', animate)
493+
toggleEndTraceButton(state == 'running' || state == 'ending', animate)
494+
toggleFinishing(state == 'ending')
531495
}
532-
})
496+
497+
var gotFirstValue = false,
498+
valuesThatCount = d3.set(['idle', 'connecting', 'running', 'ending'])
499+
500+
// When the state changes, show or hide the appropriate divs.
501+
// Depending on whether this is the first 'visible' state change, the show/hide
502+
// effect will have an animation. (it animates after the initial change).
503+
Trace.status.onValue(function(state){
504+
var doAnimate = gotFirstValue
505+
506+
gotFirstValue = gotFirstValue || valuesThatCount.has(state)
507+
508+
onStateChange(state, doAnimate)
509+
})
510+
})()
533511

534512
/* Clicking the newTraceButton asks the server to look for
535513
* a new tracer connection. This may be ignored if the trace
@@ -542,7 +520,6 @@
542520
* that will be closed when the trace's state becomes 'finished'.
543521
*/
544522
endTraceButton.click(function(){
545-
endTraceButton.overlay('wait')
546523
TraceAPI.requestEnd()
547524
})
548525

codepulse/src/main/resources/toserve/pages/traces/traces.css

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,22 @@ body {
22
background: #6D6D6D;
33
}
44

5+
body > .overlay {
6+
/* The waiting overlay for when the trace is loading data.
7+
* It needs to be in front of the other fixed-position things,
8+
* but behind the header and footer.
9+
*/
10+
z-index: 2;
11+
}
12+
13+
body > .overlay:before {
14+
content: 'Processing upload data...';
15+
position: absolute;
16+
top: calc(50% - 50px);
17+
width: 100%;
18+
text-align: center;
19+
}
20+
521
/*************************\
622
| High Level Page Layouts |
723
\*************************/

codepulse/src/main/resources/toserve/pages/traces/traces.js

Lines changed: 66 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,30 @@ $(document).ready(function(){
4848
return spinner
4949
})()
5050

51+
// Set a UI state for the 'loading' and 'deleted' states.
52+
;(function(){
53+
var wasLoading = false
54+
Trace.status.onValue(function(status){
55+
console.log('watching UI, status = ', status)
56+
if(status == 'loading'){
57+
wasLoading = true
58+
$('body').overlay('wait')
59+
} else {
60+
$('body').overlay('ready')
61+
}
62+
63+
if(status == 'deleted'){
64+
if(wasLoading){
65+
alert('Processing upload data failed. You will be redirected to the home screen.')
66+
} else {
67+
alert('This trace has been deleted. You will be redirected to the home screen.')
68+
}
69+
window.location.href = '/'
70+
}
71+
})
72+
})()
73+
74+
5175
// When the `treemapColoringStateChanges` fires, use the current `legendData`
5276
// to generate a new treemap coloring function, and update the treemap's colors
5377
// with that.
@@ -290,6 +314,21 @@ $(document).ready(function(){
290314
else i = i.parent
291315
}
292316

317+
// take the last path node of its kind from the path.
318+
// e.g. [P1, P2, C1, C2, C3, M] becomes [P2, C3, M]
319+
var pathCondensed = []
320+
for(i = path.length-1; i>=0; i--){
321+
var newPath = path[i],
322+
prevPath = path[i+1],
323+
newKind = newPath.kind
324+
prevKind = prevPath && prevPath.kind
325+
if(newKind != prevKind){
326+
pathCondensed.unshift(newPath)
327+
}
328+
}
329+
// render the condensed path instead of the full path.
330+
path = pathCondensed
331+
293332
function recurse(i){
294333
if(i > path.length) return
295334

@@ -324,12 +363,33 @@ $(document).ready(function(){
324363

325364
// Allow the header title to be edited.
326365
// When it changes, send the change to the server to check for name conflicts
327-
$('h1.editable').editable().on('edited', function(e, newName){
328-
TraceAPI.renameTrace(newName, function(reply, error){
329-
if(!error){
330-
var hasNameConflict = (reply.warn == 'nameConflict')
331-
$('.nameConflict').toggleClass('hasConflict', hasNameConflict)
366+
$('h1.editable').editable().on('editable.save.cancel', function(e, newName){
367+
var n = e.namespace
368+
if(!n) return
369+
370+
var nc = $('.nameConflict')
371+
372+
var shouldSave = false
373+
if(n == 'save') shouldSave = true
374+
else if(n == 'cancel'){
375+
if(nc.hasClass('noTraceName')){
376+
shouldSave = true
377+
newName = $(this).editable('getText') || 'Untitled'
332378
}
333-
})
379+
}
380+
381+
if(shouldSave){
382+
TraceAPI.renameTrace(newName, function(reply, error){
383+
if(!error){
384+
var hasNameConflict = (reply.warn == 'nameConflict')
385+
$('.nameConflict').toggleClass('hasConflict', hasNameConflict)
386+
}
387+
})
388+
}
389+
})
390+
391+
// If the nameConflict container has the 'noTraceName' class, open up the name editor now
392+
$('.nameConflict.noTraceName').each(function(){
393+
$('h1.editable').editable('open')
334394
})
335395
})

0 commit comments

Comments
 (0)