Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#681@minor: Add scrollX, scrollY, pageXOffset, pageYOffset to window. #681

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/happy-dom/src/window/IWindow.ts
Expand Up @@ -245,6 +245,10 @@ export default interface IWindow extends IEventTarget, NodeJS.Global {
readonly sessionStorage: Storage;
readonly localStorage: Storage;
readonly performance: Performance;
readonly pageXOffset: number;
readonly pageYOffset: number;
readonly scrollX: number;
readonly scrollY: number;

/**
* Evaluates code.
Expand Down
38 changes: 37 additions & 1 deletion packages/happy-dom/src/window/Window.ts
Expand Up @@ -14,7 +14,7 @@ import HTMLFormElement from '../nodes/html-form-element/HTMLFormElement';
import HTMLElement from '../nodes/html-element/HTMLElement';
import HTMLUnknownElement from '../nodes/html-unknown-element/HTMLUnknownElement';
import HTMLInputElement from '../nodes/html-input-element/HTMLInputElement';
import HTMLSelectElement from '../nodes/html-input-element/HTMLSelectElement';
import HTMLSelectElement from '../nodes/html-select-element/HTMLSelectElement';
import HTMLTextAreaElement from '../nodes/html-text-area-element/HTMLTextAreaElement';
import HTMLLinkElement from '../nodes/html-link-element/HTMLLinkElement';
import HTMLStyleElement from '../nodes/html-style-element/HTMLStyleElement';
Expand Down Expand Up @@ -483,6 +483,42 @@ export default class Window extends EventTarget implements IWindow {
this.document._onWindowReady();
}

/**
* The number of pixels that the document is currently scrolled horizontally
*
* @returns number
*/
public get scrollX(): number {
return this?.document?.documentElement?.scrollLeft ?? 0;
capricorn86 marked this conversation as resolved.
Show resolved Hide resolved
}

/**
* The read-only Window property pageXOffset is an alias for scrollX.
*
* @returns number
*/
public get pageXOffset(): number {
return this.scrollX;
}

/**
* The number of pixels that the document is currently scrolled vertically
*
* @returns number
*/
public get scrollY(): number {
return this?.document?.documentElement?.scrollTop ?? 0;
capricorn86 marked this conversation as resolved.
Show resolved Hide resolved
}

/**
* The read-only Window property pageYOffset is an alias for scrollY.
*
* @returns number
*/
public get pageYOffset(): number {
return this.scrollY;
}

/**
* The CSS interface holds useful CSS-related methods.
*
Expand Down
36 changes: 31 additions & 5 deletions packages/happy-dom/test/window/Window.test.ts
Expand Up @@ -667,37 +667,63 @@ describe('Window', () => {

for (const functionName of ['scroll', 'scrollTo']) {
describe(`${functionName}()`, () => {
it('Sets the properties scrollTop and scrollLeft.', () => {
it('Sets the properties scrollTop, scrollLeft, scrollY, scrollX, pageXOffset and pageYOffset', () => {
window[functionName](50, 60);
expect(window.document.documentElement.scrollLeft).toBe(50);
expect(window.document.documentElement.scrollTop).toBe(60);
expect(window.pageXOffset).toBe(50);
expect(window.pageYOffset).toBe(60);
expect(window.scrollX).toBe(50);
expect(window.scrollY).toBe(60);
});

it('Sets the properties scrollTop and scrollLeft using object.', () => {
it('Sets the properties scrollTop, scrollLeft, scrollY, scrollX, pageXOffset and pageYOffset using object.', () => {
window[functionName]({ left: 50, top: 60 });
expect(window.document.documentElement.scrollLeft).toBe(50);
expect(window.document.documentElement.scrollTop).toBe(60);
expect(window.pageXOffset).toBe(50);
expect(window.pageYOffset).toBe(60);
expect(window.scrollX).toBe(50);
expect(window.scrollY).toBe(60);
});

it('Sets only the property scrollTop.', () => {
it('Sets only the property scrollTop, pageYOffset, and scrollY', () => {
window[functionName]({ top: 60 });
expect(window.document.documentElement.scrollLeft).toBe(0);
expect(window.document.documentElement.scrollTop).toBe(60);
expect(window.pageXOffset).toBe(0);
expect(window.pageYOffset).toBe(60);
expect(window.scrollX).toBe(0);
expect(window.scrollY).toBe(60);
});

it('Sets only the property scrollLeft.', () => {
it('Sets only the property scrollLeft, pageXOffset, and scrollX', () => {
window[functionName]({ left: 60 });
expect(window.document.documentElement.scrollLeft).toBe(60);
expect(window.document.documentElement.scrollTop).toBe(0);
expect(window.document.documentElement.scrollLeft).toBe(60);
expect(window.document.documentElement.scrollTop).toBe(0);
expect(window.pageXOffset).toBe(60);
expect(window.pageYOffset).toBe(0);
expect(window.scrollX).toBe(60);
expect(window.scrollY).toBe(0);
});

it('Sets the properties scrollTop and scrollLeft with animation.', async () => {
it('Sets the properties scrollTop, scrollLeft, scrollY, scrollX, pageXOffset and pageYOffset with animation.', async () => {
window[functionName]({ left: 50, top: 60, behavior: 'smooth' });
expect(window.document.documentElement.scrollLeft).toBe(0);
expect(window.document.documentElement.scrollTop).toBe(0);
expect(window.pageXOffset).toBe(0);
expect(window.pageYOffset).toBe(0);
expect(window.scrollX).toBe(0);
expect(window.scrollY).toBe(0);
await window.happyDOM.whenAsyncComplete();
expect(window.document.documentElement.scrollLeft).toBe(50);
expect(window.document.documentElement.scrollTop).toBe(60);
expect(window.pageXOffset).toBe(50);
expect(window.pageYOffset).toBe(60);
expect(window.scrollX).toBe(50);
expect(window.scrollY).toBe(60);
});
});
}
Expand Down