about summary refs log tree commit diff stats
path: root/src/html
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2024-03-24 11:49:28 +0100
committerbptato <nincsnevem662@gmail.com>2024-03-24 11:51:16 +0100
commit64d80e44c3c2f0cdd51632757bab8158b314a413 (patch)
tree8b98b62be8fc7eead6d93799163795a53210adce /src/html
parent03d591d9aed833b0bdb028bfea376e0beeac8e9a (diff)
downloadchawan-64d80e44c3c2f0cdd51632757bab8158b314a413.tar.gz
buffer: form fixes & improvements
* fall back to text for unimplemented input types
* add custom prompt to all text-like input types
* show min/max for range
* fix accidental override of repaint
Diffstat (limited to 'src/html')
-rw-r--r--src/html/catom.nim2
-rw-r--r--src/html/dom.nim46
-rw-r--r--src/html/enums.nim39
-rw-r--r--src/html/formdata.nim12
4 files changed, 58 insertions, 41 deletions
diff --git a/src/html/catom.nim b/src/html/catom.nim
index 5e5f6174..5a05ffab 100644
--- a/src/html/catom.nim
+++ b/src/html/catom.nim
@@ -42,8 +42,10 @@ macro makeStaticAtom =
       satIntegrity = "integrity"
       satIsmap = "ismap"
       satLanguage = "language"
+      satMax = "max",
       satMedia = "media"
       satMethod = "method"
+      satMin = "min",
       satMultiple = "multiple"
       satName = "name"
       satNomodule = "nomodule"
diff --git a/src/html/dom.nim b/src/html/dom.nim
index 692a80de..41869a95 100644
--- a/src/html/dom.nim
+++ b/src/html/dom.nim
@@ -1008,13 +1008,13 @@ iterator inputs(form: HTMLFormElement): HTMLInputElement {.inline.} =
 
 iterator radiogroup(form: HTMLFormElement): HTMLInputElement {.inline.} =
   for input in form.inputs:
-    if input.inputType == INPUT_RADIO:
+    if input.inputType == itRadio:
       yield input
 
 iterator radiogroup(document: Document): HTMLInputElement {.inline.} =
   for input in document.elements(TAG_INPUT):
     let input = HTMLInputElement(input)
-    if input.form == nil and input.inputType == INPUT_RADIO:
+    if input.form == nil and input.inputType == itRadio:
       yield input
 
 iterator radiogroup*(input: HTMLInputElement): HTMLInputElement {.inline.} =
@@ -1764,14 +1764,13 @@ func isSubmitButton*(element: Element): bool =
     return element.attr(satType) == "submit"
   elif element of HTMLInputElement:
     let element = HTMLInputElement(element)
-    return element.inputType in {INPUT_SUBMIT, INPUT_IMAGE}
+    return element.inputType in {itSubmit, itImage}
   return false
 
 func canSubmitImplicitly*(form: HTMLFormElement): bool =
   const BlocksImplicitSubmission = {
-    INPUT_TEXT, INPUT_SEARCH, INPUT_URL, INPUT_TEL, INPUT_EMAIL, INPUT_PASSWORD,
-    INPUT_DATE, INPUT_MONTH, INPUT_WEEK, INPUT_TIME, INPUT_DATETIME_LOCAL,
-    INPUT_NUMBER
+    itText, itSearch, itURL, itTel, itEmail, itPassword, itDate, itMonth,
+    itWeek, itTime, itDatetimeLocal, itNumber
   }
   var found = false
   for control in form.controls:
@@ -2197,20 +2196,24 @@ proc sheets*(document: Document): seq[CSSStylesheet] =
 
 func inputString*(input: HTMLInputElement): string =
   case input.inputType
-  of INPUT_CHECKBOX, INPUT_RADIO:
-    if input.checked: "*"
-    else: " "
-  of INPUT_SEARCH, INPUT_TEXT, INPUT_EMAIL, INPUT_URL, INPUT_TEL:
+  of itCheckbox, itRadio:
+    if input.checked:
+      "*"
+    else:
+      " "
+  of itSearch, itText, itEmail, itURL, itTel:
     input.value.padToWidth(int(input.attrulgz(satSize).get(20)))
-  of INPUT_PASSWORD:
+  of itPassword:
     '*'.repeat(input.value.len).padToWidth(int(input.attrulgz(satSize).get(20)))
-  of INPUT_RESET:
+  of itReset:
     if input.value != "": input.value
     else: "RESET"
-  of INPUT_SUBMIT, INPUT_BUTTON:
-    if input.value != "": input.value
-    else: "SUBMIT"
-  of INPUT_FILE:
+  of itSubmit, itButton:
+    if input.value != "":
+      input.value
+    else:
+      "SUBMIT"
+  of itFile:
     if input.file.isNone:
       "".padToWidth(int(input.attrulgz(satSize).get(20)))
     else:
@@ -2236,7 +2239,7 @@ func isButton*(element: Element): bool =
     return true
   if element of HTMLInputElement:
     let element = HTMLInputElement(element)
-    return element.inputType in {INPUT_SUBMIT, INPUT_BUTTON, INPUT_RESET, INPUT_IMAGE}
+    return element.inputType in {itSubmit, itButton, itReset, itImage}
   return false
 
 func action*(element: Element): string =
@@ -3148,13 +3151,12 @@ proc resetElement*(element: Element) =
   of TAG_INPUT:
     let input = HTMLInputElement(element)
     case input.inputType
