Browse Source

Organize code

Switch order in appearance of definitions.
master
TheoryOfNekomata 3 years ago
parent
commit
1495659990
1 changed files with 96 additions and 107 deletions
  1. +96
    -107
      src/index.ts

+ 96
- 107
src/index.ts View File

@@ -1,12 +1,3 @@
/**
* Type for valid field elements.
*/
export type HTMLFieldElement
= HTMLInputElement
| HTMLButtonElement
| HTMLSelectElement
| HTMLTextAreaElement

/**
* Line ending.
*/
@@ -25,84 +16,6 @@ export enum LineEnding {
CRLF = '\r\n',
}

/**
* Type for valid submitter elements.
*
* Only the `<button>` and `<input>` elements can be submitter elements.
*/
export type HTMLSubmitterElement
= HTMLButtonElement
| HTMLInputElement

/**
* Options for getting a `<textarea>` element field value.
*/
type GetTextAreaValueOptions = {
/**
* Line ending used for the element's value.
*/
lineEndings?: LineEnding,
}

/**
* Options for getting a `<select>` element field value.
*/
type GetSelectValueOptions = {}

/**
* Options for getting an `<input type="checkbox">` element field value.
*/
type GetInputCheckboxFieldValueOptions = {
/**
* Should we consider the `checked` attribute of checkboxes with no `value` attributes instead of the default value
* "on" when checked?
*
* This forces the field to get the `false` value when unchecked.
*/
booleanValuelessCheckbox?: true,
}

/**
* Options for getting an `<input type="radio">` element field value.
*/
type GetInputRadioFieldValueOptions = {}

/**
* Options for getting an `<input type="file">` element field value.
*/
type GetInputFileFieldValueOptions = {
/**
* Should we retrieve the `files` attribute of file inputs instead of the currently selected file names?
*/
getFileObjects?: true,
}

/**
* Options for getting an `<input>` element field value.
*/
type GetInputFieldValueOptions
= GetInputCheckboxFieldValueOptions
& GetInputFileFieldValueOptions
& GetInputRadioFieldValueOptions

/**
* Options for getting a field value.
*/
type GetFieldValueOptions
= GetTextAreaValueOptions
& GetSelectValueOptions
& GetInputFieldValueOptions

/**
* Options for getting form values.
*/
type GetFormValuesOptions = GetFieldValueOptions & {
/**
* The element that triggered the submission of the form.
*/
submitter?: HTMLSubmitterElement,
}

/**
* Checks if an element can hold a field value.
* @param el - The element.
@@ -123,11 +36,32 @@ export const isFormFieldElement = (el: HTMLElement) => {
return Boolean(inputEl.name)
}

/**
* Options for getting a `<textarea>` element field value.
*/
type GetTextAreaValueOptions = {
/**
* Line ending used for the element's value.
*/
lineEndings?: LineEnding,
}

/**
* Gets the value of a `<textarea>` element.
* @param textareaEl - The element.
* @param options - The options.
* @returns Value of the textarea element.
*/
const getTextAreaFieldValue = (textareaEl: HTMLTextAreaElement, options = {} as GetTextAreaValueOptions) => {
const { lineEndings = LineEnding.CRLF, } = options
return textareaEl.value.replace(/\n/g, lineEndings)
}

/**
* Options for getting a `<select>` element field value.
*/
type GetSelectValueOptions = {}

/**
* Gets the value of a `<select>` element.
* @param selectEl - The element.
@@ -144,20 +78,15 @@ const getSelectFieldValue = (selectEl: HTMLSelectElement, options = {} as GetSel
return selectEl.value
}

/**
* Type for an `<input type="checkbox">` element.
*/
export type HTMLInputCheckboxElement = HTMLInputElement & { type: 'checkbox' }

/**
* Type for an `<input type="radio">` element.
*/
export type HTMLInputRadioElement = HTMLInputElement & { type: 'radio' }

/**
* Type for an `<input type="file">` element.
* Options for getting an `<input type="radio">` element field value.
*/
export type HTMLInputFileElement = HTMLInputElement & { type: 'file' }
type GetInputRadioFieldValueOptions = {}

/**
* Gets the value of an `<input type="radio">` element.
@@ -174,13 +103,35 @@ const getInputRadioFieldValue = (inputEl: HTMLInputRadioElement, options = {} as
}
return null
}

/**
* Type for an `<input type="checkbox">` element.
*/
export type HTMLInputCheckboxElement = HTMLInputElement & { type: 'checkbox' }

/**
* Options for getting an `<input type="checkbox">` element field value.
*/
type GetInputCheckboxFieldValueOptions = {
/**
* Should we consider the `checked` attribute of checkboxes with no `value` attributes instead of the default value
* "on" when checked?
*
* This forces the field to get the `false` value when unchecked.
*/
booleanValuelessCheckbox?: true,
}

