about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2025-01-09 19:19:10 +0100
committerbptato <nincsnevem662@gmail.com>2025-01-09 19:19:10 +0100
commit06e3ef17faa1876f75a0a09e601f9968026c8fb5 (patch)
tree5ff0bef52369cd4e798b825637d62f5de1080bcd /src
parentc31cc2f163f4ab72207cf4c96804ec937604087e (diff)
downloadchawan-06e3ef17faa1876f75a0a09e601f9968026c8fb5.tar.gz
env: basic postMessage
Diffstat (limited to 'src')
-rw-r--r--src/html/catom.nim1
-rw-r--r--src/html/env.nim17
-rw-r--r--src/html/event.nim42
3 files changed, 50 insertions, 10 deletions
diff --git a/src/html/catom.nim b/src/html/catom.nim
index 3f5bd716..1900a502 100644
--- a/src/html/catom.nim
+++ b/src/html/catom.nim
@@ -64,6 +64,7 @@ macro makeStaticAtom =
       satLoadstart = "loadstart"
       satMax = "max"
       satMedia = "media"
+      satMessage = "message"
       satMethod = "method"
       satMin = "min"
       satMousewheel = "mousewheel"
diff --git a/src/html/env.nim b/src/html/env.nim
index 83dbdbae..8d59803d 100644
--- a/src/html/env.nim
+++ b/src/html/env.nim
@@ -17,6 +17,7 @@ import io/console
 import io/dynstream
 import io/promise
 import io/timeout
+import monoucha/fromjs
 import monoucha/javascript
 import monoucha/jserror
 import monoucha/jspropenumlist
@@ -308,8 +309,20 @@ proc matchMedia(window: Window; s: string): MediaQueryList {.jsfunc.} =
     media: $mqlist
   )
 
-proc postMessage(window: Window) {.jsfunc.} =
-  window.console.log("postMessage: Stub")
+proc postMessage(ctx: JSContext; window: Window; value: JSValue): Err[void]
+    {.jsfunc.} =
+  #TODO structuredClone...
+  let value = JS_JSONStringify(ctx, value, JS_UNDEFINED, JS_UNDEFINED)
+  defer: JS_FreeValue(ctx, value)
+  var s: string
+  ?ctx.fromJS(value, s)
+  let data = JS_ParseJSON(ctx, cstring(s), csize_t(s.len),
+    cstring"<postMessage>")
+  let event = ctx.newMessageEvent(ctx.toAtom(satMessage),
+    MessageEventInit(data: data))
+  JS_FreeValue(ctx, data)
+  discard ctx.dispatch(window, event)
+  ok()
 
 proc setOnLoad(ctx: JSContext; window: Window; val: JSValue)
     {.jsfset: "onload".} =
diff --git a/src/html/event.nim b/src/html/event.nim
index 0625001d..3f3a434f 100644
--- a/src/html/event.nim
+++ b/src/html/event.nim
@@ -44,6 +44,10 @@ type
   CustomEvent* = ref object of Event
     detail {.jsget.}: JSValue
 
+  MessageEvent* = ref object of Event
+    data {.jsget.}: JSValue
+    origin {.jsget.}: string
+
   EventTarget* = ref object of RootObj
     eventListeners*: seq[EventListener]
 
@@ -62,6 +66,7 @@ type
 
 jsDestructor(Event)
 jsDestructor(CustomEvent)
+jsDestructor(MessageEvent)
 jsDestructor(EventTarget)
 
 # Forward declaration hack
@@ -77,7 +82,12 @@ type
     composed* {.jsdefault.}: bool
 
   CustomEventInit = object of EventInit
-    detail* {.jsdefault: JS_NULL.}: JSValue
+    detail {.jsdefault: JS_NULL.}: JSValue
+
+  MessageEventInit* = object of EventInit
+    data* {.jsdefault: JS_NULL.}: JSValue
+    origin {.jsdefault.}: string
+    lastEventId {.jsdefault.}: string
 
 # Event
 proc innerEventCreationSteps*(event: Event; eventInitDict: EventInit) =
@@ -91,10 +101,10 @@ proc innerEventCreationSteps*(event: Event; eventInitDict: EventInit) =
 
 #TODO eventInitDict type
 proc newEvent(ctx: JSContext; ctype: CAtom; eventInitDict = EventInit()):
-    JSResult[Event] {.jsctor.} =
+    Event {.jsctor.} =
   let event = Event(ctype: ctype)
   event.innerEventCreationSteps(eventInitDict)
-  return ok(event)
+  return event
 
 proc newEvent*(ctype: CAtom; target: EventTarget): Event =
   return Event(
@@ -160,12 +170,13 @@ func composed(this: Event): bool {.jsfget.} =
 
 # CustomEvent
 proc newCustomEvent(ctx: JSContext; ctype: CAtom;
-    eventInitDict = CustomEventInit()): JSResult[CustomEvent] {.jsctor.} =
-  let event = CustomEvent()
+    eventInitDict = CustomEventInit()): CustomEvent {.jsctor.} =
+  let event = CustomEvent(
+    ctype: ctype,
+    detail: JS_DupValue(ctx, eventInitDict.detail)
+  )
   event.innerEventCreationSteps(eventInitDict)
-  event.detail = JS_DupValue(ctx, eventInitDict.detail)
-  event.ctype = ctype
-  return ok(event)
+  return event
 
 proc finalize(rt: JSRuntime; this: CustomEvent) {.jsfin.} =
   JS_FreeValueRT(rt, this.detail)
@@ -176,6 +187,20 @@ proc initCustomEvent(this: CustomEvent; ctype: CAtom;
     this.initialize(ctype, bubbles, cancelable)
     this.detail = detail
 
+# MessageEvent
+proc finalize(rt: JSRuntime; this: MessageEvent) {.jsfin.} =
+  JS_FreeValueRT(rt, this.data)
+
+proc newMessageEvent*(ctx: JSContext; ctype: CAtom;
+    eventInit = MessageEventInit()): MessageEvent =
+  let event = MessageEvent(
+    ctype: ctype,
+    data: JS_DupValue(ctx, eventInit.data),
+    origin: eventInit.origin
+  )
+  event.innerEventCreationSteps(eventInit)
+  return event
+
 # EventTarget
 proc newEventTarget(): EventTarget {.jsctor.} =
   return EventTarget()
@@ -335,5 +360,6 @@ proc dispatchEvent(ctx: JSContext; this: EventTarget; event: Event):
 proc addEventModule*(ctx: JSContext) =
   let eventCID = ctx.registerType(Event)
   ctx.registerType(CustomEvent, parent = eventCID)
+  ctx.registerType(MessageEvent, parent = eventCID)
   ctx.defineConsts(eventCID, EventPhase)
   ctx.registerType(EventTarget)