summaryrefslogtreecommitdiff
path: root/cli/js/form_data.ts
diff options
context:
space:
mode:
Diffstat (limited to 'cli/js/form_data.ts')
-rw-r--r--cli/js/form_data.ts149
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) {}