diff options
author | bptato <nincsnevem662@gmail.com> | 2023-10-25 11:56:54 +0200 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2023-10-25 12:04:37 +0200 |
commit | 98865ac747766118b94f39f749aba4be62c78022 (patch) | |
tree | dd0d6520997eef16fa7238d1dc486affd49057b6 /src/js | |
parent | e4cccbeb7488dfe8afbbe51c60fd16557dea923f (diff) | |
download | chawan-98865ac747766118b94f39f749aba4be62c78022.tar.gz |
Add jspropnames, CSSStyleDeclaration stub
Diffstat (limited to 'src/js')
-rw-r--r-- | src/js/javascript.nim | 53 | ||||
-rw-r--r-- | src/js/propertyenumlist.nim | 42 |
2 files changed, 92 insertions, 3 deletions
diff --git a/src/js/javascript.nim b/src/js/javascript.nim index 996137cd..e682098a 100644 --- a/src/js/javascript.nim +++ b/src/js/javascript.nim @@ -32,6 +32,9 @@ # {.jsdelprop.} for property deletion. It is like the deleteProperty method # of Proxy. Must return true if deleted, false if not deleted. # {.jshasprop.} for overriding has_property. Must return a boolean. +# {.jspropnames.} overrides get_own_property_names. Must return a +# JSPropertyEnumList object. +# UncheckedArray[JSPropertyEnum] import macros import options @@ -98,6 +101,7 @@ type PROPERTY_SET = "js_prop_set" PROPERTY_DEL = "js_prop_del" PROPERTY_HAS = "js_prop_has" + PROPERTY_NAMES = "js_prop_names" FINALIZER = "js_fin" var runtimes {.threadVar.}: seq[JSRuntime] @@ -471,6 +475,15 @@ template getJSSetterParams(): untyped = newIdentDefs(ident("val"), quote do: JSValue), ] +template getJSPropNamesParams(): untyped = + [ + (quote do: cint), + newIdentDefs(ident("ctx"), quote do: JSContext), + newIdentDefs(ident("ptab"), quote do: ptr JSPropertyEnumArray), + newIdentDefs(ident("plen"), quote do: ptr uint32), + newIdentDefs(ident("obj"), quote do: JSValue) + ] + template fromJS_or_return*(t, ctx, val: untyped): untyped = ( let x = fromJS[t](ctx, val) @@ -563,6 +576,10 @@ proc addUnionParam0(gen: var JSFuncGenerator, tt: NimNode, s: NimNode, val: NimN elif g == bool.getTypeInst(): hasBoolean = true elif g == int.getTypeInst(): #TODO should be SomeNumber + assert numg.isNone + numg = some(g) + elif g == uint32.getTypeInst(): #TODO should be SomeNumber + assert numg.isNone numg = some(g) elif g.getTypeInst().getTypeImpl().kind == nnkRefTy: # Assume it's ref object. @@ -789,7 +806,8 @@ func getFuncName(fun: NimNode, jsname: string): string = return x func getErrVal(t: BoundFunctionType): NimNode = - if t in {PROPERTY_GET, PROPERTY_SET, PROPERTY_DEL, PROPERTY_HAS}: + if t in {PROPERTY_GET, PROPERTY_SET, PROPERTY_DEL, PROPERTY_HAS, + PROPERTY_NAMES}: return quote do: cint(-1) return quote do: JS_EXCEPTION @@ -976,6 +994,26 @@ macro jsdelprop*(fun: typed) = gen.registerFunction() return newStmtList(fun, jsProc) +macro jspropnames*(fun: typed) = + var gen = setupGenerator(fun, PROPERTY_NAMES, thisname = some("obj")) + if gen.newName.strVal in existing_funcs: + #TODO TODO TODO ditto + error("Function overloading hasn't been implemented yet...") + gen.addFixParam("obj") + gen.finishFunCallList() + let jfcl = gen.jsFunCallList + let dl = gen.dielabel + gen.jsCallAndRet = quote do: + block `dl`: + let retv = `jfcl` + ptab[] = retv.buffer + plen[] = retv.len + return cint(0) + return cint(-1) + let jsProc = gen.newJSProc(getJSPropNamesParams(), false) + gen.registerFunction() + return newStmtList(fun, jsProc) + macro jsfgetn(jsname: static string, uf: static bool, fun: typed) = var gen = setupGenerator(fun, GETTER, jsname = jsname, unforgeable = uf) if gen.actualMinArgs != 0 or gen.funcParams.len != gen.minArgs: @@ -1221,6 +1259,7 @@ type RegistryInfo = object propSetFun: NimNode # custom set function ident propDelFun: NimNode # custom del function ident propHasFun: NimNode # custom has function ident + propNamesFun: NimNode # custom property names function ident finFun: NimNode # finalizer ident finName: NimNode # finalizer wrapper ident dfin: NimNode # CheckDestroy finalizer ident @@ -1252,7 +1291,8 @@ proc newRegistryInfo(t: NimNode, name: string): RegistryInfo = propGetFun: newNilLit(), propSetFun: newNilLit(), propDelFun: newNilLit(), - propHasFun: newNilLit() + propHasFun: newNilLit(), + propNamesFun: newNilLit() ) if info.tname notin js_dtors: warning("No destructor has been defined for type " & info.tname) @@ -1368,6 +1408,10 @@ proc bindFunctions(stmts: NimNode, info: var RegistryInfo) = if info.propHasFun.kind != nnkNilLit: error("Class " & info.tname & " has 2+ hasprop getters.") info.propHasFun = f1 + of PROPERTY_NAMES: + if info.propNamesFun.kind != nnkNilLit: + error("Class " & info.tname & " has 2+ propnames getters.") + info.propNamesFun = f1 of FINALIZER: f0 = fun.name info.finFun = ident(f0) @@ -1463,16 +1507,19 @@ proc bindEndStmts(endstmts: NimNode, info: RegistryInfo) = if info.propGetFun.kind != nnkNilLit or info.propSetFun.kind != nnkNilLit or info.propDelFun.kind != nnkNilLit or - info.propHasFun.kind != nnkNilLit: + info.propHasFun.kind != nnkNilLit or + info.propNamesFun.kind != nnkNilLit: let propGetFun = info.propGetFun let propSetFun = info.propSetFun let propDelFun = info.propDelFun let propHasFun = info.propHasFun + let propNamesFun = info.propNamesFun endstmts.add(quote do: # No clue how to do this in pure nim. {.emit: [""" static JSClassExoticMethods exotic = { .get_own_property = """, `propGetFun`, """, + .get_own_property_names = """, `propNamesFun`, """, .has_property = """, `propHasFun`, """, .set_property = """, `propSetFun`, """, .delete_property = """, `propDelFun`, """ diff --git a/src/js/propertyenumlist.nim b/src/js/propertyenumlist.nim new file mode 100644 index 00000000..98ad2a4f --- /dev/null +++ b/src/js/propertyenumlist.nim @@ -0,0 +1,42 @@ +import bindings/quickjs + +type + JSPropertyEnumArray* = ptr UncheckedArray[JSPropertyEnum] + + JSPropertyEnumList* = object + buffer*: JSPropertyEnumArray + size: uint32 + len*: uint32 + ctx: JSContext + + JSPropertyEnumWrapper* = object + is_enumerable: bool + name: string + +func newJSPropertyEnumList*(ctx: JSContext, size: uint32): JSPropertyEnumList = + let p = js_malloc(ctx, csize_t(sizeof(JSPropertyEnum)) * csize_t(size)) + let buffer = cast[JSPropertyEnumArray](p) + return JSPropertyEnumList( + ctx: ctx, + buffer: buffer, + size: size + ) + +proc grow(this: var JSPropertyEnumList) = + this.size *= 2 + let p = js_realloc(this.ctx, this.buffer, csize_t(this.size)) + this.buffer = cast[JSPropertyEnumArray](p) + +proc add*(this: var JSPropertyEnumList, val: uint32) = + let i = this.len + inc this.len + if this.size < this.len: + this.grow() + this.buffer[i].atom = JS_NewAtomUInt32(this.ctx, val) + +proc add*(this: var JSPropertyEnumList, val: string) = + let i = this.len + inc this.len + if this.size < this.len: + this.grow() + this.buffer[i].atom = JS_NewAtomLen(this.ctx, cstring(val), csize_t(val.len)) |