about summary refs log tree commit diff stats
path: root/src/html
diff options
context:
space:
mode:
Diffstat (limited to 'src/html')
-rw-r--r--src/html/dom.nim57
-rw-r--r--src/html/enums.nim12
-rw-r--r--src/html/formdata.nim22
3 files changed, 40 insertions, 51 deletions
diff --git a/src/html/dom.nim b/src/html/dom.nim
index 5daba32e..3e93de79 100644
--- a/src/html/dom.nim
+++ b/src/html/dom.nim
@@ -51,7 +51,9 @@ import chame/tags
 
 type
   FormMethod* = enum
-    fmGet, fmPost, fmDialog
+    fmGet = "get"
+    fmPost = "post"
+    fmDialog = "dialog"
 
   FormEncodingType* = enum
     fetUrlencoded = "application/x-www-form-urlencoded",
@@ -245,7 +247,7 @@ type
     checked* {.jsget.}: bool
     xcoord*: int
     ycoord*: int
-    file*: Option[URL]
+    file*: WebFile
 
   HTMLAnchorElement* = ref object of HTMLElement
     relList {.jsget.}: DOMTokenList
@@ -281,7 +283,6 @@ type
     fetchStarted: bool
 
   HTMLFormElement* = ref object of HTMLElement
-    enctype*: string
     constructingEntryList*: bool
     controls*: seq[FormAssociatedElement]
     relList {.jsget.}: DOMTokenList
@@ -2231,19 +2232,18 @@ func inputString*(input: HTMLInputElement): string =
   of itPassword:
     '*'.repeat(input.value.len).padToWidth(int(input.attrulgz(satSize).get(20)))
   of itReset:
-    if input.value != "": input.value
-    else: "RESET"
+    if input.value != "":
+      input.value
+    else:
+      "RESET"
   of itSubmit, itButton:
     if input.value != "":
       input.value
     else:
       "SUBMIT"
   of itFile:
-    if input.file.isNone:
-      "".padToWidth(int(input.attrulgz(satSize).get(20)))
-    else:
-      input.file.get.path.serialize_unicode()
-        .padToWidth(int(input.attrulgz(satSize).get(20)))
+    let s = if input.file != nil: input.file.name else: ""
+    s.padToWidth(int(input.attrulgz(satSize).get(20)))
   else: input.value
 
 func textAreaString*(textarea: HTMLTextAreaElement): string =
@@ -2281,30 +2281,25 @@ func action*(element: Element): string =
   return ""
 
 func enctype*(element: Element): FormEncodingType =
+  if element of HTMLFormElement:
+    # Note: see below, this is not in the standard.
+    if element.attrb(satEnctype):
+      let s = element.attr(satEnctype)
+      return parseEnumNoCase[FormEncodingType](s).get(fetUrlencoded)
   if element.isSubmitButton():
     if element.attrb(satFormenctype):
-      return case element.attr(satFormenctype).toLowerAscii()
-      of "application/x-www-form-urlencoded": fetUrlencoded
-      of "multipart/form-data": fetMultipart
-      of "text/plain": fetTextPlain
-      else: fetUrlencoded
-  if element of HTMLInputElement:
-    let element = HTMLInputElement(element)
-    if element.form != nil:
-      if element.form.attrb(satEnctype):
-        return case element.attr(satEnctype).toLowerAscii()
-        of "application/x-www-form-urlencoded": fetUrlencoded
-        of "multipart/form-data": fetMultipart
-        of "text/plain": fetTextPlain
-        else: fetUrlencoded
+      let s = element.attr(satFormenctype)
+      return parseEnumNoCase[FormEncodingType](s).get(fetUrlencoded)
+  if element of FormAssociatedElement:
+    let element = FormAssociatedElement(element)
+    if (let form = element.form; form != nil):
+      if form.attrb(satEnctype):
+        let s = form.attr(satEnctype)
+        return parseEnumNoCase[FormEncodingType](s).get(fetUrlencoded)
   return fetUrlencoded
 
 func parseFormMethod(s: string): FormMethod =
