Repository: capricorn86/happy-dom
Pull request #832 (2023-04-01 16:56:48)

#691@minor: Adds support for HTMLTextAreaElement.select().


Patch:
diff --git a/packages/happy-dom/src/nodes/html-button-element/IHTMLButtonElement.ts b/packages/happy-dom/src/nodes/html-button-element/IHTMLButtonElement.ts
index 0db0bec3..c61e5fb5 100644
--- a/packages/happy-dom/src/nodes/html-button-element/IHTMLButtonElement.ts
+++ b/packages/happy-dom/src/nodes/html-button-element/IHTMLButtonElement.ts
@@ -1,3 +1,4 @@
+import ValidityState from '../../validity-state/ValidityState';
 import IHTMLElement from '../html-element/IHTMLElement';
 import IHTMLFormElement from '../html-form-element/IHTMLFormElement';
 import IHTMLLabelElement from '../html-label-element/IHTMLLabelElement';
@@ -15,6 +16,7 @@ export default interface IHTMLButtonElement extends IHTMLElement {
 	disabled: boolean;
 	type: string;
 	formNoValidate: boolean;
+	readonly validity: ValidityState;
 	readonly form: IHTMLFormElement;
 	readonly validationMessage: string;
 	readonly labels: INodeList<IHTMLLabelElement>;
diff --git a/packages/happy-dom/src/nodes/html-input-element/IHTMLInputElement.ts b/packages/happy-dom/src/nodes/html-input-element/IHTMLInputElement.ts
index fef9056e..64452437 100644
--- a/packages/happy-dom/src/nodes/html-input-element/IHTMLInputElement.ts
+++ b/packages/happy-dom/src/nodes/html-input-element/IHTMLInputElement.ts
@@ -17,6 +17,7 @@ import IHTMLLabelElement from '../html-label-element/IHTMLLabelElement';
 export default interface IHTMLInputElement extends IHTMLElement {
 	readonly form: IHTMLFormElement;
 	readonly labels: INodeList<IHTMLLabelElement>;
+	readonly validity: ValidityState;
 	formAction: string;
 	formMethod: string;
 	formNoValidate: boolean;
@@ -52,7 +53,6 @@ export default interface IHTMLInputElement extends IHTMLElement {
 	selectionStart: number;
 	selectionEnd: number;
 	selectionDirection: string;
-	validity: ValidityState;
 	willValidate: boolean;
 	valueAsDate: Date;
 	valueAsNumber: number;
@@ -75,6 +75,11 @@ export default interface IHTMLInputElement extends IHTMLElement {
 	 */
 	reportValidity(): void;
 
+	/**
+	 * Selects the text.
+	 */
+	select(): void;
+
 	/**
 	 * Set selection range.
 	 *
@@ -100,21 +105,6 @@ export default interface IHTMLInputElement extends IHTMLElement {
 		selectionMode?: HTMLInputElementSelectionModeEnum
 	): void;
 
-	/**
-	 * Set range text.
-	 *
-	 * @param replacement Replacement.
-	 * @param [start] Start.
-	 * @param [end] End.
-	 * @param [direction] Direction.
-	 */
-	setRangeText(
-		replacement: string,
-		start: number,
-		end: number,
-		selectionMode: HTMLInputElementSelectionModeEnum
-	): void;
-
 	/**
 	 * Checks validity.
 	 *
diff --git a/packages/happy-dom/src/nodes/html-text-area-element/HTMLTextAreaElement.ts b/packages/happy-dom/src/nodes/html-text-area-element/HTMLTextAreaElement.ts
index e97c4620..0ad8840c 100644
--- a/packages/happy-dom/src/nodes/html-text-area-element/HTMLTextAreaElement.ts
+++ b/packages/happy-dom/src/nodes/html-text-area-element/HTMLTextAreaElement.ts
@@ -429,6 +429,17 @@ export default class HTMLTextAreaElement extends HTMLElement implements IHTMLTex
 		return new NodeList<IHTMLLabelElement>();
 	}
 
+	/**
+	 * Selects the text.
+	 */
+	public select(): void {
+		this._selectionStart = 0;
+		this._selectionEnd = this.value.length;
+		this._selectionDirection = HTMLInputElementSelectionDirectionEnum.none;
+
+		this.dispatchEvent(new Event('select', { bubbles: true, cancelable: true }));
+	}
+
 	/**
 	 * Set selection range.
 	 *
diff --git a/packages/happy-dom/src/nodes/html-text-area-element/IHTMLTextAreaElement.ts b/packages/happy-dom/src/nodes/html-text-area-element/IHTMLTextAreaElement.ts
index 93f1df31..df5729b4 100644
--- a/packages/happy-dom/src/nodes/html-text-area-element/IHTMLTextAreaElement.ts
+++ b/packages/happy-dom/src/nodes/html-text-area-element/IHTMLTextAreaElement.ts
@@ -1,4 +1,5 @@
 import Event from '../../event/Event';
+import ValidityState from '../../validity-state/ValidityState';
 import IHTMLElement from '../html-element/IHTMLElement';
 import IHTMLFormElement from '../html-form-element/IHTMLFormElement';
 import HTMLInputElementSelectionModeEnum from '../html-input-element/HTMLInputElementSelectionModeEnum';
@@ -16,6 +17,7 @@ export default interface IHTMLTextAreaElement extends IHTMLElement {
 	readonly form: IHTMLFormElement;
 	readonly validationMessage: string;
 	readonly labels: INodeList<IHTMLLabelElement>;
+	readonly validity: ValidityState;
 	defaultValue: string;
 	minLength: number;
 	maxLength: number;
@@ -39,6 +41,11 @@ export default interface IHTMLTextAreaElement extends IHTMLElement {
 	oninput: (event: Event) => void | null;
 	onselectionchange: (event: Event) => void | null;
 
+	/**
+	 * Selects the text.
+	 */
+	select(): void;
+
 	/**
 	 * Set selection range.
 	 *
@@ -60,7 +67,7 @@ export default interface IHTMLTextAreaElement extends IHTMLElement {
 		replacement: string,
 		start: number,
 		end: number,
-		selectionMode: HTMLInputElementSelectionModeEnum
+		selectionMode?: HTMLInputElementSelectionModeEnum
 	): void;
 
 	/**


Test patch:
diff --git a/packages/happy-dom/test/nodes/html-button-element/HTMLButtonElement.test.ts b/packages/happy-dom/test/nodes/html-button-element/HTMLButtonElement.test.ts
index 7ba1ead9..a229540d 100644
--- a/packages/happy-dom/test/nodes/html-button-element/HTMLButtonElement.test.ts
+++ b/packages/happy-dom/test/nodes/html-button-element/HTMLButtonElement.test.ts
@@ -1,21 +1,20 @@
 import Window from '../../../src/window/Window';
 import Document from '../../../src/nodes/document/Document';
-import HTMLButtonElement from '../../../src/nodes/html-button-element/HTMLButtonElement';
+import IHTMLButtonElement from '../../../src/nodes/html-button-element/IHTMLButtonElement';
 import Event from '../../../src/event/Event';
 import IHTMLElement from '../../../src/nodes/html-element/IHTMLElement';
 import IHTMLFormElement from '../../../src/nodes/html-form-element/IHTMLFormElement';
 import ValidityState from '../../../src/validity-state/ValidityState';
-import IHTMLButtonElement from '../../../src/nodes/html-button-element/IHTMLButtonElement';
 
 describe('HTMLButtonElement', () => {
 	let window: Window;
 	let document: Document;
-	let element: HTMLButtonElement;
+	let element: IHTMLButtonElement;
 
 	beforeEach(() => {
 		window = new Window();
 		document = window.document;
-		element = <HTMLButtonElement>document.createElement('button');
+		element = <IHTMLButtonElement>document.createElement('button');
 	});
 
 	describe('Object.prototype.toString', () => {
diff --git a/packages/happy-dom/test/nodes/html-input-element/HTMLInputElement.test.ts b/packages/happy-dom/test/nodes/html-input-element/HTMLInputElement.test.ts
index fe587c95..5adc0fe3 100644
--- a/packages/happy-dom/test/nodes/html-input-element/HTMLInputElement.test.ts
+++ b/packages/happy-dom/test/nodes/html-input-element/HTMLInputElement.test.ts
@@ -538,13 +538,29 @@ describe('HTMLInputElement', () => {
 		});
 	});
 
+	describe('select()', () => {
+		it('Selects all text.', () => {
+			let triggeredEvent: Event | null = null;
+			element.addEventListener('select', (event) => (triggeredEvent = event));
+			element.value = 'TEST_VALUE';
+			element.select();
+			expect(element.selectionStart).toBe(0);
+			expect(element.selectionEnd).toBe(10);
+			expect(element.selectionDirection).toBe('none');
+			expect(triggeredEvent.type).toBe('select');
+		});
+	});
+
 	describe('setSelectionRange()', () => {
 		it('Sets selection range.', () => {
+			let triggeredEvent: Event | null = null;
+			element.addEventListener('select', (event) => (triggeredEvent = event));
 			element.value = 'TEST_VALUE';
 			element.setSelectionRange(1, 5, 'forward');
 			expect(element.selectionStart).toBe(1);
 			expect(element.selectionEnd).toBe(5);
 			expect(element.selectionDirection).toBe('forward');
+			expect(triggeredEvent.type).toBe('select');
 		});
 
 		it('Sets selection end to the value length if out of range.', () => {
diff --git a/packages/happy-dom/test/nodes/html-text-area-element/HTMLTextAreaElement.test.ts b/packages/happy-dom/test/nodes/html-text-area-element/HTMLTextAreaElement.test.ts
index 56ea2519..a359ce9e 100644
--- a/packages/happy-dom/test/nodes/html-text-area-element/HTMLTextAreaElement.test.ts
+++ b/packages/happy-dom/test/nodes/html-text-area-element/HTMLTextAreaElement.test.ts
@@ -1,6 +1,6 @@
 import Window from '../../../src/window/Window';
 import Document from '../../../src/nodes/document/Document';
-import HTMLTextAreaElement from '../../../src/nodes/html-text-area-element/HTMLTextAreaElement';
+import IHTMLTextAreaElement from '../../../src/nodes/html-text-area-element/IHTMLTextAreaElement';
 import HTMLInputElementSelectionModeEnum from '../../../src/nodes/html-input-element/HTMLInputElementSelectionModeEnum';
 import HTMLInputElementSelectionDirectionEnum from '../../../src/nodes/html-input-element/HTMLInputElementSelectionDirectionEnum';
 import ValidityState from '../../../src/validity-state/ValidityState';
@@ -10,12 +10,12 @@ import IText from '../../../src/nodes/text/IText';
 describe('HTMLTextAreaElement', () => {
 	let window: Window;
 	let document: Document;
-	let element: HTMLTextAreaElement;
+	let element: IHTMLTextAreaElement;
 
 	beforeEach(() => {
 		window = new Window();
 		document = window.document;
-		element = <HTMLTextAreaElement>document.createElement('textarea');
+		element = <IHTMLTextAreaElement>document.createElement('textarea');
 	});
 
 	describe('Object.prototype.toString', () => {
@@ -230,13 +230,29 @@ describe('HTMLTextAreaElement', () => {
 		});
 	}
 
+	describe('select()', () => {
+		it('Selects all text.', () => {
+			let triggeredEvent: Event | null = null;
+			element.addEventListener('select', (event) => (triggeredEvent = event));
+			element.value = 'TEST_VALUE';
+			element.select();
+			expect(element.selectionStart).toBe(0);
+			expect(element.selectionEnd).toBe(10);
+			expect(element.selectionDirection).toBe('none');
+			expect(triggeredEvent.type).toBe('select');
+		});
+	});
+
 	describe('setSelectionRange()', () => {
 		it('Sets selection range.', () => {
+			let triggeredEvent: Event | null = null;
+			element.addEventListener('select', (event) => (triggeredEvent = event));
 			element.value = 'TEST_VALUE';
 			element.setSelectionRange(1, 5, 'forward');
 			expect(element.selectionStart).toBe(1);
 			expect(element.selectionEnd).toBe(5);
 			expect(element.selectionDirection).toBe('forward');
+			expect(triggeredEvent.type).toBe('select');
 		});
 
 		it('Sets selection end to the value length if out of range.', () => {