Skip to content

Commit

Permalink
capricorn86#428@minor: Fixes select element undefined options error.
Browse files Browse the repository at this point in the history
  • Loading branch information
fatihcure-jf committed Jun 7, 2022
1 parent b8f80e9 commit ae1ad43
Show file tree
Hide file tree
Showing 23 changed files with 16,288 additions and 313 deletions.
592 changes: 296 additions & 296 deletions package-lock.json

Large diffs are not rendered by default.

9 changes: 6 additions & 3 deletions packages/happy-dom/src/config/ElementTag.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ import HTMLLabelElement from '../nodes/html-label-element/HTMLLabelElement';
import HTMLSlotElement from '../nodes/html-slot-element/HTMLSlotElement';
import HTMLMetaElement from '../nodes/html-meta-element/HTMLMetaElement';
import HTMLBaseElement from '../nodes/html-base-element/HTMLBaseElement';
import HTMLSelectElement from '../nodes/html-select-element/HTMLSelectElement';
import HTMLOptionElement from '../nodes/html-option-element/HTMLOptionElement';
import HTMLOptGroupElement from '../nodes/html-opt-group-element/HTMLOptGroupElement';

export default {
A: HTMLElement,
Expand Down Expand Up @@ -102,8 +105,8 @@ export default {
NOSCRIPT: HTMLElement,
OBJECT: HTMLElement,
OL: HTMLElement,
OPTGROUP: HTMLElement,
OPTION: HTMLElement,
OPTGROUP: HTMLOptGroupElement,
OPTION: HTMLOptionElement,
OUTPUT: HTMLElement,
P: HTMLElement,
PARAM: HTMLElement,
Expand All @@ -119,7 +122,7 @@ export default {
S: HTMLElement,
SAMP: HTMLElement,
SECTION: HTMLElement,
SELECT: HTMLElement,
SELECT: HTMLSelectElement,
SMALL: HTMLElement,
SOURCE: HTMLElement,
SPAN: HTMLElement,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,10 @@ export default [
'HTMLMediaElement',
'HTMLMeterElement',
'HTMLModElement',
'HTMLOptGroupElement',
'HTMLOptionElement',
'HTMLOutputElement',
'HTMLPictureElement',
'HTMLProgressElement',
'HTMLQuoteElement',
'HTMLSelectElement',
'HTMLSourceElement',
'HTMLSpanElement',
'HTMLTableCaptionElement',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import File from '../../file/File';
import HTMLElement from '../html-element/HTMLElement';
import ValidityState from './ValidityState';
import ValidityState from '../validity-state/ValidityState';
import DOMException from '../../exception/DOMException';
import DOMExceptionNameEnum from '../../exception/DOMExceptionNameEnum';
import Event from '../../event/Event';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import File from '../../file/File';
import IHTMLElement from '../html-element/IHTMLElement';
import IHTMLFormElement from '../html-form-element/IHTMLFormElement';
import HTMLInputElementSelectionModeEnum from './HTMLInputElementSelectionModeEnum';
import ValidityState from './ValidityState';
import ValidityState from '../validity-state/ValidityState';

/**
* HTML Input Element.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import HTMLElement from '../html-element/HTMLElement';
import IHTMLOptGroupElement from './IHTMLOptGroupElement';

/**
* HTML Opt Group Element.
*
* Reference:
* https://developer.mozilla.org/en-US/docs/Web/API/HTMLOptGroupElement.
*/
export default class HTMLOptGroupElement extends HTMLElement implements IHTMLOptGroupElement {
/**
* Returns label.
*
* @returns Label.
*/
public get label(): string {
return this.getAttributeNS(null, 'label') || '';
}

/**
* Sets label.
*
* @param label Label.
*/
public set label(label: string) {
if (!label) {
this.removeAttributeNS(null, 'label');
} else {
this.setAttributeNS(null, 'label', label);
}
}

/**
* Returns disabled.
*
* @returns Disabled.
*/
public get disabled(): boolean {
return this.getAttributeNS(null, 'disabled') !== null;
}

/**
* Sets disabled.
*
* @param disabled Disabled.
*/
public set disabled(disabled: boolean) {
if (!disabled) {
this.removeAttributeNS(null, 'disabled');
} else {
this.setAttributeNS(null, 'disabled', '');
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import IHTMLElement from '../html-element/IHTMLElement';

/**
* HTML Opt Group Element.
*
* Reference:
* https://developer.mozilla.org/en-US/docs/Web/API/HTMLOptGroupElement.
*/
export default interface IHTMLOptGroupElement extends IHTMLElement {
disabled: boolean;
label: string;
}
117 changes: 117 additions & 0 deletions packages/happy-dom/src/nodes/html-option-element/HTMLOptionElement.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import HTMLElement from '../html-element/HTMLElement';
import IHTMLElement from '../html-element/IHTMLElement';
import IHTMLFormElement from '../html-form-element/IHTMLFormElement';
import HTMLOptionElementValueSanitizer from './HTMLOptionElementValueSanitizer';
import IHTMLOptionElement from './IHTMLOptionElement';

/**
* HTML Option Element.
*
* Reference:
* https://developer.mozilla.org/en-US/docs/Web/API/HTMLOptionElement.
*/
export default class HTMLOptionElement extends HTMLElement implements IHTMLOptionElement {
public _index: number;

/**
* Returns inner text, which is the rendered appearance of text.
*
* @returns Inner text.
*/
public get text(): string {
return this.innerText;
}

/**
* Sets the inner text, which is the rendered appearance of text.
*
* @param innerText Inner text.
*/
public set text(text: string) {
this.innerText = text;
}

/**
* Returns index.
*
* @returns Index.
*/
public get index(): number {
return this._index;
}

/**
* Returns the parent form element.
*
* @returns Form.
*/
public get form(): IHTMLFormElement {
let parent = <IHTMLElement>this.parentNode;
while (parent && parent.tagName !== 'FORM') {
parent = <IHTMLElement>parent.parentNode;
}
return <IHTMLFormElement>parent;
}

/**
* Returns selected.
*
* @returns Selected.
*/
public get selected(): boolean {
return this.getAttributeNS(null, 'selected') !== null;
}

/**
* Sets selected.
*
* @param selected Selected.
*/
public set selected(selected: boolean) {
if (!selected) {
this.removeAttributeNS(null, 'selected');
} else {
this.setAttributeNS(null, 'selected', '');
}
}

/**
* Returns disabled.
*
* @returns Disabled.
*/
public get disabled(): boolean {
return this.getAttributeNS(null, 'disabled') !== null;
}

/**
* Sets disabled.
*
* @param disabled Disabled.
*/
public set disabled(disabled: boolean) {
if (!disabled) {
this.removeAttributeNS(null, 'disabled');
} else {
this.setAttributeNS(null, 'disabled', '');
}
}

/**
* Returns value.
*
* @returns Value.
*/
public get value(): string {
return this.getAttributeNS(null, 'value') || '';
}

/**
* Sets value.
*
* @param value Value.
*/
public set value(value: string) {
this.setAttributeNS(null, 'value', HTMLOptionElementValueSanitizer.sanitize(value));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const NEW_LINES_REGEXP = /[\n\r]/gm;

/**
* HTML select element value sanitizer.
*/
export default class HTMLOptionElementValueSanitizer {
/**
* Sanitizes a value.
*
* @param value Value.
*/
public static sanitize(value: string): string {
return value.trim().replace(NEW_LINES_REGEXP, '');
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import DOMException from '../../exception/DOMException';
import HTMLCollection from '../element/HTMLCollection';
import HTMLOptGroupElement from '../html-opt-group-element/HTMLOptGroupElement';
import HTMLOptionElement from './HTMLOptionElement';
import IHTMLOptionsCollection from './IHTMLOptionsCollection';

/**
* HTML Options Collection.
*
* Reference:
* https://developer.mozilla.org/en-US/docs/Web/API/HTMLOptionsCollection.
*/
export default class HTMLOptionsCollection
extends HTMLCollection
implements IHTMLOptionsCollection
{
public _selectedIndex: number;

/**
* Returns selectedIndex.
*
* @returns SelectedIndex.
*/
public get selectedIndex(): number {
return this._selectedIndex;
}

/**
* Sets selectedIndex.
*
* @param selectedIndex SelectedIndex.
*/
public set selectedIndex(selectedIndex: number) {
this._selectedIndex = selectedIndex;
}

/**
* Returns item by index.
*
* @param index Index.
*/
public item(index: number): HTMLOptionElement | HTMLOptGroupElement {
return this[index];
}

/**
*
* @param element
* @param before
*/
public add(
element: HTMLOptionElement | HTMLOptGroupElement,
before?: number | HTMLOptionElement | HTMLOptGroupElement
): void {
if (!before && before !== 0) {
this.push(element);
return;
}

if (!Number.isNaN(Number(before))) {
if (before < 0) {
return;
}

this.splice(<number>before, 0, element);
return;
}

const idx = this.findIndex((element) => element === before);
if (idx === -1) {
throw new DOMException(
"Failed to execute 'add' on 'DOMException': The node before which the new node is to be inserted is not a child of this node."
);
}

this.splice(idx, 0, element);
}

/**
* Removes indexed element from collection.
*
* @param index Index.
*/
public remove(index: number): void {
this.splice(index, 1);
if (index === this.selectedIndex) {
if (this.length) {
this.selectedIndex = 0;
} else {
this.selectedIndex = -1;
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import IHTMLElement from '../html-element/IHTMLElement';
import IHTMLFormElement from '../html-form-element/IHTMLFormElement';

/**
* HTML Option Element.
*
* Reference:
* https://developer.mozilla.org/en-US/docs/Web/API/HTMLOptionElement.
*/
export default interface IHTMLOptionElement extends IHTMLElement {
readonly form: IHTMLFormElement;
readonly index: number;
selected: boolean;
value: string;
text: string;
disabled: boolean;
}

0 comments on commit ae1ad43

Please sign in to comment.