about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--src/html/event.nim6
-rw-r--r--src/server/buffer.nim118
2 files changed, 75 insertions, 49 deletions
diff --git a/src/html/event.nim b/src/html/event.nim
index 46a576fb..6234f166 100644
--- a/src/html/event.nim
+++ b/src/html/event.nim
@@ -28,7 +28,7 @@ type
   Event* = ref object of RootObj
     ctype {.jsget: "type".}: string
     target* {.jsget.}: EventTarget
-    currentTarget {.jsget.}: EventTarget
+    currentTarget* {.jsget.}: EventTarget
     eventPhase {.jsget.}: uint16
     bubbles {.jsget.}: bool
     cancelable {.jsget.}: bool
@@ -93,11 +93,11 @@ proc newEvent(ctx: JSContext, ctype: string, eventInitDict = EventInit()):
   event.ctype = ctype
   return ok(event)
 
-proc newEvent*(ctx: JSContext, ctype: string, target, currentTarget: EventTarget): Event =
+proc newEvent*(ctx: JSContext, ctype: string, target: EventTarget): Event =
   return Event(
     ctype: ctype,
     target: target,
-    currentTarget: currentTarget
+    currentTarget: target
   )
 
 proc initialize(this: Event, ctype: string, bubbles, cancelable: bool) =
diff --git a/src/server/buffer.nim b/src/server/buffer.nim
index 681f9bb2..fa134d8f 100644
--- a/src/server/buffer.nim
+++ b/src/server/buffer.nim
@@ -985,6 +985,76 @@ proc clone*(buffer: Buffer, newurl: URL): Pid {.proxy.} =
     buffer.loader.resume(fds)
     return pid
 
+proc dispatchDOMContentLoadedEvent(buffer: Buffer) =
+  let window = buffer.window
+  if window == nil or not buffer.config.scripting:
+    return
+  let ctx = window.jsctx
+  let document = buffer.document
+  let event = newEvent(ctx, "DOMContentLoaded", document)
+  var called = false
+  for el in document.eventListeners:
+    if el.ctype == "DOMContentLoaded":
+      let e = el.callback(event)
+      if e.isErr:
+        ctx.writeException(buffer.estream)
+      called = true
+  if called:
+    buffer.do_reshape()
+
+proc dispatchLoadEvent(buffer: Buffer) =
+  let window = buffer.window
+  if window == nil or not buffer.config.scripting:
+    return
+  let ctx = window.jsctx
+  let event = newEvent(ctx, "load", window)
+  var called = false
+  for el in window.eventListeners:
+    if el.ctype == "load":
+      let e = el.callback(event)
+      if e.isErr:
+        ctx.writeException(buffer.estream)
+      called = true
+  let jsWindow = toJS(ctx, window)
+  let jsonload = JS_GetPropertyStr(ctx, jsWindow, "onload")
+  var jsEvent = toJS(ctx, event)
+  if JS_IsFunction(ctx, jsonload):
+    JS_FreeValue(ctx, JS_Call(ctx, jsonload, jsWindow, 1, addr jsEvent))
+    called = true
+  JS_FreeValue(ctx, jsEvent)
+  JS_FreeValue(ctx, jsonload)
+  JS_FreeValue(ctx, jsWindow)
+  if called:
+    buffer.do_reshape()
+
+proc dispatchEvent(buffer: Buffer, ctype: string, elem: Element): tuple[
+      called: bool,
+      canceled: bool
+    ] =
+  var called = false
+  var canceled = false
+  let ctx = buffer.window.jsctx
+  let event = newEvent(ctx, ctype, elem)
+  for a in elem.branch:
+    event.currentTarget = a
+    var stop = false
+    for el in a.eventListeners:
+      if el.ctype == ctype:
+        let e = el.callback(event)
+        called = true
+        if e.isErr:
+          ctx.writeException(buffer.estream)
+        if FLAG_STOP_IMMEDIATE_PROPAGATION in event.flags:
+          stop = true
+          break
+        if FLAG_STOP_PROPAGATION in event.flags:
+          stop = true
+        if FLAG_CANCELED in event.flags:
+          canceled = true
+    if stop:
+      break
+  return (called, canceled)
+
 const BufferSize = 4096
 
 proc finishLoad(buffer: Buffer): EmptyPromise =
@@ -1003,6 +1073,7 @@ proc finishLoad(buffer: Buffer): EmptyPromise =
       window = buffer.window, url = buffer.url)
     buffer.document = doc
     buffer.state = LOADING_RESOURCES
+    buffer.dispatchDOMContentLoadedEvent()
     p = buffer.loadResources()
   else:
     p = EmptyPromise()
@@ -1036,26 +1107,6 @@ proc resolveTask[T](buffer: Buffer, cmd: BufferCommand, res: T) =
   buffer.pstream.swrite(res)
   buffer.pstream.flush()
 
-proc dispatchLoadEvent(buffer: Buffer) =
-  let window = buffer.window
-  if window == nil or not buffer.config.scripting:
-    return
-  let ctx = buffer.window.jsctx
-  let event = newEvent(ctx, "load", window, window)
-  for el in window.eventListeners:
-    if el.ctype == "load":
-      let e = el.callback(event)
-      if e.isErr:
-        ctx.writeException(buffer.estream)
-  let jsWindow = toJS(ctx, window)
-  let jsonload = JS_GetPropertyStr(ctx, jsWindow, "onload")
-  var jsEvent = toJS(ctx, event)
-  if JS_IsFunction(ctx, jsonload):
-    JS_FreeValue(ctx, JS_Call(ctx, jsonload, jsWindow, 1, addr jsEvent))
-  JS_FreeValue(ctx, jsEvent)
-  JS_FreeValue(ctx, jsonload)
-  JS_FreeValue(ctx, jsWindow)
-
 proc onload(buffer: Buffer) =
   var res: LoadResult = (false, buffer.lines.len, -1)
   case buffer.state
@@ -1502,32 +1553,6 @@ proc click(buffer: Buffer, clickable: Element): ClickResult =
   else:
     result.repaint = buffer.restoreFocus()
 
-proc dispatchEvent(buffer: Buffer, ctype: string, elem: Element): tuple[
-      called: bool,
-      canceled: bool
-    ] =
-  var called = false
-  var canceled = false
-  for a in elem.branch:
-    var stop = false
-    for el in a.eventListeners:
-      if el.ctype == ctype:
-        let event = newEvent(buffer.window.jsctx, ctype, elem, a)
-        let e = el.callback(event)
-        called = true
-        if e.isErr:
-          buffer.window.jsctx.writeException(buffer.estream)
-        if FLAG_STOP_IMMEDIATE_PROPAGATION in event.flags:
-          stop = true
-          break
-        if FLAG_STOP_PROPAGATION in event.flags:
-          stop = true
-        if FLAG_CANCELED in event.flags:
-          canceled = true
-    if stop:
-      break
-  return (called, canceled)
-
 proc click*(buffer: Buffer, cursorx, cursory: int): ClickResult {.proxy.} =
   if buffer.lines.len <= cursory: return
   var called = false
@@ -1720,6 +1745,7 @@ proc runBuffer(buffer: Buffer) =
         let r = buffer.window.timeouts.runTimeoutFd(event.fd)
         assert r
         buffer.window.runJSJobs()
+        buffer.do_reshape()
     buffer.loader.unregistered.setLen(0)
 
 proc launchBuffer*(config: BufferConfig, source: BufferSource,