diff options
author | 7PH <benjamin.raymond@sonarsource.com> | 2023-05-03 13:56:07 +0200 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2023-05-03 20:02:58 +0000 |
commit | 28c90e506a83f31e09b5c9ea5abf098a6dc37df8 (patch) | |
tree | a442bf3a7df43b9ffc804be11a1e7aef75494bbc /server/sonar-web/src/main/js/helpers | |
parent | 22b829b7b8a22cbb8305c0474baaeedaf53d7938 (diff) | |
download | sonarqube-28c90e506a83f31e09b5c9ea5abf098a6dc37df8.tar.gz sonarqube-28c90e506a83f31e09b5c9ea5abf098a6dc37df8.zip |
SONAR-18670 Drop scrollToElement helper function in favor of native browser scroll utilities
Diffstat (limited to 'server/sonar-web/src/main/js/helpers')
3 files changed, 5 insertions, 279 deletions
diff --git a/server/sonar-web/src/main/js/helpers/__tests__/scrolling-test.ts b/server/sonar-web/src/main/js/helpers/__tests__/scrolling-test.ts deleted file mode 100644 index f9e938f2c13..00000000000 --- a/server/sonar-web/src/main/js/helpers/__tests__/scrolling-test.ts +++ /dev/null @@ -1,120 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2023 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -import { scrollToElement } from '../scrolling'; - -beforeAll(() => { - jest.useFakeTimers(); -}); - -afterAll(() => { - jest.runOnlyPendingTimers(); - jest.useRealTimers(); -}); - -describe('scrollToElement', () => { - it('should scroll parent up to element', () => { - const element = document.createElement('a'); - element.getBoundingClientRect = mockGetBoundingClientRect({ top: 5, bottom: 20 }); - - const parent = document.createElement('div'); - parent.getBoundingClientRect = mockGetBoundingClientRect({ height: 30, top: 15 }); - parent.scrollTop = 10; - parent.scrollLeft = 12; - parent.appendChild(element); - - document.body.appendChild(parent); - scrollToElement(element, { parent, smooth: false }); - - expect(parent.scrollTop).toEqual(0); - expect(parent.scrollLeft).toEqual(12); - }); - - it('should scroll parent down to element', () => { - const element = document.createElement('a'); - element.getBoundingClientRect = mockGetBoundingClientRect({ top: 25, bottom: 50 }); - - const parent = document.createElement('div'); - parent.getBoundingClientRect = mockGetBoundingClientRect({ height: 30, top: 15 }); - parent.scrollTop = 10; - parent.scrollLeft = 12; - parent.appendChild(element); - - document.body.appendChild(parent); - scrollToElement(element, { parent, smooth: false }); - - expect(parent.scrollTop).toEqual(15); - expect(parent.scrollLeft).toEqual(12); - }); - - it('should scroll window down to element', () => { - const element = document.createElement('a'); - element.getBoundingClientRect = mockGetBoundingClientRect({ top: 840, bottom: 845 }); - - Object.defineProperty(window, 'innerHeight', { value: 400 }); - window.scrollTo = jest.fn(); - - document.body.appendChild(element); - - scrollToElement(element, { smooth: false }); - - expect(window.scrollTo).toHaveBeenCalledWith(0, 445); - }); - - it('should scroll window up to element', () => { - const element = document.createElement('a'); - element.getBoundingClientRect = mockGetBoundingClientRect({ top: -10, bottom: 10 }); - - Object.defineProperty(window, 'innerHeight', { value: 50 }); - window.scrollTo = jest.fn(); - - document.body.appendChild(element); - - scrollToElement(element, { smooth: false }); - - expect(window.scrollTo).toHaveBeenCalledWith(0, -10); - }); - - it('should scroll window down to element smoothly', () => { - const element = document.createElement('a'); - element.getBoundingClientRect = mockGetBoundingClientRect({ top: 840, bottom: 845 }); - - Object.defineProperty(window, 'innerHeight', { value: 400 }); - window.scrollTo = jest.fn(); - - document.body.appendChild(element); - - scrollToElement(element, {}); - - jest.runAllTimers(); - - expect(window.scrollTo).toHaveBeenCalledTimes(10); - }); -}); - -const mockGetBoundingClientRect = (overrides: Partial<ClientRect>) => () => - ({ - bottom: 0, - height: 0, - left: 0, - right: 0, - top: 0, - width: 0, - ...overrides, - } as DOMRect); diff --git a/server/sonar-web/src/main/js/helpers/mocks/security-hotspots.ts b/server/sonar-web/src/main/js/helpers/mocks/security-hotspots.ts index afc79f6c77f..946b1f79a24 100644 --- a/server/sonar-web/src/main/js/helpers/mocks/security-hotspots.ts +++ b/server/sonar-web/src/main/js/helpers/mocks/security-hotspots.ts @@ -67,17 +67,17 @@ export function mockHotspot(overrides?: Partial<Hotspot>): Hotspot { creationDate: '2013-05-13T17:55:41+0200', flows: [{ locations: [mockFlowLocation()] }], key: '01fc972e-2a3c-433e-bcae-0bd7f88f5123', - line: 142, + line: 6, message: "'3' is a magic number.", project: mockHotspotComponent({ qualifier: ComponentQualifier.Project }), resolution: HotspotResolution.FIXED, rule: mockHotspotRule(), status: HotspotStatus.REVIEWED, textRange: { - startLine: 142, - endLine: 142, - startOffset: 26, - endOffset: 83, + startLine: 6, + endLine: 6, + startOffset: 3, + endOffset: 9, }, updateDate: '2013-05-13T17:55:42+0200', users: [assigneeUser, authorUser], diff --git a/server/sonar-web/src/main/js/helpers/scrolling.ts b/server/sonar-web/src/main/js/helpers/scrolling.ts deleted file mode 100644 index 5edda86d2e0..00000000000 --- a/server/sonar-web/src/main/js/helpers/scrolling.ts +++ /dev/null @@ -1,154 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2023 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -const SCROLLING_DURATION = 100; -const SCROLLING_INTERVAL = 10; -const SCROLLING_STEPS = SCROLLING_DURATION / SCROLLING_INTERVAL; - -function isWindow(element: Element | Window): element is Window { - return element === window; -} - -function getScroll(element: Element | Window) { - return isWindow(element) - ? { x: window.pageXOffset, y: window.pageYOffset } - : { x: element.scrollLeft, y: element.scrollTop }; -} - -function scrollElement(element: Element | Window, x: number, y: number): Promise<void> { - if (isWindow(element)) { - window.scrollTo(x, y); - } else { - element.scrollLeft = x; - element.scrollTop = y; - } - return Promise.resolve(); -} - -function smoothScroll( - target: number, - current: number, - scroll: (position: number) => void -): Promise<void> { - const positiveDirection = target > current; - const step = Math.ceil(Math.abs(target - current) / SCROLLING_STEPS); - let stepsDone = 0; - - return new Promise((resolve) => { - const interval = setInterval(() => { - if (current === target || SCROLLING_STEPS === stepsDone) { - clearInterval(interval); - resolve(); - } else { - let goal; - if (positiveDirection) { - goal = Math.min(target, current + step); - } else { - goal = Math.max(target, current - step); - } - stepsDone++; - current = goal; - scroll(goal); - } - }, SCROLLING_INTERVAL); - }); -} - -function smoothScrollTop(parent: Element | Window, position: number) { - const scroll = getScroll(parent); - return smoothScroll(position, scroll.y, (position) => scrollElement(parent, scroll.x, position)); -} - -/** - * @deprecated use scrollIntoView instead - */ -export function scrollToElement( - element: Element, - options: { - topOffset?: number; - bottomOffset?: number; - parent?: Element; - smooth?: boolean; - } -): void { - const opts = { topOffset: 0, bottomOffset: 0, parent: window, smooth: true, ...options }; - const { parent } = opts; - - const { top, bottom } = element.getBoundingClientRect(); - - const scroll = getScroll(parent); - - const height: number = isWindow(parent) - ? window.innerHeight - : parent.getBoundingClientRect().height; - - const parentTop = isWindow(parent) ? 0 : parent.getBoundingClientRect().top; - - if (top - parentTop < opts.topOffset) { - const goal = scroll.y - opts.topOffset + top - parentTop; - if (opts.smooth) { - addToScrollQueue(smoothScrollTop, parent, goal); - } else { - addToScrollQueue(scrollElement, parent, scroll.x, goal); - } - } - - if (bottom - parentTop > height - opts.bottomOffset) { - const goal = scroll.y + bottom - parentTop - height + opts.bottomOffset; - if (opts.smooth) { - addToScrollQueue(smoothScrollTop, parent, goal); - } else { - addToScrollQueue(scrollElement, parent, scroll.x, goal); - } - } -} - -type ScrollFunction = (element: Element | Window, x: number, y?: number) => Promise<void>; - -interface ScrollQueueItem { - element: Element | Window; - fn: ScrollFunction; - x: number; - y?: number; -} - -const queue: ScrollQueueItem[] = []; -let queueRunning: boolean; - -function addToScrollQueue( - fn: ScrollFunction, - element: Element | Window, - x: number, - y?: number -): void { - queue.push({ fn, element, x, y }); - if (!queueRunning) { - processQueue(); - } -} - -function processQueue() { - if (queue.length > 0) { - queueRunning = true; - const { fn, element, x, y } = queue.shift()!; - fn(element, x, y).then(processQueue).catch(processQueue); - } else { - queueRunning = false; - } -} |