/**
* Gets the value of an `<input type="checkbox">` element.
* @param inputEl - The element.
* @param options - The options.
* @returns Value of the input element.
*/
const getInputCheckboxFieldValue = (inputEl: HTMLInputCheckboxElement, options = {} as GetInputCheckboxFieldValueOptions) => {
const getInputCheckboxFieldValue = (
inputEl: HTMLInputCheckboxElement,
options = {} as GetInputCheckboxFieldValueOptions
) => {
const checkedValue = inputEl.getAttribute('value')
if (checkedValue !== null) {
if (inputEl.checked) {
@@ -197,6 +148,21 @@ const getInputCheckboxFieldValue = (inputEl: HTMLInputCheckboxElement, options =
return null
}

/**
* Type for an `<input type="file">` element.
*/
export type HTMLInputFileElement = HTMLInputElement & { type: 'file' }

/**
* Options for getting an `<input type="file">` element field value.
*/
type GetInputFileFieldValueOptions = {
/**
* Should we retrieve the `files` attribute of file inputs instead of the currently selected file names?
*/
getFileObjects?: true,
}

/**
* Gets the value of an `<input type="file">` element.
* @param inputEl - The element.
@@ -204,7 +170,7 @@ const getInputCheckboxFieldValue = (inputEl: HTMLInputCheckboxElement, options =
* @returns Value of the input element.
*/
const getInputFileFieldValue = (inputEl: HTMLInputFileElement, options = {} as GetInputFileFieldValueOptions) => {
const { files } = inputEl
const { files, multiple } = inputEl
if ((files as unknown) === null) {
return null
}
@@ -212,15 +178,20 @@ const getInputFileFieldValue = (inputEl: HTMLInputFileElement, options = {} as G
return files
}
const filesArray = Array.from(files as FileList)
if (filesArray.length > 1) {
if (multiple) {
return filesArray.map(f => f.name)
}
if (filesArray.length === 1) {
return filesArray[0].name
}
return ''
return filesArray[0].name || ''
}

/**
* Options for getting an `<input>` element field value.
*/
type GetInputFieldValueOptions
= GetInputCheckboxFieldValueOptions
& GetInputFileFieldValueOptions
& GetInputRadioFieldValueOptions

/**
* Gets the value of an `<input>` element.
* @param inputEl - The element.
@@ -228,7 +199,7 @@ const getInputFileFieldValue = (inputEl: HTMLInputFileElement, options = {} as G
* @returns Value of the input element.
*/
const getInputFieldValue = (inputEl: HTMLInputElement, options = {} as GetInputFieldValueOptions) => {
switch (inputEl.type) {
switch (inputEl.type.toLowerCase()) {
case 'checkbox':
return getInputCheckboxFieldValue(inputEl as HTMLInputCheckboxElement, options)
case 'radio':
@@ -241,6 +212,14 @@ const getInputFieldValue = (inputEl: HTMLInputElement, options = {} as GetInputF
return inputEl.value
}

/**
* Options for getting a field value.
*/
type GetFieldValueOptions
= GetTextAreaValueOptions
& GetSelectValueOptions
& GetInputFieldValueOptions

/**
* Gets the value of a field element.
* @param el - The field element.
@@ -248,7 +227,7 @@ const getInputFieldValue = (inputEl: HTMLInputElement, options = {} as GetInputF
* @returns Value of the field element.
*/
export const getFieldValue = (el: HTMLElement, options = {} as GetFieldValueOptions) => {
switch (el.tagName) {
switch (el.tagName.toUpperCase()) {
case 'TEXTAREA':
return getTextAreaFieldValue(el as HTMLTextAreaElement, options)
case 'SELECT':
@@ -259,7 +238,7 @@ export const getFieldValue = (el: HTMLElement, options = {} as GetFieldValueOpti
break
}

const fieldEl = el as HTMLFieldElement
const fieldEl = el as HTMLElement & { value?: unknown }
return fieldEl.value || null
}

@@ -280,6 +259,16 @@ export const isNamedEnabledFormFieldElement = (el: HTMLElement) => {
)
}

/**
* Options for getting form values.
*/
type GetFormValuesOptions = GetFieldValueOptions & {
/**
* The element that triggered the submission of the form.
*/
submitter?: HTMLElement,
}

/**
* Gets the values of all the fields within the form through accessing the DOM nodes.
* @param form - The form.
@@ -290,8 +279,8 @@ const getFormValues = (form: HTMLFormElement, options = {} as GetFormValuesOptio
if (!form) {
throw new TypeError('Invalid form element.')
}
const formElements = form.elements as unknown as Record<string | number, HTMLFieldElement>
const allFormFieldElements = Object.entries<HTMLFieldElement>(formElements)
const formElements = form.elements as unknown as Record<string | number, HTMLElement>
const allFormFieldElements = Object.entries<HTMLElement>(formElements)
const indexedNamedEnabledFormFieldElements = allFormFieldElements.filter(([k, el]) => (
!isNaN(Number(k))
&& isNamedEnabledFormFieldElement(el)
@@ -328,7 +317,7 @@ const getFormValues = (form: HTMLFormElement, options = {} as GetFormValuesOptio
{} as any
)
if (Boolean(options.submitter as unknown)) {
const submitter = options.submitter as HTMLSubmitterElement
const submitter = options.submitter as HTMLElement & { name: string, value: unknown }
if (submitter.name.length > 0) {
return {
...fieldValues,


Loading…
Cancel
Save