angular-sticky-table-header
Advanced tools
Comparing version
{ | ||
"name": "angular-sticky-table-header", | ||
"version": "0.2.9", | ||
"version": "0.2.12", | ||
"description": "Sticky headers for tables", | ||
"main": "dist/angular-sticky-table-header.js", | ||
"homepage": "https://github.com/turn/angular-sticky-table-header", | ||
"authors": [ | ||
"Boris Cherny <bcherny@turn.com>" | ||
"Boris Cherny <bcherny@turn.com>", | ||
"Nina Chen <nchen@turn.com>" | ||
], | ||
@@ -9,0 +11,0 @@ "license": "Apache2", |
@@ -86,3 +86,3 @@ angular.module('watchDom', []).constant('watchDomOptions', { | ||
scope.offset = { | ||
width: element[0].getBoundingClientRect().width, | ||
width: element.find('table').get(0).getBoundingClientRect().width, | ||
left: offset.left, | ||
@@ -104,5 +104,6 @@ top: offset.top | ||
scope.setCloneGutter(); | ||
scope.checkScroll(); | ||
}), | ||
checkScroll: ifClone(function () { | ||
var scrollY = $window.scrollY; | ||
var scrollY = ($window.scrollY || 0) + element.scrollTop(), scrollX = ($window.scrollX || 0) + element.scrollLeft(); | ||
if (!scope.stuck && scrollY >= scope.offset.top) { | ||
@@ -113,5 +114,6 @@ scope.setClonedCellWidths(); | ||
scope.setStuck(false); | ||
} else if ($window.scrollX) { | ||
scope.clone.css('left', scope.offset.left - $window.scrollX); | ||
} | ||
if (scrollX) { | ||
scope.clone.css('left', scope.offset.left - scrollX); | ||
} | ||
}), | ||
@@ -122,6 +124,3 @@ observeTr: function () { | ||
rowsChanged: function () { | ||
$timeout(function () { | ||
scope.sizeClone(); | ||
scope.checkScroll(); | ||
}); | ||
$timeout(scope.sizeClone); | ||
}, | ||
@@ -138,2 +137,3 @@ on: function () { | ||
addEvents: function () { | ||
scope.elementEvents = { scroll: scope.checkScroll }; | ||
scope.windowEvents = { | ||
@@ -144,8 +144,11 @@ scroll: scope.checkScroll, | ||
angular.element($window).on(scope.windowEvents); | ||
element.on(scope.elementEvents); | ||
}, | ||
removeEvents: function () { | ||
if (!scope.windowEvents.resize || !scope.windowEvents.scroll) { | ||
if (!scope.windowEvents.resize || !scope.windowEvents.scroll || !scope.elementEvents.scroll) { | ||
return; | ||
} | ||
angular.element($window).off(scope.windowEvents); | ||
element.off(scope.elementEvents); | ||
scope.elementEvents = {}; | ||
scope.windowEvents = {}; | ||
@@ -152,0 +155,0 @@ }, |
{ | ||
"name": "angular-sticky-table-header", | ||
"version": "0.2.9", | ||
"version": "0.2.12", | ||
"description": "Sticky headers for tables", | ||
"main": "dist/angular-sticky-table-header.js", | ||
"homepage": "https://github.com/turn/angular-sticky-table-header", | ||
"authors": [ | ||
"Boris Cherny <bcherny@turn.com>", | ||
"Nina Chen <nchen@turn.com>" | ||
], | ||
"repository": "git://github.com/turn/angular-sticky-table-header.git", | ||
@@ -10,3 +15,2 @@ "scripts": { | ||
}, | ||
"author": "Boris Cherny <bcherny@turn.com>", | ||
"license": "Apache2", | ||
@@ -13,0 +17,0 @@ "devDependencies": { |
@@ -89,3 +89,2 @@ angular-sticky-table-header [](https://travis-ci.org/turn/angular-sticky-table-header) [](https://coveralls.io/r/turn/angular-sticky-table-header) | ||
- more unit tests | ||
- end to end tests |
@@ -109,7 +109,6 @@ angular | ||
scope.offset = { | ||
width: element[0].getBoundingClientRect().width, | ||
width: element.find('table').get(0).getBoundingClientRect().width, | ||
left: offset.left, | ||
top: offset.top | ||
}; | ||
}, | ||
@@ -136,2 +135,3 @@ | ||
scope.setCloneGutter(); | ||
scope.checkScroll(); | ||
@@ -142,3 +142,4 @@ }), | ||
var scrollY = $window.scrollY; | ||
var scrollY = ($window.scrollY || 0) + element.scrollTop(), | ||
scrollX = ($window.scrollX || 0) + element.scrollLeft(); | ||
@@ -150,6 +151,6 @@ if (!scope.stuck && scrollY >= scope.offset.top) { | ||
scope.setStuck(false); | ||
} else if ($window.scrollX) { | ||
} | ||
scope.clone.css('left', scope.offset.left - $window.scrollX); | ||
if (scrollX) { | ||
scope.clone.css('left', scope.offset.left - scrollX); | ||
} | ||
@@ -171,6 +172,3 @@ | ||
$timeout(function(){ | ||
scope.sizeClone(); | ||
scope.checkScroll(); | ||
}); | ||
$timeout(scope.sizeClone); | ||
@@ -196,2 +194,6 @@ }, | ||
scope.elementEvents = { | ||
scroll: scope.checkScroll | ||
}; | ||
scope.windowEvents = { | ||
@@ -206,2 +208,5 @@ scroll: scope.checkScroll, | ||
element | ||
.on(scope.elementEvents); | ||
}, | ||
@@ -211,3 +216,3 @@ | ||
if (!scope.windowEvents.resize || !scope.windowEvents.scroll) { | ||
if (!scope.windowEvents.resize || !scope.windowEvents.scroll || !scope.elementEvents.scroll) { | ||
return; | ||
@@ -220,2 +225,6 @@ } | ||
element | ||
.off(scope.elementEvents); | ||
scope.elementEvents = {}; | ||
scope.windowEvents = {}; | ||
@@ -222,0 +231,0 @@ |
224
test/test.js
@@ -1,2 +0,2 @@ | ||
// Generated by CoffeeScript 1.7.1 | ||
// Generated by CoffeeScript 1.8.0 | ||
describe('angular-sticky-table-header', function() { | ||
@@ -18,2 +18,3 @@ var $window, options; | ||
$window = { | ||
scrollX: 0, | ||
scrollY: 0, | ||
@@ -133,4 +134,7 @@ on: function() {}, | ||
describe('#setOffset', function() { | ||
var table; | ||
table = null; | ||
beforeEach(function() { | ||
spyOn(this.element[0], 'getBoundingClientRect').andReturn({ | ||
table = (this.element.find('table')).get(0); | ||
spyOn(table, 'getBoundingClientRect').andReturn({ | ||
width: 'bar', | ||
@@ -147,3 +151,3 @@ top: 'zoo' | ||
it('should call getBoundingClientRect on the first <tr>', function() { | ||
return expect(this.element[0].getBoundingClientRect).toHaveBeenCalledWith(); | ||
return expect(table.getBoundingClientRect).toHaveBeenCalledWith(); | ||
}); | ||
@@ -208,3 +212,3 @@ it('should call $.offset on the first <tr>', function() { | ||
describe('#sizeClone', function() { | ||
return it('should call #setOffset, #setClonedCellWidths, and #setClonedCellWidths', function() { | ||
return it('should call #setOffset, #setClonedCellWidths, #setClonedCellWidths, and #checkScroll with no arguments', function() { | ||
this.scope.clone = true; | ||
@@ -214,9 +218,12 @@ this.scope.setClonedCellWidths = function() {}; | ||
this.scope.setOffset = function() {}; | ||
this.scope.checkScroll = function() {}; | ||
spyOn(this.scope, 'setClonedCellWidths'); | ||
spyOn(this.scope, 'setCloneGutter'); | ||
spyOn(this.scope, 'setOffset'); | ||
spyOn(this.scope, 'checkScroll'); | ||
this.scope.sizeClone(); | ||
expect(this.scope.setOffset).toHaveBeenCalled(); | ||
expect(this.scope.setClonedCellWidths).toHaveBeenCalled(); | ||
return expect(this.scope.setCloneGutter).toHaveBeenCalled(); | ||
expect(this.scope.setOffset).toHaveBeenCalledWith; | ||
expect(this.scope.setClonedCellWidths).toHaveBeenCalledWith; | ||
expect(this.scope.setCloneGutter).toHaveBeenCalledWith; | ||
return expect(this.scope.checkScroll).toHaveBeenCalledWith; | ||
}); | ||
@@ -229,22 +236,59 @@ }); | ||
}); | ||
it('should call #setStuck with true and #setClonedCellWidths with no arguments when scope.stuck is false and scrollY is >= offset.top', function() { | ||
this.scope.clone = true; | ||
this.scope.stuck = false; | ||
this.scope.offset = { | ||
top: 0 | ||
}; | ||
$window.scrollY = 1; | ||
this.scope.checkScroll(); | ||
expect(this.scope.setStuck).toHaveBeenCalledWith(true); | ||
return expect(this.scope.setClonedCellWidths).toHaveBeenCalled(); | ||
[ | ||
{ | ||
elementScrollY: 0, | ||
windowScrollY: 0 | ||
}, { | ||
elementScrollY: 0, | ||
windowScrollY: 1 | ||
}, { | ||
elementScrollY: 1, | ||
windowScrollY: 0 | ||
}, { | ||
elementScrollY: 1, | ||
windowScrollY: 1 | ||
}, { | ||
elementScrollY: 2, | ||
windowScrollY: -1 | ||
}, { | ||
elementScrollY: -1, | ||
windowScrollY: 2 | ||
} | ||
].forEach(function(data) { | ||
return it('should call #setStuck with true and #setClonedCellWidths with no arguments when scope.stuck is false and scrollY is >= offset.top', function() { | ||
spyOn(this.element, 'scrollTop').andReturn(data.elementScrollY); | ||
this.scope.clone = true; | ||
this.scope.stuck = false; | ||
this.scope.offset = { | ||
top: 0 | ||
}; | ||
$window.scrollY = data.windowScrollY; | ||
this.scope.checkScroll(); | ||
expect(this.scope.setStuck).toHaveBeenCalledWith(true); | ||
return expect(this.scope.setClonedCellWidths).toHaveBeenCalled(); | ||
}); | ||
}); | ||
it('should call #setStuck with false when scope.stuck is true and scrollY is < offset.top', function() { | ||
this.scope.clone = true; | ||
this.scope.stuck = true; | ||
this.scope.offset = { | ||
top: 1 | ||
}; | ||
$window.scrollY = 0; | ||
this.scope.checkScroll(); | ||
return expect(this.scope.setStuck).toHaveBeenCalledWith(false); | ||
[ | ||
{ | ||
elementScrollY: 0, | ||
windowScrollY: 0 | ||
}, { | ||
elementScrollY: 0, | ||
windowScrollY: -1 | ||
}, { | ||
elementScrollY: -1, | ||
windowScrollY: 0 | ||
} | ||
].forEach(function(data) { | ||
return it('should call #setStuck with false when scope.stuck is true and scrollY is < offset.top', function() { | ||
spyOn(this.element, 'scrollTop').andReturn(data.elementScrollY); | ||
this.scope.clone = true; | ||
this.scope.stuck = true; | ||
this.scope.offset = { | ||
top: 1 | ||
}; | ||
$window.scrollY = data.windowScrollY; | ||
this.scope.checkScroll(); | ||
return expect(this.scope.setStuck).toHaveBeenCalledWith(false); | ||
}); | ||
}); | ||
@@ -269,9 +313,7 @@ return it('should not call #setStuck otherwise', function() { | ||
describe('#rowsChanged', function() { | ||
return it('should call #checkScroll and #sizeClone after a $timeout', inject(function($timeout) { | ||
spyOn(this.scope, 'checkScroll'); | ||
return it('should call #sizeClone with no arguments after a $timeout', inject(function($timeout) { | ||
spyOn(this.scope, 'sizeClone'); | ||
this.scope.rowsChanged(); | ||
$timeout.flush(); | ||
expect(this.scope.checkScroll).toHaveBeenCalled(); | ||
return expect(this.scope.sizeClone).toHaveBeenCalled(); | ||
return expect(this.scope.sizeClone).toHaveBeenCalledWith; | ||
})); | ||
@@ -301,9 +343,14 @@ }); | ||
describe('#addEvents', function() { | ||
it('should store decorated resize and scroll events on scope.windowEvents', function() { | ||
it('should store resize and scroll events on scope.windowEvents', function() { | ||
this.scope.windowEvents = null; | ||
this.scope.addEvents(); | ||
expect(angular.isFunction(this.scope.windowEvents.resize)).toBe(true); | ||
return expect(angular.isFunction(this.scope.windowEvents.scroll)).toBe(true); | ||
expect(this.scope.windowEvents.resize).toBe(this.scope.sizeClone); | ||
return expect(this.scope.windowEvents.scroll).toBe(this.scope.checkScroll); | ||
}); | ||
return it('should bind those events to the $window', inject(function($window) { | ||
it('should store the scroll event on scope.elementEvents', function() { | ||
this.scope.elementEvents = null; | ||
this.scope.addEvents(); | ||
return expect(this.scope.elementEvents.scroll).toBe(this.scope.checkScroll); | ||
}); | ||
it('should bind windowEvents to the $window', inject(function($window) { | ||
spyOn(($()).__proto__, 'on'); | ||
@@ -315,31 +362,89 @@ spyOn(angular, 'element').andCallThrough(); | ||
})); | ||
return it('should bind elementEvents to the element', function() { | ||
spyOn(($()).__proto__, 'on'); | ||
this.scope.addEvents(); | ||
return expect(($()).__proto__.on).toHaveBeenCalledWith(this.scope.elementEvents); | ||
}); | ||
}); | ||
describe('#removeEvents', function() { | ||
it('should not reset scope.windowEvents or unbind events from the $window if windowEvents.resize or windowEvents.scroll are falsey', function() { | ||
it('should not reset scope.windowEvents or unbind events from the $window if windowEvents.resize, windowEvents.scroll, or elementEvents.scroll are falsey', function() { | ||
spyOn(($()).__proto__, 'on'); | ||
return [ | ||
{ | ||
elementEvents: { | ||
scroll: null | ||
}, | ||
windowEvents: { | ||
resize: null, | ||
scroll: null | ||
} | ||
}, { | ||
elementEvents: { | ||
scroll: true | ||
}, | ||
windowEvents: { | ||
resize: null, | ||
scroll: null | ||
} | ||
}, { | ||
elementEvents: { | ||
scroll: null | ||
}, | ||
windowEvents: { | ||
resize: true, | ||
scroll: null | ||
} | ||
}, { | ||
elementEvents: { | ||
scroll: null | ||
}, | ||
windowEvents: { | ||
resize: null, | ||
scroll: true | ||
} | ||
}, { | ||
elementEvents: { | ||
scroll: true | ||
}, | ||
windowEvents: { | ||
resize: true, | ||
scroll: null | ||
} | ||
}, { | ||
elementEvents: { | ||
scroll: true | ||
}, | ||
windowEvents: { | ||
resize: null, | ||
scroll: true | ||
} | ||
}, { | ||
elementEvents: { | ||
scroll: null | ||
}, | ||
windowEvents: { | ||
resize: true, | ||
scroll: true | ||
} | ||
} | ||
].forEach((function(_this) { | ||
return function(vars) { | ||
_this.scope.elementEvents = vars.elementEvents; | ||
_this.scope.windowEvents = vars.windowEvents; | ||
_this.scope.removeEvents(); | ||
expect(($()).__proto__.on).not.toHaveBeenCalled(); | ||
expect(_this.scope.elementEvents).toEqual(vars.elementEvents); | ||
return expect(_this.scope.windowEvents).toEqual(vars.windowEvents); | ||
}; | ||
})(this)); | ||
}); | ||
it('should unbind events from the element', function() { | ||
var events; | ||
spyOn(($()).__proto__, 'on'); | ||
events = { | ||
resize: null, | ||
scroll: null | ||
}; | ||
this.scope.windowEvents = angular.copy(events); | ||
this.scope.removeEvents(); | ||
expect(($()).__proto__.on).not.toHaveBeenCalled(); | ||
expect(this.scope.windowEvents).toEqual(events); | ||
this.scope.windowEvents = { | ||
resize: true, | ||
scroll: null | ||
}; | ||
this.scope.windowEvents = angular.copy(events); | ||
this.scope.removeEvents(); | ||
expect(($()).__proto__.on).not.toHaveBeenCalled(); | ||
expect(this.scope.windowEvents).toEqual(events); | ||
this.scope.windowEvents = { | ||
resize: null, | ||
scroll: true | ||
}; | ||
this.scope.windowEvents = angular.copy(events); | ||
this.scope.elementEvents = angular.copy(events); | ||
spyOn(($()).__proto__, 'off'); | ||
this.scope.removeEvents(); | ||
expect(($()).__proto__.on).not.toHaveBeenCalled(); | ||
return expect(this.scope.windowEvents).toEqual(events); | ||
return expect(($()).__proto__.off).toHaveBeenCalledWith(events); | ||
}); | ||
@@ -359,2 +464,9 @@ it('should unbind events from the $window', inject(function($window) { | ||
})); | ||
it('should set scope.elementEvents to an empty object', function() { | ||
this.scope.elementEvents = { | ||
scroll: true | ||
}; | ||
this.scope.removeEvents(); | ||
return expect(this.scope.elementEvents).toEqual({}); | ||
}); | ||
return it('should set scope.windowEvents to an empty object', function() { | ||
@@ -361,0 +473,0 @@ this.scope.windowEvents = { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
No contributors or author data
MaintenancePackage does not specify a list of contributors or an author in package.json.
Found 1 instance in 1 package
No website
QualityPackage does not have a website.
Found 1 instance in 1 package
66127
11.3%938
15.38%1
-50%3
50%89
-1.11%