about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2025-01-01 15:35:12 +0100
committerbptato <nincsnevem662@gmail.com>2025-01-01 15:35:12 +0100
commit36cb127b7eef0312b3cd67b9bbb588047b0a1d14 (patch)
tree6a7d894380625b9a54cd1fb194320e244b89adcb /src
parentd94270baf61881af500c4ebf498708aad5835040 (diff)
downloadchawan-36cb127b7eef0312b3cd67b9bbb588047b0a1d14.tar.gz
dom: add cookie setter stub, HTMLSelectElement stuff
Diffstat (limited to 'src')
-rw-r--r--src/html/dom.nim87
1 files changed, 68 insertions, 19 deletions
diff --git a/src/html/dom.nim b/src/html/dom.nim
index 5e0b6534..06193a98 100644
--- a/src/html/dom.nim
+++ b/src/html/dom.nim
@@ -217,6 +217,8 @@ type
     cachedForms: HTMLCollection
     parser*: RootRef
 
+    internalCookie: string
+
   CharacterData* = ref object of Node
     data* {.jsget.}: string
 
@@ -297,7 +299,6 @@ type
 
   HTMLSelectElement* = ref object of FormAssociatedElement
     cachedOptions: HTMLOptionsCollection
-    cachedSelectedOptions: HTMLCollection
 
   HTMLSpanElement* = ref object of HTMLElement
 
@@ -305,6 +306,7 @@ type
 
   HTMLOptionElement* = ref object of HTMLElement
     selected*: bool
+    dirty: bool
 
   HTMLHeadingElement* = ref object of HTMLElement
 
@@ -485,15 +487,16 @@ jsDestructor(CSSStyleDeclaration)
 # Forward declarations
 func attr*(element: Element; s: StaticAtom): string
 func attrb*(element: Element; s: CAtom): bool
-proc baseURL*(document: Document): URL
+func value*(option: HTMLOptionElement): string
 proc attr*(element: Element; name: CAtom; value: string)
 proc attr*(element: Element; name: StaticAtom; value: string)
+proc baseURL*(document: Document): URL
 proc delAttr(element: Element; i: int; keep = false)
 proc getImageId(window: Window): int
+proc invalidateCollections(node: Node)
 proc parseColor(element: Element; s: string): ARGBColor
 proc reflectAttr(element: Element; name: CAtom; value: Option[string])
 proc setInvalid*(element: Element)
-func value*(option: HTMLOptionElement): string
 
 # Forward declaration hacks
 # set in css/cascade
@@ -1446,8 +1449,12 @@ func forms(document: Document): HTMLCollection {.jsfget.} =
     )
   return document.cachedForms
 
-func cookie(document: Document): string {.jsfget.} =
-  return ""
+func cookie(ctx: JSContext; document: Document): string {.jsfget.} =
+  return document.internalCookie
+
+proc setCookie(ctx: JSContext; document: Document; cookie: string)
+    {.jsfset: "cookie".} =
+  document.internalCookie = cookie
 
 # DOMTokenList
 func length(tokenList: DOMTokenList): uint32 {.jsfget.} =
@@ -2956,24 +2963,66 @@ proc item(this: HTMLSelectElement; u: uint32): Node {.jsfunc.} =
 func namedItem(this: HTMLSelectElement; atom: CAtom): Element {.jsfunc.} =
   return this.jsOptions.namedItem(atom)
 
-proc selectedOptions(this: HTMLSelectElement): HTMLCollection {.jsfget.} =
-  if this.cachedSelectedOptions == nil:
-    this.cachedSelectedOptions = newCollection[HTMLCollection](
-      root = this,
-      match = func(node: Node): bool =
-        return node.isOptionOf(this) and HTMLOptionElement(node).selected,
-      islive = true,
-      childonly = false
-    )
-  return this.cachedSelectedOptions
+proc selectedOptions(ctx: JSContext; this: HTMLSelectElement): JSValue
+    {.jsfget.} =
+  let selectedOptions = ctx.toJS(newCollection[HTMLCollection](
+    root = this,
+    match = func(node: Node): bool =
+      return node.isOptionOf(this) and HTMLOptionElement(node).selected,
+    islive = true,
+    childonly = false
+  ))
+  let this = ctx.toJS(this)
+  ctx.definePropertyCW(this, "selectedOptions",
+    JS_DupValue(ctx, selectedOptions))
+  JS_FreeValue(ctx, this)
+  return selectedOptions
+
+proc selectedIndex(this: HTMLSelectElement): int {.jsfget.} =
+  var i = 0
+  for it in this.options:
+    if it.selected:
+      return i
+    inc i
+  return -1
+
+proc setSelectedIndex(this: HTMLSelectElement; n: int)
+    {.jsfset: "selectedIndex".} =
+  var i = 0
+  for it in this.options:
+    if i == n:
+      it.selected = true
+      it.dirty = true
+    else:
+      it.selected = false
+    it.invalidateCollections()
+    inc i
 
 proc value(this: HTMLSelectElement): string {.jsfget.} =
-  let first = this.selectedOptions.item(0)
-  if first != nil:
-    return HTMLOptionElement(first).value
+  for it in this.options:
+    if it.selected:
+      return it.value
   return ""
 
-#TODO add, selectedIndex, value setter, showPicker
+proc setValue(this: HTMLSelectElement; value: string) {.jsfset: "value".} =
+  var found = false
+  for it in this.options:
+    if not found and it.value == value:
+      found = true
+      it.selected = true
+      it.dirty = true
+    else:
+      it.selected = false
+    it.invalidateCollections()
+
+proc showPicker(this: HTMLSelectElement): Err[DOMException] {.jsfunc.} =
+  # Per spec, we should do something if it's being rendered and on
+  # transient user activation.
+  # If this is ever implemented, then the "is rendered" check must
+  # be app mode only.
+  return errDOMException("not allowed", "NotAllowedError")
+
+#TODO add, remove
 
 # <button>
 func jsForm(this: HTMLButtonElement): HTMLFormElement {.jsfget: "form".} =