]>
Commit | Line | Data |
---|---|---|
1 | /*global $:false, _:false, Morris:false, CodeMirror:false, __report:false, __history:false */ | |
2 | /*jshint browser:true*/ | |
3 | ||
4 | $(function(){ | |
5 | "use strict"; | |
6 | ||
7 | // bootstrap popover | |
8 | $('[rel=popover]').popover(); | |
9 | ||
10 | _.templateSettings = { | |
11 | interpolate : /\{\{(.+?)\}\}/g | |
12 | }; | |
13 | ||
14 | function focusFragment() { | |
15 | $('.plato-mark').removeClass('focus'); | |
16 | var markId = window.location.hash.substr(1); | |
17 | if (markId) $('.' + markId).addClass('focus'); | |
18 | return focusFragment; | |
19 | } | |
20 | ||
21 | window.onhashchange = focusFragment(); | |
22 | ||
23 | var srcEl = document.getElementById('file-source'); | |
24 | ||
25 | var options = { | |
26 | lineNumbers : true, | |
27 | gutters : ['plato-gutter-jshint','plato-gutter-complexity'], | |
28 | readOnly : 'nocursor' | |
29 | }; | |
30 | ||
31 | var cm = CodeMirror.fromTextArea(srcEl, options); | |
32 | ||
33 | var byComplexity = [], bySloc = []; | |
34 | ||
35 | var popoverTemplate = _.template($('#complexity-popover-template').text()); | |
36 | var gutterIcon = $('<a><i class="plato-gutter-icon icon-cog"></i></a>'); | |
37 | ||
38 | var popovers = cm.operation(function(){ | |
39 | var queuedPopovers = []; | |
40 | __report.complexity.functions.forEach(function(fn,i){ | |
41 | byComplexity.push({ | |
42 | label : fn.name, | |
43 | value : fn.complexity.cyclomatic | |
44 | }); | |
45 | bySloc.push({ | |
46 | label : fn.name, | |
47 | value : fn.complexity.sloc.physical, | |
48 | formatter: function (x) { return x + " lines"; } | |
49 | }); | |
50 | ||
51 | var name = fn.name === '<anonymous>' ? 'function\\s*\\([^)]*\\)' : fn.name; | |
52 | var line = fn.line - 1; | |
53 | var className = 'plato-mark-fn-' + i; | |
54 | var gutter = { | |
55 | gutterId : 'plato-gutter-complexity', | |
56 | el : gutterIcon.clone().attr('name',className)[0] | |
57 | }; | |
58 | var popover = { | |
59 | type : 'popover', | |
60 | title : fn.name === '<anonymous>' ? '<anonymous>' : 'function ' + fn.name + '', | |
61 | content : popoverTemplate(fn) | |
62 | }; | |
63 | queuedPopovers.push(cm.markPopoverText({line : line, ch:0}, name, className, gutter, popover)); | |
64 | }); | |
65 | return queuedPopovers; | |
66 | }); | |
67 | ||
68 | popovers.forEach(function(fn){fn();}); | |
69 | ||
70 | var scrollToLine = function(i) { | |
71 | var origScroll = [window.pageXOffset,window.pageYOffset]; | |
72 | window.location.hash = '#plato-mark-fn-' + i; | |
73 | window.scrollTo(origScroll[0],origScroll[1]); | |
74 | var line = __report.complexity.functions[i].line; | |
75 | var coords = cm.charCoords({line : line, ch : 0}); | |
76 | $('body,html').animate({scrollTop : coords.top -50},250); | |
77 | }; | |
78 | ||
79 | // yield to the browser | |
80 | setTimeout(function(){ | |
81 | drawFunctionCharts([ | |
82 | { element: 'fn-by-complexity', data: byComplexity }, | |
83 | { element: 'fn-by-sloc', data: bySloc } | |
84 | ]); | |
85 | drawHistoricalCharts(__history); | |
86 | },0); | |
87 | ||
88 | cm.operation(function(){ | |
89 | addLintMessages(__report); | |
90 | }); | |
91 | ||
92 | ||
93 | function drawFunctionCharts(charts) { | |
94 | charts.forEach(function(chart){ | |
95 | Morris.Donut(chart).on('click',scrollToLine); | |
96 | }); | |
97 | } | |
98 | ||
99 | function drawHistoricalCharts(history) { | |
100 | $('.historical.chart').empty(); | |
101 | var data = _.map(history,function(record){ | |
102 | var date = new Date(record.date); | |
103 | return { | |
104 | date : date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + date.getDate(), | |
105 | maintainability : parseFloat(record.maintainability).toFixed(2), | |
106 | sloc : record.sloc | |
107 | }; | |
108 | }).slice(-20); | |
109 | Morris.Line({ | |
110 | element: 'chart_historical_sloc', | |
111 | data: data, | |
112 | xkey: 'date', | |
113 | ykeys: ['sloc'], | |
114 | labels: ['Lines of Code'], | |
115 | parseTime : false | |
116 | }); | |
117 | Morris.Line({ | |
118 | element: 'chart_historical_maint', | |
119 | data: data, | |
120 | xkey: 'date', | |
121 | ykeys: ['maintainability'], | |
122 | labels: ['Maintainability'], | |
123 | ymax: 100, | |
124 | parseTime : false | |
125 | }); | |
126 | } | |
127 | ||
128 | function addLintMessages(report) { | |
129 | var lines = {}; | |
130 | report.jshint.messages.forEach(function (message) { | |
131 | var text = 'Column: ' + message.column + ' "' + message.message + '"'; | |
132 | if (_.isArray(message.line)) { | |
133 | message.line.forEach(function(line){ | |
134 | if (!lines[line]) lines[line] = ''; | |
135 | lines[line] += '<div class="plato-jshint-message text-'+message.severity+'">' + text + '</div>'; | |
136 | }); | |
137 | } else { | |
138 | if (!lines[message.line]) lines[message.line] = ''; | |
139 | lines[message.line] += '<div class="plato-jshint-message text-'+message.severity+'">' + text + '</div>'; | |
140 | } | |
141 | }); | |
142 | var marker = document.createElement('a'); | |
143 | marker.innerHTML = '<i class="plato-gutter-icon icon-eye-open"></i>'; | |
144 | Object.keys(lines).forEach(function(line){ | |
145 | var lineWidget = document.createElement('div'); | |
146 | lineWidget.innerHTML = lines[line]; | |
147 | cm.setGutterMarker(line - 1, 'plato-gutter-jshint', marker.cloneNode(true)); | |
148 | cm.addLineWidget(line - 1, lineWidget); | |
149 | }); | |
150 | } | |
151 | }); | |
152 |