rubycritic 0.0.13 → 0.0.14

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b4f79955ca6f3dab8dccacc5dca7c2b994db9cc7
4
- data.tar.gz: 51bb696eca3c5caa072c1e20a0fb67c1d18c113f
3
+ metadata.gz: 74b9972ae846d78f2a449e831f4f56d5475349d8
4
+ data.tar.gz: 737c696e6b0b42393c3b6ddb2a8f6d09f446fed2
5
5
  SHA512:
6
- metadata.gz: 0794412b39af6196e6d9e70ab55c634744778acf6a9102538ea34a2bbf0aa509fb2f4569437203eb53e0dc770dd73db7095ae2238323e9a10fff1520e30dfb50
7
- data.tar.gz: f93087c069037601daa5f19c21d5794d8b176dbcc81b291b8a3f46f5d14a091bce4d75c0dd2d0e9b73cc7d0f4c5aa1568ec93ef7f33a91f2d3839010aeee60f6
6
+ metadata.gz: b5490faab830e968d3cdef7cdb0f04c1158197c8b738b30f383f9227fbbc102ba17d0276a248007ce7a668d53640cc54410d09c136f3e4ce24d59c1a9c26653e
7
+ data.tar.gz: d51c2940dc3a15ec3b6551d35c0ee24f6f7e8ed510e3dc74865301ef59e41cf361511e17a6db14e098e45fbdb188cf9524629ad72a35670c1f98d8f1eae05c4b
@@ -1,6 +1,8 @@
1
1
  ---
2
2
  Attribute:
3
3
  enabled: false
4
+ DuplicateMethodCall:
5
+ max_calls: 2
4
6
  IrresponsibleModule:
5
7
  enabled: false
6
8
  NestedIterators:
@@ -27,7 +27,7 @@ module Rubycritic
27
27
  end
28
28
 
29
29
  def aggregate_smells(smell_adapters)
30
- smell_adapters.flat_map(&:smells).sort
30
+ smell_adapters.flat_map(&:smells)
31
31
  end
32
32
  end
33
33
 
@@ -30,10 +30,6 @@ module Rubycritic
30
30
  end
31
31
  alias_method :eql?, :==
32
32
 
33
- def <=>(other)
34
- locations <=> other.locations
35
- end
36
-
37
33
  def to_s
38
34
  "(#{type}) #{context} #{message}"
39
35
  end
@@ -46,9 +46,11 @@ function toggleSmells() {
46
46
  $(".js-smells").toggle();
47
47
  }
48
48
 
49
- $("#js-code-table").tablesorter({
50
- sortList: [[0,0]] // sort on the first column, order asc
51
- });
49
+ $("#js-index-table")
50
+ .tablesorter({ // Sort the table
51
+ sortList: [[0,0]] // on the first column, in ascending order
52
+ })
53
+ .floatThead(); // Make table headers stick to the top when scrolling
52
54
 
