diff --git a/app/assets/javascripts/stick-to-window-when-scrolling.js b/app/assets/javascripts/stick-to-window-when-scrolling.js index 0a3176beb..c75779109 100644 --- a/app/assets/javascripts/stick-to-window-when-scrolling.js +++ b/app/assets/javascripts/stick-to-window-when-scrolling.js @@ -710,21 +710,36 @@ this.recalculate(); }; Sticky.prototype.setEvents = function () { - var self = this; + this._scrollEvent = this.onScroll.bind(this); + this._resizeEvent = this.onResize.bind(this); // flag when scrolling takes place and check (and re-position) sticky elements relative to // window position - if (self._scrollTimeout === false) { - $(global).scroll(function (e) { self.onScroll(); }); - self._scrollTimeout = global.setInterval(function (e) { self.checkScroll(); }, 50); + if (this._scrollTimeout === false) { + $(global).scroll(this._scrollEvent); + this._scrollTimeout = global.setInterval(this.checkScroll.bind(this), 50); } // Recalculate all dimensions when the window resizes - if (self._resizeTimeout === false) { - $(global).resize(function (e) { self.onResize(); }); - self._resizeTimeout = global.setInterval(function (e) { self.checkResize(); }, 50); + if (this._resizeTimeout === false) { + $(global).resize(this._resizeEvent); + this._resizeTimeout = global.setInterval(this.checkResize.bind(this), 50); } }; + Sticky.prototype.clearEvents = function () { + if (this._scrollTimeout !== false) { + $(global).off('scroll', this._scrollEvent); + global.clearInterval(this._scrollTimeout); + this._scrollTimeout = false; + } + + if (this._resizeTimeout !== false) { + $(global).off('resize', this._resizeEvent); + global.clearInterval(this._resizeTimeout); + this._resizeTimeout = false; + } + + }; Sticky.prototype.viewportIsWideEnough = function (windowWidth) { return windowWidth > 768; }; diff --git a/tests/javascripts/fullscreenTable.test.js b/tests/javascripts/fullscreenTable.test.js index c1130f1ce..968712134 100644 --- a/tests/javascripts/fullscreenTable.test.js +++ b/tests/javascripts/fullscreenTable.test.js @@ -181,7 +181,7 @@ describe('FullscreenTable', () => { test("when the page has scrolled", () => { // scroll the window so the table fills the height of the window (768px) - windowMock.scrollBy(500); + windowMock.scrollTo(500); // the frames should crop to the window height expect(window.getComputedStyle(tableFrame)['height']).toEqual('768px'); diff --git a/tests/javascripts/stick-to-window-when-scrolling.test.js b/tests/javascripts/stick-to-window-when-scrolling.test.js new file mode 100644 index 000000000..fec68663f --- /dev/null +++ b/tests/javascripts/stick-to-window-when-scrolling.test.js @@ -0,0 +1,1336 @@ +const helpers = require('./support/helpers'); +const PADDING_BETWEEN_STICKYS = 40; +const PADDING_BEFORE_STOPPING_POINT = 10; + +function getScreenItemBottomPosition (screenItem) { + return screenItem.offsetTop + screenItem.offsetHeight; +}; + +function getCaretPosition (caretPosition, textarea) { + + return { + top: textarea.offsetTop + caretPosition.top, + bottom: textarea.offsetTop + caretPosition.top + caretPosition.height, + height: caretPosition.height + }; + +}; + +function getStickyGroupPosition (screenMock, opts) { + + const edgePosition = screenMock.window[opts.edge]; + const height = opts.stickyEls + .map(el => el.offsetHeight) + .reduce((accumulator, height) => accumulator + height); + + if (opts.edge === 'top') { + return { + top: screenMock.window.top, + bottom: edgePosition + height, + height: height + }; + } else { + return { + top: edgePosition - height, + bottom: screenMock.window.bottom, + height: height + } + } + +}; + +class CaretCoordinates { + constructor (data) { + this.top = 5.5; + this.left = 2; + this.height = 19; + } + + moveToLine (lineNumber) { + const lineHeight = 30; + const verticalPadding = 5.5; + + this.top = ((lineNumber - 1) * lineHeight) + verticalPadding; + } +} + +beforeAll(() => { + require('../../app/assets/javascripts/stick-to-window-when-scrolling.js'); +}); + +afterAll(() => { + require('./support/teardown.js'); +}); + +describe("Stick to top/bottom of window when scrolling", () => { + + let screenMock; + + describe("If intending to stick to the top", () => { + + let inputForm; + let formFooter; + let footer; + let windowHeight; + let getFurthestTopPoint; + + beforeEach(() => { + + document.body.innerHTML = ` +