about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2024-11-19 00:10:47 +0100
committerbptato <nincsnevem662@gmail.com>2024-11-19 00:10:47 +0100
commit15b0afc98c0cfb685379b3680552bbe5d0f7a003 (patch)
tree19c5702008c0b397966f8f39c16c265c07b9773e /src
parente05761118941bdf729facde4838b7dddb255b818 (diff)
downloadchawan-15b0afc98c0cfb685379b3680552bbe5d0f7a003.tar.gz
dom: add HTMLHyperlinkElementUtils setters
Diffstat (limited to 'src')
-rw-r--r--src/html/catom.nim16
-rw-r--r--src/html/dom.nim96
2 files changed, 82 insertions, 30 deletions
diff --git a/src/html/catom.nim b/src/html/catom.nim
index 4a0b4f65..0c866b71 100644
--- a/src/html/catom.nim
+++ b/src/html/catom.nim
@@ -98,6 +98,7 @@ macro makeStaticAtom =
       satText = "text"
       satTimeout = "timeout"
       satTitle = "title"
+      satToString = "toString"
       satTouchmove = "touchmove"
       satTouchstart = "touchstart"
       satType = "type"
@@ -200,6 +201,9 @@ func toAtom*(factory: CAtomFactory; attrType: StaticAtom): CAtom =
 func toStr*(factory: CAtomFactory; atom: CAtom): string =
   return factory.atomMap[int(atom)]
 
+func toStr*(factory: CAtomFactory; sa: StaticAtom): string =
+  return factory.toStr(factory.toAtom(sa))
+
 func toTagType*(factory: CAtomFactory; atom: CAtom): TagType =
   let i = int(atom)
   if i <= int(TagType.high):
@@ -212,6 +216,9 @@ func toStaticAtom*(factory: CAtomFactory; atom: CAtom): StaticAtom =
     return StaticAtom(i)
   return atUnknown
 
+func toStaticAtom*(factory: CAtomFactory; s: string): StaticAtom =
+  return factory.toStaticAtom(factory.toAtom(s))
+
 # Forward declaration hack
 var getFactoryImpl*: proc(ctx: JSContext): CAtomFactory {.nimcall, noSideEffect,
   raises: [].}
@@ -225,6 +232,15 @@ proc toAtom*(ctx: JSContext; s: string): CAtom =
 proc toStaticAtom*(ctx: JSContext; atom: CAtom): StaticAtom =
   return ctx.getFactoryImpl().toStaticAtom(atom)
 
+proc toStaticAtom*(ctx: JSContext; s: string): StaticAtom =
+  return ctx.getFactoryImpl().toStaticAtom(s)
+
+proc toStr*(ctx: JSContext; atom: CAtom): string =
+  return ctx.getFactoryImpl().toStr(atom)
+
+proc toStr*(ctx: JSContext; sa: StaticAtom): string =
+  return ctx.getFactoryImpl().toStr(sa)
+
 proc fromJS*(ctx: JSContext; val: JSValue; res: var CAtom): Opt[void] =
   var s: string
   ?ctx.fromJS(val, s)
diff --git a/src/html/dom.nim b/src/html/dom.nim
index 10b64941..6cb6426c 100644
--- a/src/html/dom.nim
+++ b/src/html/dom.nim
@@ -2653,31 +2653,73 @@ proc parseColor(element: Element; s: string): ARGBColor =
   return color.argb
 
 # HTMLHyperlinkElementUtils (for <a> and <area>)
-proc reinitURL*(element: HTMLElement): Option[URL] =
+proc reinitURL*(element: Element): Option[URL] =
   if element.attrb(satHref):
     let url = parseURL(element.attr(satHref), some(element.document.baseURL))
     if url.isSome and url.get.scheme != "blob":
       return url
   return none(URL)
 