-  return case s.toLowerAscii()
-  of "get": fmGet
-  of "post": fmPost
-  of "dialog": fmDialog
-  else: fmGet
+  return parseEnumNoCase[FormMethod](s).get(fmGet)
 
 func formmethod*(element: Element): FormMethod =
   if element of HTMLFormElement:
@@ -2951,7 +2946,7 @@ proc reflectAttrs(element: Element; name: CAtom; value: string) =
     input.reflect_str satValue, value
     input.reflect_bool satChecked, checked
     if name == satType:
-      input.inputType = inputType(value)
+      input.inputType = parseEnumNoCase[InputType](value).get(itText)
   of TAG_OPTION:
     let option = HTMLOptionElement(element)
     option.reflect_bool satSelected, selected
@@ -3223,7 +3218,7 @@ proc resetElement*(element: Element) =
     of itCheckbox, itRadio:
       input.checked = input.attrb(satChecked)
     of itFile:
-      input.file = none(URL)
+      input.file = nil
     else:
       input.value = input.attr(satValue)
     input.invalid = true
diff --git a/src/html/enums.nim b/src/html/enums.nim
index 925e3b68..119a9a9b 100644
--- a/src/html/enums.nim
+++ b/src/html/enums.nim
@@ -1,6 +1,3 @@
-import std/strutils
-import std/tables
-
 import chame/tags
 
 type
@@ -71,15 +68,6 @@ const ResettableElements* = {
   TAG_INPUT, TAG_OUTPUT, TAG_SELECT, TAG_TEXTAREA
 }
 
-func getInputTypeMap(): Table[string, InputType] =
-  for i in InputType:
-    result[$InputType(i)] = InputType(i)
-
-const inputTypeMap = getInputTypeMap()
-
-func inputType*(s: string): InputType =
-  return inputTypeMap.getOrDefault(s.toLowerAscii())
-
 const AutoDirInput* = {
   itHidden, itText, itSearch, itTel, itURL, itEmail, itPassword, itSubmit,
   itReset, itButton
diff --git a/src/html/formdata.nim b/src/html/formdata.nim
index 335e36b6..7f099acd 100644
--- a/src/html/formdata.nim
+++ b/src/html/formdata.nim
@@ -1,8 +1,8 @@
-import std/streams
-
 import html/catom
 import html/dom
 import html/enums
+import io/dynstream
+import io/posixstream
 import js/base64
 import js/domexception
 import js/javascript
@@ -16,11 +16,12 @@ import chame/tags
 proc constructEntryList*(form: HTMLFormElement; submitter: Element = nil;
     encoding = "UTF-8"): seq[FormDataEntry]
 
+var urandom* {.global.}: PosixStream
+
 proc generateBoundary(): string =
-  let urandom = newFileStream("/dev/urandom")
-  let s = urandom.readStr(32)
-  urandom.close()
-  # 32 * 4 / 3 (padded) = 44 + prefix string is 22 bytes = 66 bytes
+  var s: array[33, uint8]
+  urandom.recvDataLoop(s)
+  # 33 * 4 / 3 = 44 + prefix string is 22 bytes = 66 bytes
   return "----WebKitFormBoundary" & btoa(s)
 
 proc newFormData0*(): FormData =
@@ -147,8 +148,13 @@ proc constructEntryList*(form: HTMLFormElement; submitter: Element = nil;
           "on"
         entrylist.add((name, value))
       of itFile:
-        #TODO file
-        discard
+        if field.file != nil:
+          entrylist.add(FormDataEntry(
+            name: name,
+            filename: field.file.name,
+            isstr: false,
+            value: field.file
+          ))
       of itHidden:
         if name.equalsIgnoreCase("_charset_"):
           entrylist.add((name, encoding))