about summary refs log tree commit diff stats
path: root/src/html
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2024-04-21 20:19:39 +0200
committerbptato <nincsnevem662@gmail.com>2024-04-21 20:19:39 +0200
commit39ea6e0bff8b5f3bfb564846f7a123067af92d6f (patch)
tree842c3b203623e12df926a613baab3791f7657678 /src/html
parent470aeef2d72614cb8f904d8ef19583312410d981 (diff)
downloadchawan-39ea6e0bff8b5f3bfb564846f7a123067af92d6f.tar.gz
dom: fix property event handler setters
Diffstat (limited to 'src/html')
-rw-r--r--src/html/dom.nim65
-rw-r--r--src/html/env.nim10
2 files changed, 52 insertions, 23 deletions
diff --git a/src/html/dom.nim b/src/html/dom.nim
index 8767ac6e..bedde23b 100644
--- a/src/html/dom.nim
+++ b/src/html/dom.nim
@@ -714,17 +714,19 @@ proc roundRect(ctx: CanvasRenderingContext2D; x, y, w, h, radii: float64)
 # Reflected attributes.
 type
   ReflectType = enum
-    REFLECT_STR, REFLECT_BOOL, REFLECT_LONG, REFLECT_ULONG_GZ, REFLECT_ULONG
+    rtStr, rtBool, rtLong, rtUlongGz, rtUlong, rtFunction
 
   ReflectEntry = object
     attrname: StaticAtom
     funcname: string
     tags: set[TagType]
     case t: ReflectType
-    of REFLECT_LONG:
+    of rtLong:
       i: int32
-    of REFLECT_ULONG, REFLECT_ULONG_GZ:
+    of rtUlong, rtUlongGz:
       u: uint32
+    of rtFunction:
+      ctype: string
     else: discard
 
 func attrType0(s: static string): StaticAtom =
@@ -741,7 +743,7 @@ func makes(name: static string; ts: set[TagType]): ReflectEntry =
   ReflectEntry(
     attrname: attrname,
     funcname: name,
-    t: REFLECT_STR,
+    t: rtStr,
     tags: ts
   )
 
@@ -751,7 +753,7 @@ func makes(attrname, funcname: static string; ts: set[TagType]):
   ReflectEntry(
     attrname: attrname,
     funcname: funcname,
-    t: REFLECT_STR,
+    t: rtStr,
     tags: ts
   )
 
@@ -768,7 +770,7 @@ func makeb(attrname, funcname: static string; ts: varargs[TagType]):
   ReflectEntry(
     attrname: attrname,
     funcname: funcname,
-    t: REFLECT_BOOL,
+    t: rtBool,
     tags: toset(ts)
   )
 
@@ -781,22 +783,32 @@ func makeul(name: static string; ts: varargs[TagType]; default = 0u32):
   ReflectEntry(
     attrname: attrname,
     funcname: name,
-    t: REFLECT_ULONG,
+    t: rtUlong,
     tags: toset(ts),
     u: default
   )
 
-func makeulgz(name: static string; ts: varargs[TagType], default = 0u32):
+func makeulgz(name: static string; ts: varargs[TagType]; default = 0u32):
     ReflectEntry =
   const attrname = attrType0(name)
   ReflectEntry(
     attrname: attrname,
     funcname: name,
-    t: REFLECT_ULONG_GZ,
+    t: rtUlongGz,
     tags: toset(ts),
     u: default
   )
 
+func makef(name: static string; ts: set[TagType]; ctype: string): ReflectEntry =
+  const attrname = attrType0(name)
+  ReflectEntry(
+    attrname: attrname,
+    funcname: name,
+    t: rtFunction,
+    tags: ts,
+    ctype: ctype
+  )
+
 const ReflectTable0 = [
   # non-global attributes
   makes("target", TAG_A, TAG_AREA, TAG_LABEL, TAG_LINK),
@@ -824,7 +836,8 @@ const ReflectTable0 = [
   makeb("ismap", "isMap", TAG_IMG),
   # "super-global" attributes
   makes("slot", AllTagTypes),
-  makes("class", "className", AllTagTypes)
+  makes("class", "className", AllTagTypes),
+  makef("onclick", AllTagTypes, "click"),
 ]
 
 # Forward declarations
@@ -4043,17 +4056,19 @@ proc jsReflectGet(ctx: JSContext; this: JSValue; magic: cint): JSValue
   if element.tagType notin entry.tags:
     return JS_ThrowTypeError(ctx, "Invalid tag type %s", element.tagType)
   case entry.t
-  of REFLECT_STR:
+  of rtStr:
     let x = toJS(ctx, element.attr(entry.attrname))
     return x
-  of REFLECT_BOOL:
+  of rtBool:
     return toJS(ctx, element.attrb(entry.attrname))
-  of REFLECT_LONG:
+  of rtLong:
     return toJS(ctx, element.attrl(entry.attrname).get(entry.i))
-  of REFLECT_ULONG:
+  of rtUlong:
     return toJS(ctx, element.attrul(entry.attrname).get(entry.u))
-  of REFLECT_ULONG_GZ:
+  of rtUlongGz:
     return toJS(ctx, element.attrulgz(entry.attrname).get(entry.u))
+  of rtFunction:
+    return JS_GetPropertyStr(ctx, this, cstring($entry.attrname))
 
 proc jsReflectSet(ctx: JSContext; this, val: JSValue; magic: cint): JSValue
     {.cdecl.} =
@@ -4067,11 +4082,11 @@ proc jsReflectSet(ctx: JSContext; this, val: JSValue; magic: cint): JSValue
   if element.tagType notin entry.tags:
     return JS_ThrowTypeError(ctx, "Invalid tag type %s", element.tagType)
   case entry.t
-  of REFLECT_STR:
+  of rtStr:
     let x = fromJS[string](ctx, val)
     if x.isSome:
       element.attr(entry.attrname, x.get)
-  of REFLECT_BOOL:
+  of rtBool:
     let x = fromJS[bool](ctx, val)
     if x.isSome:
       if x.get:
@@ -4080,18 +4095,24 @@ proc jsReflectSet(ctx: JSContext; this, val: JSValue; magic: cint): JSValue
         let i = element.findAttr(entry.attrname)
         if i != -1:
           element.delAttr(i)
-  of REFLECT_LONG:
+  of rtLong:
     let x = fromJS[int32](ctx, val)
     if x.isSome:
       element.attrl(entry.attrname, x.get)
-  of REFLECT_ULONG:
+  of rtUlong:
     let x = fromJS[uint32](ctx, val)
     if x.isSome:
       element.attrul(entry.attrname, x.get)
-  of REFLECT_ULONG_GZ:
+  of rtUlongGz:
     let x = fromJS[uint32](ctx, val)
     if x.isSome:
       element.attrulgz(entry.attrname, x.get)
+  of rtFunction:
+    if JS_IsFunction(ctx, val):
+      let target = fromJS[EventTarget](ctx, this).get
+      ctx.definePropertyC(this, $entry.attrname, JS_DupValue(ctx, val))
+      #TODO I haven't checked but this might also be wrong
+      doAssert ctx.addEventListener(target, entry.ctype, val).isOk
   return JS_DupValue(ctx, val)
 
 func getReflectFunctions(tags: set[TagType]): seq[TabGetSet] =
@@ -4108,8 +4129,7 @@ func getReflectFunctions(tags: set[TagType]): seq[TabGetSet] =
 
 func getElementReflectFunctions(): seq[TabGetSet] =
   result = @[]
-  var i: int16 = ReflectAllStartIndex
-  while i < int16(ReflectTable.len):
+  for i in ReflectAllStartIndex ..< int16(ReflectTable.len):
     let entry = ReflectTable[i]
     assert entry.tags == AllTagTypes
     result.add(TabGetSet(
@@ -4118,7 +4138,6 @@ func getElementReflectFunctions(): seq[TabGetSet] =
       set: jsReflectSet,
       magic: i
     ))
-    inc i
 
 proc getContext*(jctx: JSContext; this: HTMLCanvasElement; contextId: string;
     options = none(JSValue)): RenderingContext {.jsfunc.} =
diff --git a/src/html/env.nim b/src/html/env.nim
index 2d5743ed..c9d99dc2 100644
--- a/src/html/env.nim
+++ b/src/html/env.nim
@@ -19,6 +19,7 @@ import js/intl
 import js/javascript
 import js/jstypes
 import js/timeout
+import js/tojs
 import loader/headers
 import loader/loader
 import loader/request
@@ -160,6 +161,15 @@ proc getComputedStyle(window: Window; element: Element;
   #TODO implement this properly
   return ok(element.style)
 
+proc setOnLoad(ctx: JSContext; window: Window; val: JSValue)
+    {.jsfset: "onload".} =
+  if JS_IsFunction(ctx, val):
+    let this = ctx.toJS(window)
+    ctx.definePropertyC(this, "onload", JS_DupValue(ctx, val))
+    #TODO I haven't checked but this might also be wrong
+    doAssert ctx.addEventListener(window, "load", val).isOk
+    JS_FreeValue(ctx, this)
+
 proc addScripting*(window: Window; selector: Selector[int]) =
   let rt = newJSRuntime()
   let ctx = rt.newJSContext()