-proc hyperlinkGetProp(ctx: JSContext; element: HTMLElement; a: JSAtom):
-    JSValue =
-  let href = element.reinitURL()
-  var res = JS_UNINITIALIZED
-  var ca: StaticAtom
-  if ctx.fromJS(a, ca).isSome:
-    if ca in {satHref, satOrigin, satProtocol, satUsername, satPassword,
+proc hyperlinkGet(ctx: JSContext; this: JSValue; magic: cint): JSValue
+    {.cdecl.} =
+  var element: Element
+  if ctx.fromJS(this, element).isNone:
+    return JS_EXCEPTION
+  let sa = StaticAtom(magic)
+  let url = element.reinitURL()
+  if url.isSome:
+    let href = ctx.toJS(url.get)
+    let s = ctx.toStr(sa)
+    let res = JS_GetPropertyStr(ctx, href, cstring(s))
+    JS_FreeValue(ctx, href)
+    return res
+  if sa == satProtocol:
+    return ctx.toJS(":")
+  return ctx.toJS("")
+
+proc hyperlinkSet(ctx: JSContext; this, val: JSValue; magic: cint): JSValue
+    {.cdecl.} =
+  var element: Element
+  if ctx.fromJS(this, element).isNone:
+    return JS_EXCEPTION
+  let sa = StaticAtom(magic)
+  if sa == satHref:
+    var s: string
+    if ctx.fromJS(val, s).isSome:
+      element.attr(satHref, s)
+      return JS_DupValue(ctx, val)
+    return JS_EXCEPTION
+  let url = element.reinitURL()
+  if url.isSome:
+    let href = ctx.toJS(url)
+    let s = ctx.toStr(sa)
+    let res = JS_SetPropertyStr(ctx, href, cstring(s), JS_DupValue(ctx, val))
+    if res < 0:
+      return JS_EXCEPTION
+    var outs: string
+    if ctx.fromJS(href, outs).isSome:
+      element.attr(satHref, outs)
+    JS_FreeValue(ctx, href)
+  return JS_DupValue(ctx, val)
+
+proc hyperlinkGetProp(ctx: JSContext; element: HTMLElement; a: JSAtom;
+    desc: ptr JSPropertyDescriptor): JSValue =
+  var s: string
+  if ctx.fromJS(a, s).isSome:
+    let sa = ctx.toStaticAtom(ctx.toAtom(s))
+    if sa in {satHref, satOrigin, satProtocol, satUsername, satPassword,
         satHost, satHostname, satPort, satPathname, satSearch, satHash}:
-      if href.isSome:
-        let url = ctx.toJS(href.get)
-        if not JS_IsException(url):
-          res = JS_GetProperty(ctx, url, a)
-          JS_FreeValue(ctx, url)
-      elif ca == satProtocol:
-        res = ctx.toJS(":")
-      else:
-        res = ctx.toJS("")
-  return res
+      if desc != nil:
+        let u1 = JSCFunctionType(getter_magic: hyperlinkGet)
+        let u2 = JSCFunctionType(setter_magic: hyperlinkSet)
+        desc.getter = JS_NewCFunction2(ctx, u1.generic,
+          cstring(s), 0, JS_CFUNC_getter_magic, cint(sa))
+        desc.setter = JS_NewCFunction2(ctx, u2.generic,
+          cstring(s), 0, JS_CFUNC_setter_magic, cint(sa))
+        desc.value = JS_UNDEFINED
+        desc.flags = JS_PROP_GETSET
+      return JS_TRUE # dummy value
+  return JS_UNINITIALIZED
 
 # <base>
 proc href(base: HTMLBaseElement): string {.jsfget.} =
@@ -2688,12 +2730,9 @@ proc href(base: HTMLBaseElement): string {.jsfget.} =
   return ""
 
 # <a>
-proc setHref(anchor: HTMLAnchorElement; href: string) {.jsfset: "href".} =
-  anchor.attr(satHref, href)
-
-proc getter(ctx: JSContext; anchor: HTMLAnchorElement; a: JSAtom): JSValue
-    {.jsgetownprop.} =
-  return ctx.hyperlinkGetProp(anchor, a)
+proc getter(ctx: JSContext; this: HTMLAnchorElement; a: JSAtom;
+    desc: ptr JSPropertyDescriptor): JSValue {.jsgetownprop.} =
+  return ctx.hyperlinkGetProp(this, a, desc)
 
 proc toString(anchor: HTMLAnchorElement): string {.jsfunc.} =
   let href = anchor.reinitURL()
@@ -2705,12 +2744,9 @@ proc setRelList(anchor: HTMLAnchorElement; s: string) {.jsfset: "relList".} =
   anchor.attr(satRel, s)
 
 # <area>
-proc setHref(area: HTMLAreaElement; href: string) {.jsfset: "href".} =
-  area.attr(satHref, href)
-
-proc getter(ctx: JSContext; anchor: HTMLAreaElement; a: JSAtom): JSValue
-    {.jsgetownprop.} =
-  return ctx.hyperlinkGetProp(anchor, a)
+proc getter(ctx: JSContext; this: HTMLAreaElement; a: JSAtom;
+    desc: ptr JSPropertyDescriptor): JSValue {.jsgetownprop.} =
+  return ctx.hyperlinkGetProp(this, a, desc)
 
 proc toString(area: HTMLAreaElement): string {.jsfunc.} =
   let href = area.reinitURL()