-    of INPUT_SEARCH, INPUT_TEXT, INPUT_PASSWORD:
-      input.value = input.attr(satValue)
-    of INPUT_CHECKBOX, INPUT_RADIO:
+    of itCheckbox, itRadio:
       input.checked = input.attrb(satChecked)
-    of INPUT_FILE:
+    of itFile:
       input.file = none(URL)
-    else: discard
+    else:
+      input.value = input.attr(satValue)
     input.invalid = true
   of TAG_SELECT:
     let select = HTMLSelectElement(element)
diff --git a/src/html/enums.nim b/src/html/enums.nim
index 856b7813..1cac0742 100644
--- a/src/html/enums.nim
+++ b/src/html/enums.nim
@@ -1,17 +1,32 @@
 import std/strutils
 import std/tables
 
-import utils/twtstr
-
 import chame/tags
 
 type
   InputType* = enum
-    INPUT_TEXT, INPUT_BUTTON, INPUT_CHECKBOX, INPUT_COLOR, INPUT_DATE,
-    INPUT_DATETIME_LOCAL, INPUT_EMAIL, INPUT_FILE, INPUT_HIDDEN, INPUT_IMAGE,
-    INPUT_MONTH, INPUT_NUMBER, INPUT_PASSWORD, INPUT_RADIO, INPUT_RANGE,
-    INPUT_RESET, INPUT_SEARCH, INPUT_SUBMIT, INPUT_TEL, INPUT_TIME, INPUT_URL,
-    INPUT_WEEK
+    itText = "text"
+    itButton = "button"
+    itCheckbox = "checkbox"
+    itColor = "color"
+    itDate = "date"
+    itDatetimeLocal = "datetime-local"
+    itEmail = "email"
+    itFile = "file"
+    itHidden = "hidden"
+    itImage = "image"
+    itMonth = "month"
+    itNumber = "number"
+    itPassword = "password"
+    itRadio = "radio"
+    itRange = "range"
+    itReset = "reset"
+    itSearch = "search"
+    itSubmit = "submit"
+    itTel = "tel"
+    itTime = "time"
+    itURL = "url"
+    itWeek = "week"
 
   ButtonType* = enum
     BUTTON_SUBMIT, BUTTON_RESET, BUTTON_BUTTON
@@ -31,7 +46,7 @@ type
     NOTATION_NODE = 12
 
 const InputTypeWithSize* = {
-  INPUT_SEARCH, INPUT_TEXT, INPUT_EMAIL, INPUT_PASSWORD, INPUT_URL, INPUT_TEL
+  itSearch, itText, itEmail, itPassword, itURL, itTel
 }
 
 const AutocapitalizeInheritingElements* = {
@@ -56,9 +71,7 @@ const ResettableElements* = {
 
 func getInputTypeMap(): Table[string, InputType] =
   for i in InputType:
-    let enumname = $InputType(i)
-    let tagname = enumname.split('_')[1..^1].join('_').toLowerAscii()
-    result[tagname] = InputType(i)
+    result[$InputType(i)] = InputType(i)
 
 const inputTypeMap = getInputTypeMap()
 
@@ -66,6 +79,6 @@ func inputType*(s: string): InputType =
   return inputTypeMap.getOrDefault(s.toLowerAscii())
 
 const AutoDirInput* = {
-  INPUT_HIDDEN, INPUT_TEXT, INPUT_SEARCH, INPUT_TEL, INPUT_URL, INPUT_EMAIL,
-  INPUT_PASSWORD, INPUT_SUBMIT, INPUT_RESET, INPUT_BUTTON
+  itHidden, itText, itSearch, itTel, itURL, itEmail, itPassword, itSubmit,
+  itReset, itButton
 }
diff --git a/src/html/formdata.nim b/src/html/formdata.nim
index cfdf6dce..d34b0194 100644
--- a/src/html/formdata.nim
+++ b/src/html/formdata.nim
@@ -106,7 +106,7 @@ func toNameValuePairs*(list: seq[FormDataEntry]):
 # https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#constructing-the-form-data-set
 # Warning: we skip the first "constructing entry list" check; the caller must
 # do it.
-proc constructEntryList*(form: HTMLFormElement, submitter: Element = nil,
+proc constructEntryList*(form: HTMLFormElement; submitter: Element = nil;
     encoding = "UTF-8"): seq[FormDataEntry] =
   assert not form.constructingEntryList
   form.constructingEntryList = true
@@ -118,9 +118,9 @@ proc constructEntryList*(form: HTMLFormElement, submitter: Element = nil,
       continue
     if field of HTMLInputElement:
       let field = HTMLInputElement(field)
-      if field.inputType in {INPUT_CHECKBOX, INPUT_RADIO} and not field.checked:
+      if field.inputType in {itCheckbox, itRadio} and not field.checked:
         continue
-      if field.inputType == INPUT_IMAGE:
+      if field.inputType == itImage:
         var name = field.attr(satName)
         if name != "":
           name &= '.'
@@ -139,17 +139,17 @@ proc constructEntryList*(form: HTMLFormElement, submitter: Element = nil,
     elif field of HTMLInputElement:
       let field = HTMLInputElement(field)
       case field.inputType
-      of INPUT_CHECKBOX, INPUT_RADIO:
+      of itCheckbox, itRadio:
         let v = field.attr(satValue)
         let value = if v != "":
           v
         else:
           "on"
         entrylist.add((name, value))
-      of INPUT_FILE:
+      of itFile:
         #TODO file
         discard
-      of INPUT_HIDDEN:
+      of itHidden:
         if name.equalsIgnoreCase("_charset_"):
           entrylist.add((name, encoding))
         else: