rubycritic 3.0.0 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/CHANGELOG.md +9 -0
  4. data/README.md +9 -6
  5. data/ROADMAP.md +56 -0
  6. data/docs/building-own-code-climate.md +4 -0
  7. data/features/command_line_interface/minimum_score.feature +1 -1
  8. data/features/command_line_interface/options.feature +1 -1
  9. data/lib/rubycritic/analysis_summary.rb +40 -0
  10. data/lib/rubycritic/cli/options.rb +1 -1
  11. data/lib/rubycritic/core/analysed_module.rb +20 -0
  12. data/lib/rubycritic/core/analysed_modules_collection.rb +8 -0
  13. data/lib/rubycritic/generators/html/assets/fonts/FontAwesome.otf +0 -0
  14. data/lib/rubycritic/generators/html/assets/fonts/Roboto-Medium.ttf +0 -0
  15. data/lib/rubycritic/generators/html/assets/fonts/Roboto-Regular.ttf +0 -0
  16. data/lib/rubycritic/generators/html/assets/fonts/fontawesome-webfont.eot +0 -0
  17. data/lib/rubycritic/generators/html/assets/fonts/fontawesome-webfont.svg +2671 -0
  18. data/lib/rubycritic/generators/html/assets/fonts/fontawesome-webfont.ttf +0 -0
  19. data/lib/rubycritic/generators/html/assets/fonts/fontawesome-webfont.woff +0 -0
  20. data/lib/rubycritic/generators/html/assets/fonts/fontawesome-webfont.woff2 +0 -0
  21. data/lib/rubycritic/generators/html/assets/fonts/glyphicons-halflings-regular.eot +0 -0
  22. data/lib/rubycritic/generators/html/assets/fonts/glyphicons-halflings-regular.svg +288 -0
  23. data/lib/rubycritic/generators/html/assets/fonts/glyphicons-halflings-regular.ttf +0 -0
  24. data/lib/rubycritic/generators/html/assets/fonts/glyphicons-halflings-regular.woff +0 -0
  25. data/lib/rubycritic/generators/html/assets/fonts/glyphicons-halflings-regular.woff2 +0 -0
  26. data/lib/rubycritic/generators/html/assets/images/logo.png +0 -0
  27. data/lib/rubycritic/generators/html/assets/javascripts/application.js +221 -72
  28. data/lib/rubycritic/generators/html/assets/javascripts/bootstrap.min.js +7 -0
  29. data/lib/rubycritic/generators/html/assets/javascripts/jquery.min.js +4 -0
  30. data/lib/rubycritic/generators/html/assets/javascripts/jquery.scrollTo.min.js +7 -0
  31. data/lib/rubycritic/generators/html/assets/javascripts/jquery.tablesorter.js +1031 -2089
  32. data/lib/rubycritic/generators/html/assets/javascripts/jquery.tablesorter.min.js +4 -0
  33. data/lib/rubycritic/generators/html/assets/javascripts/{jquery.timeago-v1.4.1.js → jquery.timeago.js} +31 -14
  34. data/lib/rubycritic/generators/html/assets/javascripts/prettify.js +46 -0
  35. data/lib/rubycritic/generators/html/assets/stylesheets/application.css +422 -197
  36. data/lib/rubycritic/generators/html/assets/stylesheets/bootstrap.min.css +6 -0
  37. data/lib/rubycritic/generators/html/assets/stylesheets/font-awesome.min.css +4 -0
  38. data/lib/rubycritic/generators/html/assets/stylesheets/prettify.css +1 -0
  39. data/lib/rubycritic/generators/html/overview.rb +2 -0
  40. data/lib/rubycritic/generators/html/templates/code_file.html.erb +56 -33
  41. data/lib/rubycritic/generators/html/templates/code_index.html.erb +45 -30
  42. data/lib/rubycritic/generators/html/templates/layouts/application.html.erb +43 -21
  43. data/lib/rubycritic/generators/html/templates/overview.html.erb +62 -7
  44. data/lib/rubycritic/generators/html/templates/smells_index.html.erb +47 -26
  45. data/lib/rubycritic/generators/html/templates/smelly_line.html.erb +16 -12
  46. data/lib/rubycritic/generators/html/turbulence.rb +2 -2
  47. data/lib/rubycritic/generators/html/view_helpers.rb +4 -0
  48. data/lib/rubycritic/source_control_systems/base.rb +1 -0
  49. data/lib/rubycritic/source_control_systems/perforce.rb +108 -0
  50. data/lib/rubycritic/version.rb +1 -1
  51. data/rubycritic.gemspec +1 -1
  52. data/test/analysers_test_helper.rb +7 -0
  53. data/test/lib/rubycritic/analysis_summary_test.rb +29 -0
  54. data/test/lib/rubycritic/generators/console_report_test.rb +3 -3
  55. data/test/lib/rubycritic/source_control_systems/perforce_test.rb +162 -0
  56. metadata +34 -9
  57. data/lib/rubycritic/generators/html/assets/javascripts/jquery-2.1.0.js +0 -9111
  58. data/lib/rubycritic/generators/html/assets/javascripts/jquery.floatThead-v1.2.7.js +0 -754
  59. data/lib/rubycritic/generators/html/assets/javascripts/jquery.scrollTo-1.4.11.js +0 -186
  60. data/lib/rubycritic/generators/html/assets/javascripts/prettify-4-Mar-2013.js +0 -1662
@@ -1,754 +0,0 @@
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
-