Skip to content

Commit

Permalink
feat: [capricorn86#1282] Support selectedOptions for select
Browse files Browse the repository at this point in the history
  • Loading branch information
otaviosoares committed Mar 21, 2024
1 parent 2ce84c0 commit 41c1d8c
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import NodeTypeEnum from '../node/NodeTypeEnum.js';
import HTMLLabelElementUtility from '../html-label-element/HTMLLabelElementUtility.js';
import NamedNodeMap from '../../named-node-map/NamedNodeMap.js';
import HTMLSelectElementNamedNodeMap from './HTMLSelectElementNamedNodeMap.js';
import HTMLCollection from '../element/HTMLCollection.js';

/**
* HTML Select Element.
Expand Down Expand Up @@ -251,6 +252,21 @@ export default class HTMLSelectElement extends HTMLElement {
}
}

/**
* Returns selected options.
*
* @returns HTMLCollection.
*/
public get selectedOptions(): HTMLCollection<HTMLOptionElement> {
const selectedOptions = new HTMLCollection<HTMLOptionElement>();
for (let i = 0, max = this[PropertySymbol.options].length; i < max; i++) {
if ((<HTMLOptionElement>this[PropertySymbol.options][i])[PropertySymbol.selectedness]) {
selectedOptions.push(<HTMLOptionElement>this[PropertySymbol.options][i]);
}
}
return selectedOptions;
}

/**
* Returns the associated label elements.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import HTMLOptionElement from '../../../src/nodes/html-option-element/HTMLOption
import ValidityState from '../../../src/validity-state/ValidityState.js';
import Event from '../../../src/event/Event.js';
import { beforeEach, describe, it, expect } from 'vitest';
import HTMLCollection from '../../../src/nodes/element/HTMLCollection.js';

describe('HTMLSelectElement', () => {
let window: Window;
Expand Down Expand Up @@ -161,6 +162,61 @@ describe('HTMLSelectElement', () => {
});
});

describe(`get selectedOptions()`, () => {
it('Defaults to an empty HTMLCollection.', () => {
expect(element.selectedOptions).toBeInstanceOf(HTMLCollection);
expect(element.selectedOptions.length).toBe(0);
});

it('Returns selected options with "selected" attribute is defined.', () => {
const option1 = document.createElement('option');
const option2 = document.createElement('option');

option2.setAttribute('selected', '');

element.appendChild(option1);
element.appendChild(option2);

expect(element.selectedOptions.length).toBe(1);
expect(element.selectedOptions[0]).toBe(option2);

option1.setAttribute('selected', '');

expect(element.selectedOptions.length).toBe(1);
expect(element.selectedOptions[0]).toBe(option1);

option2.removeAttribute('selected');

expect(element.selectedOptions.length).toBe(1);
expect(element.selectedOptions[0]).toBe(option1);
});

it('Multiple - Returns selected options with "selected" attribute is defined.', () => {
element.setAttribute('multiple', '');
const option1 = document.createElement('option');
const option2 = document.createElement('option');

option2.setAttribute('selected', '');

element.appendChild(option1);
element.appendChild(option2);

expect(element.selectedOptions.length).toBe(1);
expect(element.selectedOptions[0]).toBe(option2);

option1.setAttribute('selected', '');

expect(element.selectedOptions.length).toBe(2);
expect(element.selectedOptions[0]).toBe(option1);
expect(element.selectedOptions[1]).toBe(option2);

option2.removeAttribute('selected');

expect(element.selectedOptions.length).toBe(1);
expect(element.selectedOptions[0]).toBe(option1);
});
});

describe(`set selectedIndex()`, () => {
it('Allows -1', () => {
element.selectedIndex = -1;
Expand Down

0 comments on commit 41c1d8c

Please sign in to comment.