53
55
  $("#js-chart-container").highcharts({
54
56
  chart: {
@@ -0,0 +1,754 @@
1
+ // @preserve jQuery.floatThead 1.2.7 - http://mkoryak.github.io/floatThead/ - Copyright (c) 2012 - 2014 Misha Koryak
2
+ // @license MIT
3
+
4
+ /* @author Misha Koryak
5
+ * @projectDescription lock a table header in place while scrolling - without breaking styles or events bound to the header
6
+ *
7
+ * Dependencies:
8
+ * jquery 1.9.0 + [required] OR jquery 1.7.0 + jquery UI core
9
+ *
10
+ * http://mkoryak.github.io/floatThead/
11
+ *
12
+ * Tested on FF13+, Chrome 21+, IE8, IE9, IE10, IE11
13
+ *
14
+ */
15
+ (function( $ ) {
16
+ /**
17
+ * provides a default config object. You can modify this after including this script if you want to change the init defaults
18
+ * @type {Object}
19
+ */
20
+ $.floatThead = $.floatThead || {};
21
+ $.floatThead.defaults = {
22
+ cellTag: 'th:visible', //thead cells are this
23
+ zIndex: 1001, //zindex of the floating thead (actually a container div)
24
+ debounceResizeMs: 10,
25
+ useAbsolutePositioning: true, //if set to NULL - defaults: has scrollContainer=true, doesn't have scrollContainer=false
26
+ scrollingTop: 0, //String or function($table) - offset from top of window where the header should not pass above
27
+ scrollingBottom: 0, //String or function($table) - offset from the bottom of the table where the header should stop scrolling
28
+ scrollContainer: function($table){
29
+ return $([]); //if the table has horizontal scroll bars then this is the container that has overflow:auto and causes those scroll bars
30
+ },
31
+ getSizingRow: function($table, $cols, $fthCells){ // this is only called when using IE,
32
+ // override it if the first row of the table is going to contain colgroups (any cell spans greater then one col)
33
+ // it should return a jquery object containing a wrapped set of table cells comprising a row that contains no col spans and is visible
34
+ return $table.find('tbody tr:visible:first>td');
35
+ },
36
+ floatTableClass: 'floatThead-table',
37
+ floatWrapperClass: 'floatThead-wrapper',
38
+ floatContainerClass: 'floatThead-container',
39
+ copyTableClass: true, //copy 'class' attribute from table into the floated table so that the styles match.
40
+ debug: false //print possible issues (that don't prevent script loading) to console, if console exists.
41
+ };
42
+
43
+ var util = window._;
44
+
45
+ //browser stuff
46
+ var ieVersion = function(){for(var a=3,b=document.createElement("b"),c=b.all||[];a = 1+a,b.innerHTML="<!--[if gt IE "+ a +"]><i><![endif]-->",c[0];);return 4<a?a:document.documentMode}();
47
+ var isChrome = null;
48
+ var isChromeCheck = function(){
49
+ if(ieVersion){
50
+ return false;
51
+ }
52
+ var $table = $("<table><colgroup><col></colgroup><tbody><tr><td style='width:10px'></td></tbody></table>");
53
+ $('body').append($table);
54
+ var width = $table.find('col').width();
55
+ $table.remove();
56
+ return width == 0;
57
+ };
58
+
59
+ var $window = $(window);
60
+ var floatTheadCreated = 0;
61
+
62
+
63
+ /**
64
+ * @param debounceMs
65
+ * @param cb
66
+ */
67
+
68
+ function windowResize(debounceMs, eventName, cb){
69
+ if(ieVersion == 8){ //ie8 is crap: https://github.com/mkoryak/floatThead/issues/65
70
+ var winWidth = $window.width();
71
+ var debouncedCb = util.debounce(function(){
72
+ var winWidthNew = $window.width();
73
+ if(winWidth != winWidthNew){
74
+ winWidth = winWidthNew;
75
+ cb();
76
+ }
77
+ }, debounceMs);
78
+ $window.on(eventName, debouncedCb);
79
+ } else {
80
+ $window.on(eventName, util.debounce(cb, debounceMs));
81
+ }
82
+ }
83
+
84
+
85
+ function debug(str){
86
+ window.console && window.console && window.console.log && window.console.log(str);
87
+ }
88
+
89
+ /**
90
+ * try to calculate the scrollbar width for your browser/os
91
+ * @return {Number}
92
+ */
93
+ function scrollbarWidth() {
94
+ var $div = $( //borrowed from anti-scroll
95
+ '<div style="width:50px;height:50px;overflow-y:scroll;'
96
+ + 'position:absolute;top:-200px;left:-200px;"><div style="height:100px;width:100%">'
97
+ + '</div>'
98
+ );
99
+ $('body').append($div);
100
+ var w1 = $div.innerWidth();
101
+ var w2 = $('div', $div).innerWidth();
102
+ $div.remove();
103
+ return w1 - w2;
104
+ }
105
+ /**
106
+ * Check if a given table has been datatableized (http://datatables.net)
107
+ * @param $table
108
+ * @return {Boolean}
109
+ */
110
+ function isDatatable($table){
111
+ if($table.dataTableSettings){
112
+ for(var i = 0; i < $table.dataTableSettings.length; i++){
113
+ var table = $table.dataTableSettings[i].nTable;
114
+ if($table[0] == table){
115
+ return true;
116
+ }
117
+ }
118
+ }
119
+ return false;
120
+ }
121
+ $.fn.floatThead = function(map){
122
+ map = map || {};
123
+ if(!util){ //may have been included after the script? lets try to grab it again.
124
+ util = window._ || $.floatThead._;
125
+ if(!util){
126
+ throw new Error("jquery.floatThead-slim.js requires underscore. You should use the non-lite version since you do not have underscore.");
127
+ }
128
+ }
129
+
130
+ if(ieVersion < 8){
131
+ return this; //no more crappy browser support.
132
+ }
133
+
134
+ if(isChrome == null){ //make sure this is done only once no matter how many times you call the plugin fn
135
+ isChrome = isChromeCheck(); //need to call this after dom ready, and now it is.
136
+ if(isChrome){
137
+ //because chrome cant read <col> width, these elements are used for sizing the table. Need to create new elements because they must be unstyled by user's css.
138
+ document.createElement('fthtr'); //tr
139
+ document.createElement('fthtd'); //td
140
+ document.createElement('fthfoot'); //tfoot
141
+ }
142
+ }
143
+ if(util.isString(map)){
144
+ var command = map;
145
+ var ret = this;
146
+ this.filter('table').each(function(){
147
+ var obj = $(this).data('floatThead-attached');
148
+ if(obj && util.isFunction(obj[command])){
149
+ var r = obj[command]();
150
+ if(typeof r !== 'undefined'){
151
+ ret = r;
152
+ }
153
+ }
154
+ });
155
+ return ret;
156
+ }
157
+ var opts = $.extend({}, $.floatThead.defaults || {}, map);
158
+
159
+ $.each(map, function(key, val){
160
+ if((!(key in $.floatThead.defaults)) && opts.debug){
161
+ debug("jQuery.floatThead: used ["+key+"] key to init plugin, but that param is not an option for the plugin. Valid options are: "+ (util.keys($.floatThead.defaults)).join(', '));
162
+ }
163
+ });
164
+
165
+ this.filter(':not(.'+opts.floatTableClass+')').each(function(){
166
+ var floatTheadId = floatTheadCreated;
167
+ var $table = $(this);
168
+ if($table.data('floatThead-attached')){
169
+ return true; //continue the each loop
170
+ }
171
+ if(!$table.is('table')){
172
+ throw new Error('jQuery.floatThead must be run on a table element. ex: $("table").floatThead();');
173
+ }
174
+ var $header = $table.find('thead:first');
175
+ var $tbody = $table.find('tbody:first');
176
+ if($header.length == 0){
177
+ throw new Error('jQuery.floatThead must be run on a table that contains a <thead> element');
178
+ }
179
+ var headerFloated = false;
180
+ var scrollingTop, scrollingBottom;
181
+ var scrollbarOffset = {vertical: 0, horizontal: 0};
182
+ var scWidth = scrollbarWidth();
183
+ var lastColumnCount = 0; //used by columnNum()
184
+ var $scrollContainer = opts.scrollContainer($table) || $([]); //guard against returned nulls
185
+
186
+ var useAbsolutePositioning = opts.useAbsolutePositioning;
187
+ if(useAbsolutePositioning == null){ //defaults: locked=true, !locked=false
188
+ useAbsolutePositioning = opts.scrollContainer($table).length;
189
+ }
190
+ var $caption = $table.find("caption");
191
+ var haveCaption = $caption.length == 1;
192
+ if(haveCaption){
193
+ var captionAlignTop = ($caption.css("caption-side") || $caption.attr("align") || "top") === "top";
194
+ }
195
+
196
+ var $fthGrp = $('<fthfoot style="display:table-footer-group;"/>');
197
+
198
+ var locked = $scrollContainer.length > 0;
199
+ var wrappedContainer = false; //used with absolute positioning enabled. did we need to wrap the scrollContainer/table with a relative div?
200
+ var $wrapper = $([]); //used when absolute positioning enabled - wraps the table and the float container
201
+ var absoluteToFixedOnScroll = ieVersion <= 9 && !locked && useAbsolutePositioning; //on ie using absolute positioning doesnt look good with window scrolling, so we change positon to fixed on scroll, and then change it back to absolute when done.
202
+ var $floatTable = $("<table/>");
203
+ var $floatColGroup = $("<colgroup/>");
204
+ var $tableColGroup = $table.find('colgroup:first');
205
+ var existingColGroup = true;
206
+ if($tableColGroup.length == 0){
207
+ $tableColGroup = $("<colgroup/>");
208
+ existingColGroup = false;
209
+ }
210
+ var $fthRow = $('<fthrow style="display:table-row;height:0;"/>'); //created unstyled elements
211
+ var $floatContainer = $('<div style="overflow: hidden;"></div>');
212
+ var $newHeader = $("<thead/>");
213
+ var $sizerRow = $('<tr class="size-row"/>');
214
+ var $sizerCells = $([]);
215
+ var $tableCells = $([]); //used for sizing - either $sizerCells or $tableColGroup cols. $tableColGroup cols are only created in chrome for borderCollapse:collapse because of a chrome bug.
216
+ var $headerCells = $([]);
217
+ var $fthCells = $([]); //created elements
218
+
219
+ $newHeader.append($sizerRow);
220
+ $table.prepend($tableColGroup);
221
+ if(isChrome){
222
+ $fthGrp.append($fthRow);
223
+ $table.append($fthGrp);
224
+ }
225
+
226
+ $floatTable.append($floatColGroup);
227
+ $floatContainer.append($floatTable);
228
+ if(opts.copyTableClass){
229
+ $floatTable.attr('class', $table.attr('class'));
230
+ }
231
+ $floatTable.attr({ //copy over some deprecated table attributes that people still like to use. Good thing poeple dont use colgroups...
232
+ 'cellpadding': $table.attr('cellpadding'),
233
+ 'cellspacing': $table.attr('cellspacing'),
234
+ 'border': $table.attr('border')
235
+ });
236
+
237
+ $floatTable.addClass(opts.floatTableClass).css('margin', 0); //must have no margins or you wont be able to click on things under floating table
238
+
239
+ if(useAbsolutePositioning){
240
+ var makeRelative = function($container, alwaysWrap){
241
+ var positionCss = $container.css('position');
242
+ var relativeToScrollContainer = (positionCss == "relative" || positionCss == "absolute");
243
+ if(!relativeToScrollContainer || alwaysWrap){
244
+ var css = {"paddingLeft": $container.css('paddingLeft'), "paddingRight": $container.css('paddingRight')};
245
+ $floatContainer.css(css);
246
+ $container = $container.wrap("<div class='"+opts.floatWrapperClass+"' style='position: relative; clear:both;'></div>").parent();
247
+ wrappedContainer = true;
248
+ }
249
+ return $container;
250
+ };
251
+ if(locked){
252
+ $wrapper = makeRelative($scrollContainer, true);
253
+ $wrapper.append($floatContainer);
254
+ } else {
255
+ $wrapper = makeRelative($table);
256
+ $table.after($floatContainer);
257
+ }
258
+ } else {
259
+ $table.after($floatContainer);
260
+ }
261
+
262
+
263
+ $floatContainer.css({
264
+ position: useAbsolutePositioning ? 'absolute' : 'fixed',
265
+ marginTop: 0,
266
+ top: useAbsolutePositioning ? 0 : 'auto',
267
+ zIndex: opts.zIndex
268
+ });
269
+ $floatContainer.addClass(opts.floatContainerClass);
270
+ updateScrollingOffsets();
271
+
272
+ var layoutFixed = {'table-layout': 'fixed'};
273
+ var layoutAuto = {'table-layout': $table.css('tableLayout') || 'auto'};
274
+ var originalTableWidth = $table[0].style.width || ""; //setting this to auto is bad: #70
275
+
276
+ function eventName(name){
277
+ return name+'.fth-'+floatTheadId+'.floatTHead'
278
+ }
279
+
280
+ function setHeaderHeight(){
281
+ var headerHeight = 0;
282
+ $header.find("tr").each(function(){
283
+ headerHeight += $(this).outerHeight(true);
284
+ });
285
+ $sizerRow.outerHeight(headerHeight);
286
+ $sizerCells.outerHeight(headerHeight);
287
+ }
288
+
289
+
290
+ function setFloatWidth(){
291
+ var tableWidth = $table.outerWidth();
292
+ var width = $scrollContainer.width() || tableWidth;
293
+ $floatContainer.width(width - scrollbarOffset.vertical);
294
+ if(locked){
295
+ var percent = 100 * tableWidth / (width - scrollbarOffset.vertical);
296
+ $floatTable.css('width', percent+'%');
297
+ } else {
298
+ $floatTable.outerWidth(tableWidth);
299
+ }
300
+ }
301
+
302
+ function updateScrollingOffsets(){
303
+ scrollingTop = (util.isFunction(opts.scrollingTop) ? opts.scrollingTop($table) : opts.scrollingTop) || 0;
304
+ scrollingBottom = (util.isFunction(opts.scrollingBottom) ? opts.scrollingBottom($table) : opts.scrollingBottom) || 0;
305
+ }
306
+
307
+ /**
308
+ * get the number of columns and also rebuild resizer rows if the count is different then the last count
309
+ */
310
+ function columnNum(){
311
+ var count, $headerColumns;
312
+ if(existingColGroup){
313
+ count = $tableColGroup.find('col').length;
314
+ } else {
315
+ $headerColumns = $header.find('tr:first>'+opts.cellTag);
316
+ count = 0;
317
+ $headerColumns.each(function(){
318
+ count += parseInt(($(this).attr('colspan') || 1), 10);
319
+ });
320
+ }
321
+ if(count != lastColumnCount){
322
+ lastColumnCount = count;
323
+ var cells = [], cols = [], psuedo = [];
324
+ for(var x = 0; x < count; x++){
325
+ cells.push('<th class="floatThead-col"/>');
326
+ cols.push('<col/>');
327
+ psuedo.push("<fthtd style='display:table-cell;height:0;width:auto;'/>");
328
+ }
329
+
330
+ cols = cols.join('');
331
+ cells = cells.join('');
332
+
333
+ if(isChrome){
334
+ psuedo = psuedo.join('');
335
+ $fthRow.html(psuedo);
336
+ $fthCells = $fthRow.find('fthtd');
337
+ }
338
+
339
+ $sizerRow.html(cells);
340
+ $sizerCells = $sizerRow.find("th");
341
+ if(!existingColGroup){
342
+ $tableColGroup.html(cols);
343
+ }
344
+ $tableCells = $tableColGroup.find('col');
345
+ $floatColGroup.html(cols);
346
+ $headerCells = $floatColGroup.find("col");
347
+
348
+ }
349
+ return count;
350
+ }
351
+
352
+ function refloat(){ //make the thing float
353
+ if(!headerFloated){
354
+ headerFloated = true;
355
+ if(useAbsolutePositioning){ //#53, #56
356
+ var tableWidth = $table.width();
357
+ var wrapperWidth = $wrapper.width();
358
+ if(tableWidth > wrapperWidth){
359
+ $table.css('minWidth', tableWidth);
360
+ }
361
+ }
362
+ $table.css(layoutFixed);
363
+ $floatTable.css(layoutFixed);
364
+ $floatTable.append($header); //append because colgroup must go first in chrome
365
+ $tbody.before($newHeader);
366
+ setHeaderHeight();
367
+ }
368
+ }
369
+ function unfloat(){ //put the header back into the table
370
+ if(headerFloated){
371
+ headerFloated = false;
372
+ if(useAbsolutePositioning){ //#53, #56
373
+ $table.width(originalTableWidth);
374
+ }
375
+ $newHeader.detach();
376
+ $table.prepend($header);
377
+ $table.css(layoutAuto);
378
+ $floatTable.css(layoutAuto);
379
+ }
380
+ }
381
+ function changePositioning(isAbsolute){
382
+ if(useAbsolutePositioning != isAbsolute){
383
+ useAbsolutePositioning = isAbsolute;
384
+ $floatContainer.css({
385
+ position: useAbsolutePositioning ? 'absolute' : 'fixed'
386
+ });
387
+ }
388
+ }
389
+ function getSizingRow($table, $cols, $fthCells, ieVersion){
390
+ if(isChrome){
391
+ return $fthCells;
392
+ } else if(ieVersion) {
393
+ return opts.getSizingRow($table, $cols, $fthCells);
394
+ } else {
395
+ return $cols;
396
+ }
397
+ }
398
+
399
+ /**
400
+ * returns a function that updates the floating header's cell widths.
401
+ * @return {Function}
402
+ */
403
+ function reflow(){
404
+ var i;
405
+ var numCols = columnNum(); //if the tables columns change dynamically since last time (datatables) we need to rebuild the sizer rows and get new count
406
+ return function(){
407
+ var $rowCells = getSizingRow($table, $tableCells, $fthCells, ieVersion);
408
+ if($rowCells.length == numCols && numCols > 0){
409
+ if(!existingColGroup){
410
+ for(i=0; i < numCols; i++){
411
+ $tableCells.eq(i).css('width', '');
412
+ }
413
+ }
414
+ unfloat();
415
+ for(i=0; i < numCols; i++){
416
+ var _rowcell = $rowCells.get(i);
417
+ var rowWidth = _rowcell.offsetWidth;
418
+ $headerCells.eq(i).width(rowWidth);
419
+ $tableCells.eq(i).width(rowWidth);
420
+ }
421
+ refloat();
422
+ } else {
423
+ $floatTable.append($header);
424
+ $table.css(layoutAuto);
425
+ $floatTable.css(layoutAuto);
426
+ setHeaderHeight();
427
+ }
428
+ };
429
+ }
430
+
431
+ /**
432
+ * first performs initial calculations that we expect to not change when the table, window, or scrolling container are scrolled.
433
+ * returns a function that calculates the floating container's top and left coords. takes into account if we are using page scrolling or inner scrolling
434
+ * @return {Function}
435
+ */
436
+ function calculateFloatContainerPosFn(){
437
+ var scrollingContainerTop = $scrollContainer.scrollTop();
438
+
439
+ //this floatEnd calc was moved out of the returned function because we assume the table height doesnt change (otherwise we must reinit by calling calculateFloatContainerPosFn)
440
+ var floatEnd;
441
+ var tableContainerGap = 0;
442
+ var captionHeight = haveCaption ? $caption.outerHeight(true) : 0;
443
+ var captionScrollOffset = captionAlignTop ? captionHeight : -captionHeight;
444
+
445
+ var floatContainerHeight = $floatContainer.height();
446
+ var tableOffset = $table.offset();
447
+ if(locked){
448
+ var containerOffset = $scrollContainer.offset();
449
+ tableContainerGap = tableOffset.top - containerOffset.top + scrollingContainerTop;
450
+ if(haveCaption && captionAlignTop){
451
+ tableContainerGap += captionHeight;
452
+ }
453
+ } else {
454
+ floatEnd = tableOffset.top - scrollingTop - floatContainerHeight + scrollingBottom + scrollbarOffset.horizontal;
455
+ }
456
+ var windowTop = $window.scrollTop();
457
+ var windowLeft = $window.scrollLeft();
458
+ var scrollContainerLeft = $scrollContainer.scrollLeft();
459
+ scrollingContainerTop = $scrollContainer.scrollTop();
460
+
461
+
462
+
463
+ return function(eventType){
464
+ if(eventType == 'windowScroll'){
465
+ windowTop = $window.scrollTop();
466
+ windowLeft = $window.scrollLeft();
467
+ } else if(eventType == 'containerScroll'){
468
+ scrollingContainerTop = $scrollContainer.scrollTop();
469
+ scrollContainerLeft = $scrollContainer.scrollLeft();
470
+ } else if(eventType != 'init') {
471
+ windowTop = $window.scrollTop();
472
+ windowLeft = $window.scrollLeft();
473
+ scrollingContainerTop = $scrollContainer.scrollTop();
474
+ scrollContainerLeft = $scrollContainer.scrollLeft();
475
+ }
476
+ if(isChrome && (windowTop < 0 || windowLeft < 0)){ //chrome overscroll effect at the top of the page - breaks fixed positioned floated headers
477
+ return;
478
+ }
479
+
480
+ if(absoluteToFixedOnScroll){
481
+ if(eventType == 'windowScrollDone'){
482
+ changePositioning(true); //change to absolute
483
+ } else {
484
+ changePositioning(false); //change to fixed
485
+ }
486
+ } else if(eventType == 'windowScrollDone'){
487
+ return null; //event is fired when they stop scrolling. ignore it if not 'absoluteToFixedOnScroll'
488
+ }
489
+
490
+ tableOffset = $table.offset();
491
+ if(haveCaption && captionAlignTop){
492
+ tableOffset.top += captionHeight;
493
+ }
494
+ var top, left, tableHeight;
495
+
496
+ if(locked && useAbsolutePositioning){ //inner scrolling, absolute positioning
497
+ if (tableContainerGap >= scrollingContainerTop) {
498
+ var gap = tableContainerGap - scrollingContainerTop;
499
+ gap = gap > 0 ? gap : 0;
500
+ top = gap;
501
+ } else {
502
+ top = wrappedContainer ? 0 : scrollingContainerTop;
503
+ //headers stop at the top of the viewport
504
+ }
505
+ left = 0;
506
+ } else if(!locked && useAbsolutePositioning) { //window scrolling, absolute positioning
507
+ tableHeight = $table.outerHeight();
508
+ if(windowTop > floatEnd + tableHeight + captionScrollOffset){
509
+ top = tableHeight - floatContainerHeight + captionScrollOffset; //scrolled past table
510
+ } else if (tableOffset.top > windowTop + scrollingTop) {
511
+ top = 0; //scrolling to table
512
+ unfloat();
513
+ } else {
514
+ top = scrollingTop + windowTop - tableOffset.top + tableContainerGap + (captionAlignTop ? captionHeight : 0);
515
+ refloat(); //scrolling within table. header floated
516
+ }
517
+ left = 0;
518
+ } else if(locked && !useAbsolutePositioning){ //inner scrolling, fixed positioning
519
+ if (tableContainerGap > scrollingContainerTop) {
520
+ top = tableOffset.top - windowTop;
521
+ unfloat();
522
+ } else {
523
+ top = tableOffset.top + scrollingContainerTop - windowTop - tableContainerGap;
524
+ refloat();
525
+ //headers stop at the top of the viewport
526
+ }
527
+ left = tableOffset.left + scrollContainerLeft - windowLeft;
528
+ } else if(!locked && !useAbsolutePositioning) { //window scrolling, fixed positioning
529
+ tableHeight = $table.outerHeight();
530
+ if(windowTop > floatEnd + tableHeight + captionScrollOffset){
531
+ top = tableHeight + scrollingTop - windowTop + floatEnd + captionScrollOffset;
532
+ //scrolled past the bottom of the table
533
+ } else if (tableOffset.top > windowTop + scrollingTop) {
534
+ top = tableOffset.top - windowTop;
535
+ refloat();
536
+ //scrolled past the top of the table
537
+ } else {
538
+ //scrolling within the table
539
+ top = scrollingTop;
540
+ }
541
+ left = tableOffset.left - windowLeft;
542
+ }
543
+ return {top: top, left: left};
544
+ };
545
+ }
546
+ /**
547
+ * returns a function that caches old floating container position and only updates css when the position changes
548
+ * @return {Function}
549
+ */
550
+ function repositionFloatContainerFn(){
551
+ var oldTop = null;
552
+ var oldLeft = null;
553
+ var oldScrollLeft = null;
554
+ return function(pos, setWidth, setHeight){
555
+ if(pos != null && (oldTop != pos.top || oldLeft != pos.left)){
556
+ $floatContainer.css({
557
+ top: pos.top,
558
+ left: pos.left
559
+ });
560
+ oldTop = pos.top;
561
+ oldLeft = pos.left;
562
+ }
563
+ if(setWidth){
564
+ setFloatWidth();
565
+ }
566
+ if(setHeight){
567
+ setHeaderHeight();
568
+ }
569
+ var scrollLeft = $scrollContainer.scrollLeft();
570
+ if(oldScrollLeft != scrollLeft){
571
+ $floatContainer.scrollLeft(scrollLeft);
572
+ oldScrollLeft = scrollLeft;
573
+ }
574
+ }
575
+ }
576
+
577
+ /**
578
+ * checks if THIS table has scrollbars, and finds their widths
579
+ */
580
+ function calculateScrollBarSize(){ //this should happen after the floating table has been positioned
581
+ if($scrollContainer.length){
582
+ scrollbarOffset.horizontal = $scrollContainer.width() < $table.width() ? scWidth : 0;
583
+ scrollbarOffset.vertical = $scrollContainer.height() < $table.height() ? scWidth: 0;
584
+ }
585
+ }
586
+ //finish up. create all calculation functions and bind them to events
587
+ calculateScrollBarSize();
588
+
589
+ var flow;
590
+
591
+ var ensureReflow = function(){
592
+ flow = reflow();
593
+ flow();
594
+ };
595
+
596
+ ensureReflow();
597
+
598
+ var calculateFloatContainerPos = calculateFloatContainerPosFn();
599
+ var repositionFloatContainer = repositionFloatContainerFn();
600
+
601
+ repositionFloatContainer(calculateFloatContainerPos('init'), true); //this must come after reflow because reflow changes scrollLeft back to 0 when it rips out the thead
602
+
603
+ var windowScrollDoneEvent = util.debounce(function(){
604
+ repositionFloatContainer(calculateFloatContainerPos('windowScrollDone'), false);
605
+ }, 300);
606
+
607
+ var windowScrollEvent = function(){
608
+ repositionFloatContainer(calculateFloatContainerPos('windowScroll'), false);
609
+ windowScrollDoneEvent();
610
+ };
611
+ var containerScrollEvent = function(){
612
+ repositionFloatContainer(calculateFloatContainerPos('containerScroll'), false);
613
+ };
614
+
615
+
616
+ var windowResizeEvent = function(){
617
+ updateScrollingOffsets();
618
+ calculateScrollBarSize();
619
+ ensureReflow();
620
+ calculateFloatContainerPos = calculateFloatContainerPosFn();
621
+ repositionFloatContainer = repositionFloatContainerFn();
622
+ repositionFloatContainer(calculateFloatContainerPos('resize'), true, true);
623
+ };
624
+ var reflowEvent = util.debounce(function(){
625
+ calculateScrollBarSize();
626
+ updateScrollingOffsets();
627
+ ensureReflow();
628
+ calculateFloatContainerPos = calculateFloatContainerPosFn();
629
+ repositionFloatContainer(calculateFloatContainerPos('reflow'), true);
630
+ }, 1);
631
+ if(locked){ //internal scrolling
632
+ if(useAbsolutePositioning){
633
+ $scrollContainer.on(eventName('scroll'), containerScrollEvent);
634
+ } else {
635
+ $scrollContainer.on(eventName('scroll'), containerScrollEvent);
636
+ $window.on(eventName('scroll'), windowScrollEvent);
637
+ }
638
+ } else { //window scrolling
639
+ $window.on(eventName('scroll'), windowScrollEvent);
640
+ }
641
+
642
+ $window.on(eventName('load'), reflowEvent); //for tables with images
643
+
644
+ windowResize(opts.debounceResizeMs, eventName('resize'), windowResizeEvent);
645
+ $table.on('reflow', reflowEvent);
646
+ if(isDatatable($table)){
647
+ $table
648
+ .on('filter', reflowEvent)
649
+ .on('sort', reflowEvent)
650
+ .on('page', reflowEvent);
651
+ }
652
+
653
+ //attach some useful functions to the table.
654
+ $table.data('floatThead-attached', {
655
+ destroy: function(){
656
+ var ns = '.fth-'+floatTheadId;
657
+ unfloat();
658
+ $table.css(layoutAuto);
659
+ $tableColGroup.remove();
660
+ isChrome && $fthGrp.remove();
661
+ if($newHeader.parent().length){ //only if its in the dom
662
+ $newHeader.replaceWith($header);
663
+ }
664
+ $table.off('reflow');
665
+ $scrollContainer.off(ns);
666
+ if (wrappedContainer) {
667
+ $scrollContainer.unwrap();
668
+ }
669
+ $floatContainer.remove();
670
+ $table.data('floatThead-attached', false);
671
+
672
+ $window.off(ns);
673
+ },
674
+ reflow: function(){
675
+ reflowEvent();
676
+ },
677
+ setHeaderHeight: function(){
678
+ setHeaderHeight();
679
+ },
680
+ getFloatContainer: function(){
681
+ return $floatContainer;
682
+ },
683
+ getRowGroups: function(){
684
+ if(headerFloated){
685
+ return $floatContainer.find("thead").add($table.find("tbody,tfoot"));
686
+ } else {
687
+ return $table.find("thead,tbody,tfoot");
688
+ }
689
+ }
690
+ });
691
+ floatTheadCreated++;
692
+ });
693
+ return this;
694
+ };
695
+ })(jQuery);
696
+ /* jQuery.floatThead.utils - http://mkoryak.github.io/floatThead/ - Copyright (c) 2012 - 2014 Misha Koryak
697
+ * License: MIT
698
+ *
699
+ * This file is required if you do not use underscore in your project and you want to use floatThead.
700
+ * It contains functions from underscore that the plugin uses.
701
+ *
702
+ * YOU DON'T NEED TO INCLUDE THIS IF YOU ALREADY INCLUDE UNDERSCORE!
703
+ *
704
+ */
705
+
706
+ (function(){
707
+
708
+ $.floatThead = $.floatThead || {};
709
+
710
+ $.floatThead._ = window._ || (function(){
711
+ var that = {};
712
+ var hasOwnProperty = Object.prototype.hasOwnProperty, isThings = ['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'];
713
+ that.has = function(obj, key) {
714
+ return hasOwnProperty.call(obj, key);
715
+ };
716
+ that.keys = function(obj) {
717
+ if (obj !== Object(obj)) throw new TypeError('Invalid object');
718
+ var keys = [];
719
+ for (var key in obj) if (that.has(obj, key)) keys.push(key);
720
+ return keys;
721
+ };
722
+ $.each(isThings, function(){
723
+ var name = this;
724
+ that['is' + name] = function(obj) {
725
+ return Object.prototype.toString.call(obj) == '[object ' + name + ']';
726
+ };
727
+ });
728
+ that.debounce = function(func, wait, immediate) {
729
+ var timeout, args, context, timestamp, result;
730
+ return function() {
731
+ context = this;
732
+ args = arguments;
733
+ timestamp = new Date();
734
+ var later = function() {
735
+ var last = (new Date()) - timestamp;
736
+ if (last < wait) {
737
+ timeout = setTimeout(later, wait - last);
738
+ } else {
739
+ timeout = null;
740
+ if (!immediate) result = func.apply(context, args);
741
+ }
742
+ };
743
+ var callNow = immediate && !timeout;
744
+ if (!timeout) {
745
+ timeout = setTimeout(later, wait);
746
+ }
747
+ if (callNow) result = func.apply(context, args);
748
+ return result;
749
+ };
750
+ };
751
+ return that;
752
+ })();
753
+ })();
754
+
@@ -39,17 +39,25 @@ html {
39
39
  margin: 0 auto;
40
40
  }
41
41
 
42
- .analysis-index-table {
42
+ .index-table {
43
43
  width: 100%;
44
44
  border-collapse: collapse;
45
+ table-layout: fixed;
45
46
  }
46
47
 
47
- .analysis-index-table th {
48
+ .index-table th {
48
49
  text-align: left;
49
50
  padding: 8px 10px;
50
51
  border-bottom: 1px solid silver;
51
52
  font-size: 1.55em;
52
53
  font-weight: normal;
54
+ background-color: white;
55
+ }
56
+
57
+ .sortable-table .headerSortUp,
58
+ .sortable-table .headerSortDown {
59
+ border: 1px solid silver;
60
+ border-bottom: 0;
53
61
  }
54
62
 
55
63
  .sortable-table th:hover {
@@ -57,14 +65,22 @@ html {
57
65
  cursor: pointer;
58
66
  }
59
67
 
60
- .analysis-index-table td {
68
+ .index-table td {
61
69
  padding: 12px 10px;
62
70
  }
63
71
 
64
- .analysis-index-table .first-cell {
72
+ .index-table .first-cell {
65
73
  padding-left: 60px;
66
74
  }
67
75
 
76
+ .index-table .last-cell {
77
+ padding-right: 60px;
78
+ }
79
+
80
+ .index-table .numeric-cell {
81
+ text-align: right;
82
+ }
83
+
68
84
  .button {
69
85
  margin: 0;
70
86
  padding: 0.5em 1em;
@@ -19,10 +19,6 @@ module Rubycritic
19
19
  index_body = TEMPLATE.result(get_binding)
20
20
  LAYOUT_TEMPLATE.result(get_binding { index_body })
21
21
  end
22
-
23
- def file_path(pathname)
24
- File.join(root_directory, pathname.sub_ext(".html"))
25
- end
26
22
  end
27
23
 
28
24
  end
@@ -1,8 +1,10 @@
1
- <table id="js-code-table" class="analysis-index-table sortable-table">
1
+ <table id="js-index-table" class="index-table sortable-table">
2
2
  <thead>
3
3
  <tr>
4
4
  <th class="first-cell">Name</th>
5
- <th>Smells</th>
5
+ <th class="numeric-cell" title="Number of times a file has changed">Churn</th>
6
+ <th class="numeric-cell" title="Overall amount of code in a file">Complexity</th>
7
+ <th class="numeric-cell last-cell">Smells</th>
6
8
  </tr>
7
9
  </thead>
8
10
  <tbody>
@@ -11,7 +13,9 @@
11
13
  <td class="first-cell">
12
14
  <a href="<%= file_path(analysed_file.pathname) %>"><%= analysed_file.name %></a>
13
15
  </td>
14
- <td><%= analysed_file.smells.length %></td>
16
+ <td class="numeric-cell"><%= analysed_file.churn %></td>
17
+ <td class="numeric-cell"><%= analysed_file.complexity %></td>
18
+ <td class="numeric-cell last-cell"><%= analysed_file.smells.length %></td>
15
19
  </tr>
16
20
  <% end %>
17
21
  </tbody>
@@ -10,16 +10,17 @@
10
10
  </head>
11
11
  <body>
12
12
  <header class="project-header group">
13
- <h1 class="logo"><a href="<%= overview_path %>" class="logo-link">RubyCritic</a></h1>
13
+ <h1 class="logo"><a href="<%= file_path('overview') %>" class="logo-link">RubyCritic</a></h1>
14
14
  <nav class="project-nav">
15
- <a href="<%= overview_path %>" class="project-nav-item">Overview</a>
16
- <a href="<%= code_index_path %>" class="project-nav-item">Code</a>
17
- <a href="<%= smells_index_path %>" class="project-nav-item">Smells</a>
15
+ <a href="<%= file_path('overview') %>" class="project-nav-item">Overview</a>
16
+ <a href="<%= file_path('code_index') %>" class="project-nav-item">Code</a>
17
+ <a href="<%= file_path('smells_index') %>" class="project-nav-item">Smells</a>
18
18
  </nav>
19
19
  </header>
20
20
  <%= yield %>
21
21
  <script src="<%= javascript_path(:'jquery-2.1.0') %>"></script>
22
22
  <script src="<%= javascript_path(:'jquery.tablesorter-2.0') %>"></script>
23
+ <script src="<%= javascript_path(:'jquery.floatThead-v1.2.7') %>"></script>
23
24
  <script src="<%= javascript_path(:'highcharts.src-4.0.1') %>"></script>
24
25
  <script src="<%= javascript_path(:'jquery.scrollTo-1.4.11') %>"></script>
25
26
  <script src="<%= javascript_path(:'prettify-4-Mar-2013') %>"></script>
@@ -1,15 +1,15 @@
1
- <table id="js-code-table" class="analysis-index-table sortable-table">
1
+ <table id="js-index-table" class="index-table sortable-table">
2
2
  <thead>
3
3
  <tr>
4
4
  <th class="first-cell">Smell</th>
5
- <th>Locations</th>
5
+ <th class="last-cell">Locations</th>
6
6
  </tr>
7
7
  </thead>
8
8
  <tbody>
9
9
  <% @smells.each do |smell| %>
10
10
  <tr>
11
11
  <td class="first-cell"><%= smell.type %></td>
12
- <td>
12
+ <td class="last-cell">
13
13
  <% smell.locations.each do |location| %>
14
14
  <a href="<%= smell_location_path(location) %>"><%= location.file_name %></a>
15
15
  <% end %>
@@ -1,3 +1,5 @@
1
+ require "pathname"
2
+
1
3
  module Rubycritic
2
4
 
3
5
  module ViewHelpers
@@ -13,21 +15,12 @@ module Rubycritic
13
15
  File.join(root_directory, "assets", file)
14
16
  end
15
17
 
16
- def smell_location_path(location)
17
- pathname = location.pathname
18
- File.join(root_directory, "#{pathname.sub_ext('.html')}#L#{location.line}")
19
- end
20
-
21
- def overview_path
22
- File.join(root_directory, "overview.html")
18
+ def file_path(file)
19
+ File.join(root_directory, Pathname(file).sub_ext(".html"))
23
20
  end
24
21
 
25
- def code_index_path
26
- File.join(root_directory, "code_index.html")
27
- end
28
-
29
- def smells_index_path
30
- File.join(root_directory, "smells_index.html")
22
+ def smell_location_path(location)
23
+ File.join(root_directory, "#{location.pathname.sub_ext('.html')}#L#{location.line}")
31
24
  end
32
25
 
33
26
  def root_directory
@@ -0,0 +1,24 @@
1
+ require "fileutils"
2
+
3
+ module Rubycritic
4
+ module Reporter
5
+
6
+ class Base
7
+ ASSETS_DIR = File.expand_path("../../report_generators/assets", __FILE__)
8
+
9
+ def create_directories_and_files(generators)
10
+ Array(generators).each do |generator|
11
+ FileUtils.mkdir_p(generator.file_directory)
12
+ File.open(generator.file_pathname, "w+") do |file|
13
+ file.write(generator.render)
14
+ end
15
+ end
16
+ end
17
+
18
+ def copy_assets_to_report_directory
19
+ FileUtils.cp_r(ASSETS_DIR, ::Rubycritic.configuration.root)
20
+ end
21
+ end
22
+
23
+ end
24
+ end
@@ -1,28 +1,21 @@
1
+ require "rubycritic/reporters/base"
1
2
  require "rubycritic/report_generators/overview"
2
3
  require "rubycritic/report_generators/smells_index"
3
4
  require "rubycritic/report_generators/code_index"
4
5
  require "rubycritic/report_generators/code_file"
5
- require "fileutils"
6
6
 
7
7
  module Rubycritic
8
8
  module Reporter
9
9
 
10
- class Main
11
- ASSETS_DIR = File.expand_path("../../report_generators/assets", __FILE__)
12
-
10
+ class Main < Base
13
11
  def initialize(analysed_files, smells)
14
12
  @analysed_files = analysed_files
15
13
  @smells = smells
16
14
  end
17
15
 
18
16
  def generate_report
19
- generators.each do |generator|
20
- FileUtils.mkdir_p(generator.file_directory)
21
- File.open(generator.file_pathname, "w+") do |file|
22
- file.write(generator.render)
23
- end
24
- end
25
- FileUtils.cp_r(ASSETS_DIR, ::Rubycritic.configuration.root)
17
+ create_directories_and_files(generators)
18
+ copy_assets_to_report_directory
26
19
  overview_generator.file_href
27
20
  end
28
21
 
@@ -1,23 +1,18 @@
1
+ require "rubycritic/reporters/base"
1
2
  require "rubycritic/report_generators/code_file"
2
- require "fileutils"
3
3
 
4
4
  module Rubycritic
5
5
  module Reporter
6
6
 
7
- class Mini
8
- ASSETS_DIR = File.expand_path("../../report_generators/assets", __FILE__)
9
-
7
+ class Mini < Base
10
8
  def initialize(analysed_file)
11
9
  @analysed_file = analysed_file
12
10
  end
13
11
 
14
12
  def generate_report
15
13
  file_generator = Generator::CodeFile.new(@analysed_file)
16
- FileUtils.mkdir_p(file_generator.file_directory)
17
- File.open(file_generator.file_pathname, "w+") do |file|
18
- file.write(file_generator.render)
19
- end
20
- FileUtils.cp_r(ASSETS_DIR, ::Rubycritic.configuration.root)
14
+ create_directories_and_files(file_generator)
15
+ copy_assets_to_report_directory
21
16
  file_generator.file_href
22
17
  end
23
18
  end
@@ -1,3 +1,3 @@
1
1
  module Rubycritic
2
- VERSION = "0.0.13"
2
+ VERSION = "0.0.14"
3
3
  end
@@ -20,4 +20,16 @@ class Perfume
20
20
  do_something
21
21
  do_something
22
22
  end
23
+
24
+ def allow_up_to_two_duplicate_method_calls
25
+ respond_to do |format|
26
+ if success
27
+ format.html { redirect_to some_path }
28
+ format.js { head :ok }
29
+ else
30
+ format.html { redirect_to :back, status: :bad_request }
31
+ format.js { render status: :bad_request }
32
+ end
33
+ end
34
+ end
23
35
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubycritic
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.13
4
+ version: 0.0.14
5
5
  platform: ruby
6
6
  authors:
7
7
  - Guilherme Simoes
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-05-15 00:00:00.000000000 Z
11
+ date: 2014-05-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: virtus
@@ -163,6 +163,7 @@ files:
163
163
  - lib/rubycritic/report_generators/assets/javascripts/application.js
164
164
  - lib/rubycritic/report_generators/assets/javascripts/highcharts.src-4.0.1.js
165
165
  - lib/rubycritic/report_generators/assets/javascripts/jquery-2.1.0.js
166
+ - lib/rubycritic/report_generators/assets/javascripts/jquery.floatThead-v1.2.7.js
166
167
  - lib/rubycritic/report_generators/assets/javascripts/jquery.scrollTo-1.4.11.js
167
168
  - lib/rubycritic/report_generators/assets/javascripts/jquery.tablesorter-2.0.js
168
169
  - lib/rubycritic/report_generators/assets/javascripts/prettify-4-Mar-2013.js
@@ -182,6 +183,7 @@ files:
182
183
  - lib/rubycritic/report_generators/templates/smells_index.html.erb
183
184
  - lib/rubycritic/report_generators/templates/smelly_line.html.erb
184
185
  - lib/rubycritic/report_generators/view_helpers.rb
186
+ - lib/rubycritic/reporters/base.rb
185
187
  - lib/rubycritic/reporters/main.rb
186
188
  - lib/rubycritic/reporters/mini.rb
187
189
  - lib/rubycritic/revision_comparator.rb