diff options
Diffstat (limited to 'cli/js/form_data.ts')
-rw-r--r-- | cli/js/form_data.ts | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/cli/js/form_data.ts b/cli/js/form_data.ts new file mode 100644 index 000000000..89efb3c00 --- /dev/null +++ b/cli/js/form_data.ts @@ -0,0 +1,149 @@ +// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. +import * as domTypes from "./dom_types.ts"; +import * as blob from "./blob.ts"; +import * as domFile from "./dom_file.ts"; +import { DomIterableMixin } from "./mixins/dom_iterable.ts"; +import { requiredArguments } from "./util.ts"; + +const dataSymbol = Symbol("data"); + +class FormDataBase { + private [dataSymbol]: Array<[string, domTypes.FormDataEntryValue]> = []; + + /** Appends a new value onto an existing key inside a `FormData` + * object, or adds the key if it does not already exist. + * + * formData.append('name', 'first'); + * formData.append('name', 'second'); + */ + append(name: string, value: string): void; + append(name: string, value: blob.DenoBlob, filename?: string): void; + append(name: string, value: string | blob.DenoBlob, filename?: string): void { + requiredArguments("FormData.append", arguments.length, 2); + name = String(name); + if (value instanceof blob.DenoBlob) { + const dfile = new domFile.DomFileImpl([value], filename || name); + this[dataSymbol].push([name, dfile]); + } else { + this[dataSymbol].push([name, String(value)]); + } + } + + /** Deletes a key/value pair from a `FormData` object. + * + * formData.delete('name'); + */ + delete(name: string): void { + requiredArguments("FormData.delete", arguments.length, 1); + name = String(name); + let i = 0; + while (i < this[dataSymbol].length) { + if (this[dataSymbol][i][0] === name) { + this[dataSymbol].splice(i, 1); + } else { + i++; + } + } + } + + /** Returns an array of all the values associated with a given key + * from within a `FormData`. + * + * formData.getAll('name'); + */ + getAll(name: string): domTypes.FormDataEntryValue[] { + requiredArguments("FormData.getAll", arguments.length, 1); + name = String(name); + const values = []; + for (const entry of this[dataSymbol]) { + if (entry[0] === name) { + values.push(entry[1]); + } + } + + return values; + } + + /** Returns the first value associated with a given key from within a + * `FormData` object. + * + * formData.get('name'); + */ + get(name: string): domTypes.FormDataEntryValue | null { + requiredArguments("FormData.get", arguments.length, 1); + name = String(name); + for (const entry of this[dataSymbol]) { + if (entry[0] === name) { + return entry[1]; + } + } + + return null; + } + + /** Returns a boolean stating whether a `FormData` object contains a + * certain key/value pair. + * + * formData.has('name'); + */ + has(name: string): boolean { + requiredArguments("FormData.has", arguments.length, 1); + name = String(name); + return this[dataSymbol].some((entry): boolean => entry[0] === name); + } + + /** Sets a new value for an existing key inside a `FormData` object, or + * adds the key/value if it does not already exist. + * ref: https://xhr.spec.whatwg.org/#dom-formdata-set + * + * formData.set('name', 'value'); + */ + set(name: string, value: string): void; + set(name: string, value: blob.DenoBlob, filename?: string): void; + set(name: string, value: string | blob.DenoBlob, filename?: string): void { + requiredArguments("FormData.set", arguments.length, 2); + name = String(name); + + // If there are any entries in the context object’s entry list whose name + // is name, replace the first such entry with entry and remove the others + let found = false; + let i = 0; + while (i < this[dataSymbol].length) { + if (this[dataSymbol][i][0] === name) { + if (!found) { + if (value instanceof blob.DenoBlob) { + const dfile = new domFile.DomFileImpl([value], filename || name); + this[dataSymbol][i][1] = dfile; + } else { + this[dataSymbol][i][1] = String(value); + } + found = true; + } else { + this[dataSymbol].splice(i, 1); + continue; + } + } + i++; + } + + // Otherwise, append entry to the context object’s entry list. + if (!found) { + if (value instanceof blob.DenoBlob) { + const dfile = new domFile.DomFileImpl([value], filename || name); + this[dataSymbol].push([name, dfile]); + } else { + this[dataSymbol].push([name, String(value)]); + } + } + } + + get [Symbol.toStringTag](): string { + return "FormData"; + } +} + +export class FormData extends DomIterableMixin< + string, + domTypes.FormDataEntryValue, + typeof FormDataBase +>(FormDataBase, dataSymbol) {} |