about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/html/dom.nim27
-rw-r--r--src/html/enums.nim1
-rw-r--r--src/js/javascript.nim1
-rw-r--r--src/js/opaque.nim8
-rw-r--r--src/js/tojs.nim20
5 files changed, 49 insertions, 8 deletions
diff --git a/src/html/dom.nim b/src/html/dom.nim
index e4325b18..597d34b9 100644
--- a/src/html/dom.nim
+++ b/src/html/dom.nim
@@ -2813,6 +2813,21 @@ proc reflectAttrs(element: Element, name: CAtom, value: string) =
     element.style_cached = newCSSStyleDeclaration(element, value)
     return
   case element.tagType
+  of TAG_BODY:
+    if name == atOnload and element.scriptingEnabled:
+      let document = element.document
+      let ctx = document.window.jsctx
+      let urls = document.baseURL.serialize(excludepassword = true)
+      let fun = ctx.newFunction(["event"], value)
+      assert ctx != nil
+      if JS_IsException(fun):
+        let s = ctx.getExceptionStr()
+        document.window.console.log("Exception in body content attribute of",
+          urls, s)
+      else:
+        let jsWindow = ctx.toJS(document.window)
+        ctx.definePropertyC(jsWindow, "onload", fun)
+        JS_FreeValue(ctx, jsWindow)
   of TAG_INPUT:
     let input = HTMLInputElement(element)
     input.reflect_str atValue, value
@@ -3533,14 +3548,16 @@ proc execute*(element: HTMLScriptElement) =
     if window != nil and window.jsctx != nil:
       let script = element.scriptResult.script
       let urls = script.baseURL.serialize(excludepassword = true)
+      let ctx = window.jsctx
       if JS_IsException(script.record):
-        let s = document.window.jsctx.getExceptionStr()
-        document.window.console.log("Exception in document", urls, s)
+        let s = ctx.getExceptionStr()
+        window.console.log("Exception in document", urls, s)
       else:
-        let ret = window.jsctx.evalFunction(script.record)
+        let ret = ctx.evalFunction(script.record)
         if JS_IsException(ret):
-          let s = document.window.jsctx.getExceptionStr()
-          document.window.console.log("Exception in document", urls, s)
+          let s = ctx.getExceptionStr()
+          window.console.log("Exception in document", urls, s)
+        JS_FreeValue(ctx, ret)
     document.currentScript = oldCurrentScript
   else: discard #TODO
   if needsInc:
diff --git a/src/html/enums.nim b/src/html/enums.nim
index 4b4faa63..e422e790 100644
--- a/src/html/enums.nim
+++ b/src/html/enums.nim
@@ -68,6 +68,7 @@ type
     atMultiple = "multiple"
     atName = "name"
     atNomodule = "nomodule"
+    atOnload = "onload"
     atReferrerpolicy = "referrerpolicy"
     atRel = "rel"
     atRequired = "required"
diff --git a/src/js/javascript.nim b/src/js/javascript.nim
index 2327660d..b4c68729 100644
--- a/src/js/javascript.nim
+++ b/src/js/javascript.nim
@@ -171,6 +171,7 @@ proc free*(ctx: var JSContext) =
     JS_FreeValue(ctx, opaque.Object_prototype_valueOf)
     JS_FreeValue(ctx, opaque.Uint8Array_ctor)
     JS_FreeValue(ctx, opaque.Set_ctor)
+    JS_FreeValue(ctx, opaque.Function_ctor)
     for v in opaque.err_ctors:
       JS_FreeValue(ctx, v)
     GC_unref(opaque)
diff --git a/src/js/opaque.nim b/src/js/opaque.nim
index bae2bd5a..bff250d0 100644
--- a/src/js/opaque.nim
+++ b/src/js/opaque.nim
@@ -34,6 +34,7 @@ type
     Object_prototype_valueOf*: JSValue
     Uint8Array_ctor*: JSValue
     Set_ctor*: JSValue
+    Function_ctor*: JSValue
     err_ctors*: array[JSErrorEnum, JSValue]
     htmldda*: JSClassID # only one of these exists: document.all.
 
@@ -72,11 +73,14 @@ func newJSContextOpaque*(ctx: JSContext): JSContextOpaque =
       opaque.Object_prototype_valueOf = JS_GetPropertyStr(ctx, objproto, "valueOf")
       JS_FreeValue(ctx, objproto)
     block:
+      opaque.Uint8Array_ctor = JS_GetPropertyStr(ctx, global, "Uint8Array")
+      assert not JS_IsException(opaque.Uint8Array_ctor)
+    block:
       opaque.Set_ctor = JS_GetPropertyStr(ctx, global, "Set")
       assert not JS_IsException(opaque.Set_ctor)
     block:
-      opaque.Uint8Array_ctor = JS_GetPropertyStr(ctx, global, "Uint8Array")
-      assert not JS_IsException(opaque.Uint8Array_ctor)
+      opaque.Function_ctor = JS_GetPropertyStr(ctx, global, "Function")
+      assert not JS_IsException(opaque.Function_ctor)
     for e in JSErrorEnum:
       let s = $e
       let err = JS_GetPropertyStr(ctx, global, cstring(s))
diff --git a/src/js/tojs.nim b/src/js/tojs.nim
index 757552eb..746dccbb 100644
--- a/src/js/tojs.nim
+++ b/src/js/tojs.nim
@@ -120,6 +120,10 @@ proc defineProperty(ctx: JSContext, this: JSValue, name: string,
   if JS_DefinePropertyValueStr(ctx, this, cstring(name), prop, flags) <= 0:
     raise newException(Defect, "Failed to define property string: " & name)
 
+proc definePropertyC*(ctx: JSContext, this: JSValue, name: string,
+    prop: JSValue) =
+  ctx.defineProperty(this, name, prop, JS_PROP_CONFIGURABLE)
+
 proc defineProperty*[T](ctx: JSContext, this: JSValue, name: string, prop: T,
     flags = cint(0)) =
   defineProperty(ctx, this, name, toJS(ctx, prop), flags)
@@ -137,6 +141,18 @@ proc definePropertyCWE*[T](ctx: JSContext, this: JSValue, name: string,
     prop: T) =
   defineProperty(ctx, this, name, prop, JS_PROP_C_W_E)
 
+proc newFunction*(ctx: JSContext, args: openArray[string], body: string):
+    JSValue =
+  var paramList: seq[JSValue] = @[]
+  for arg in args:
+    paramList.add(toJS(ctx, arg))
+  paramList.add(toJS(ctx, body))
+  let fun = JS_CallConstructor(ctx, ctx.getOpaque().Function_ctor,
+    cint(paramList.len), addr paramList[0])
+  for param in paramList:
+    JS_FreeValue(ctx, param)
+  return fun
+
 proc toJS*(ctx: JSContext, s: cstring): JSValue =
   return JS_NewString(ctx, s)
 
@@ -218,7 +234,9 @@ proc toJS*[T](ctx: JSContext, s: set[T]): JSValue =
   var a = toJS(ctx, x)
   if JS_IsException(a):
     return a
-  return JS_CallConstructor(ctx, ctx.getOpaque().Set_ctor, 1, addr a)
+  let ret = JS_CallConstructor(ctx, ctx.getOpaque().Set_ctor, 1, addr a)
+  JS_FreeValue(ctx, a)
+  return ret
 
 proc toJS(ctx: JSContext, t: tuple): JSValue =
   let a = JS_NewArray(ctx)