diff options
author | bptato <nincsnevem662@gmail.com> | 2023-09-09 11:20:42 +0200 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2023-09-09 11:20:42 +0200 |
commit | 07245ef4826298fffc3e34e34a74fdf77c7a4fac (patch) | |
tree | 7b0d0aa27da58ad7109fe69d51beed7a159f1aac /src | |
parent | 11219c7d21c8ec7f438d52de063c4ac25f84711d (diff) | |
download | chawan-07245ef4826298fffc3e34e34a74fdf77c7a4fac.tar.gz |
javascript: add JSDict type
And use that in extern().
Diffstat (limited to 'src')
-rw-r--r-- | src/display/pager.nim | 24 | ||||
-rw-r--r-- | src/js/dict.nim | 5 | ||||
-rw-r--r-- | src/js/fromjs.nim | 17 | ||||
-rw-r--r-- | src/js/tojs.nim | 14 |
4 files changed, 46 insertions, 14 deletions
diff --git a/src/display/pager.nim b/src/display/pager.nim index 0229c706..438f8763 100644 --- a/src/display/pager.nim +++ b/src/display/pager.nim @@ -28,6 +28,7 @@ import io/tempfile import io/window import ips/forkserver import ips/socketstream +import js/dict import js/javascript import js/regex import js/tojs @@ -839,25 +840,22 @@ proc setEnvVars(pager: Pager) {.jsfunc.} = except OSError: pager.alert("Warning: failed to set some environment variables") -type ExternType = enum - SUSPEND_SETENV = "suspend-setenv" - SUSPEND_SETENV_WAIT = "suspend-setenv-wait" - SUSPEND_NO_SETENV = "suspend-no-setenv" - SUSPEND_NO_SETENV_WAIT = "suspend-no-setenv-wait" - NO_SUSPEND_SETENV = "no-suspend-setenv" - NO_SUSPEND_NO_SETENV = "no-suspend-no-setenv" +#TODO use default values instead... +type ExternDict = object of JSDict + setenv: Opt[bool] + suspend: Opt[bool] + wait: bool #TODO this could be handled much better. # * suspend, setenv, wait as dict flags # * retval as int? -proc extern(pager: Pager, cmd: string, t = SUSPEND_SETENV): bool {.jsfunc.} = - if t in {SUSPEND_SETENV, SUSPEND_SETENV_WAIT, NO_SUSPEND_SETENV}: +proc extern(pager: Pager, cmd: string, t = ExternDict()): bool {.jsfunc.} = + if t.setenv.get(true): pager.setEnvVars() - if t in {NO_SUSPEND_SETENV, NO_SUSPEND_NO_SETENV}: - return runProcess(cmd) + if t.suspend.get(true): + return runProcess(pager.term, cmd, t.wait) else: - return runProcess(pager.term, cmd, - t in {SUSPEND_SETENV_WAIT, SUSPEND_NO_SETENV_WAIT}) + return runProcess(cmd) proc authorize(pager: Pager) = pager.setLineEdit("Username: ", USERNAME) diff --git a/src/js/dict.nim b/src/js/dict.nim new file mode 100644 index 00000000..5003b92c --- /dev/null +++ b/src/js/dict.nim @@ -0,0 +1,5 @@ +# This is the WebIDL dictionary type. +# We only use it for type inference in generics. +#TODO required members + +type JSDict* = object of RootObj diff --git a/src/js/fromjs.nim b/src/js/fromjs.nim index 310550e4..701f0a60 100644 --- a/src/js/fromjs.nim +++ b/src/js/fromjs.nim @@ -5,6 +5,7 @@ import tables import unicode import bindings/quickjs +import js/dict import js/error import js/opaque import js/tojs @@ -403,7 +404,19 @@ proc fromJSVoid(ctx: JSContext, val: JSValue): JSResult[void] = return err() return ok() -type FromJSAllowedT = (object and not (Result|Option|Table|JSValue)) +proc fromJSDict[T: JSDict](ctx: JSContext, val: JSValue): JSResult[T] = + if not JS_IsUndefined(val) and not JS_IsNull(val) and not JS_IsObject(val): + return err(newTypeError("Dictionary is not an object")) + #TODO throw on missing required values + var d: T + if JS_IsObject(val): + for k, v in d.fieldPairs: + let esm = JS_GetPropertyStr(ctx, val, k) + if not JS_IsUndefined(esm): + v = ?fromJS[typeof(v)](ctx, esm) + return ok(d) + +type FromJSAllowedT = (object and not (Result|Option|Table|JSValue|JSDict)) proc fromJS*[T](ctx: JSContext, val: JSValue): JSResult[T] = when T is string: @@ -441,6 +454,8 @@ proc fromJS*[T](ctx: JSContext, val: JSValue): JSResult[T] = return fromJSObject[T](ctx, val) elif T is void: return fromJSVoid(ctx, val) + elif T is JSDict: + return fromJSDict[T](ctx, val) elif compiles(fromJS2(ctx, val, result)): fromJS2(ctx, val, result) else: diff --git a/src/js/tojs.nim b/src/js/tojs.nim index ca38bd2b..cd4f2b86 100644 --- a/src/js/tojs.nim +++ b/src/js/tojs.nim @@ -4,6 +4,7 @@ import unicode import bindings/quickjs import io/promise +import js/dict import js/error import js/opaque import js/typeptr @@ -33,6 +34,7 @@ proc toJS*(ctx: JSContext, promise: EmptyPromise): JSValue proc toJS*(ctx: JSContext, obj: ref object): JSValue proc toJS*(ctx: JSContext, err: JSError): JSValue proc toJS*(ctx: JSContext, f: JSCFunction): JSValue +proc toJS*(ctx: JSContext, d: JSDict): JSValue # Convert Nim types to the corresponding JavaScript type, with knowledge of # the parent object. @@ -55,6 +57,7 @@ makeToJSP(Table) makeToJSP(Option) makeToJSP(Result) makeToJSP(JSValue) +makeToJSP(JSDict) proc defineProperty(ctx: JSContext, this: JSValue, name: string, prop: JSValue, flags = cint(0)) = @@ -254,6 +257,17 @@ proc toJS*(ctx: JSContext, err: JSError): JSValue = proc toJS*(ctx: JSContext, f: JSCFunction): JSValue = return JS_NewCFunction(ctx, f, cstring"", 0) +proc toJS*(ctx: JSContext, d: JSDict): JSValue = + let obj = JS_NewObject(ctx) + if JS_IsException(obj): + return obj + for k, v in d.fieldPairs: + let val = toJS(ctx, v) + if JS_IsException(val): + return val + definePropertyCWE(ctx, obj, k, val) + return obj + proc toJSP(ctx: JSContext, parent: ref object, child: var object): JSValue = let p = addr child # Save parent as the original ancestor for this tree. |