diff options
author | bptato <nincsnevem662@gmail.com> | 2024-05-12 12:42:15 +0200 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2024-05-12 12:45:49 +0200 |
commit | 53079a080291889428071700f8c0919f84132534 (patch) | |
tree | 95cfcde7ed6a043ac3d0f38e7ad789ee074fb19d /src | |
parent | 911ec9a85fc7b773fcea4b005d926702020a551f (diff) | |
download | chawan-53079a080291889428071700f8c0919f84132534.tar.gz |
js: allow var instead of ptr
Diffstat (limited to 'src')
-rw-r--r-- | src/config/config.nim | 30 | ||||
-rw-r--r-- | src/html/dom.nim | 40 | ||||
-rw-r--r-- | src/html/env.nim | 66 | ||||
-rw-r--r-- | src/js/fromjs.nim | 3 | ||||
-rw-r--r-- | src/js/javascript.nim | 55 |
5 files changed, 100 insertions, 94 deletions
diff --git a/src/config/config.nim b/src/config/config.nim index 2e71a27d..872f0440 100644 --- a/src/config/config.nim +++ b/src/config/config.nim @@ -227,45 +227,45 @@ func getRealKey(key: string): string = realk &= '\\' return realk -proc getter(a: ptr ActionMap; s: string): Option[string] {.jsgetprop.} = +proc getter(a: var ActionMap; s: string): Option[string] {.jsgetprop.} = a.t.withValue(s, p): return some(p[]) return none(string) -proc setter(a: ptr ActionMap; k, v: string) {.jssetprop.} = +proc setter(a: var ActionMap; k, v: string) {.jssetprop.} = let k = getRealKey(k) if k == "": return - a[][k] = v + a[k] = v var teststr = k teststr.setLen(teststr.high) for i in countdown(k.high, 0): - if teststr notin a[]: - a[][teststr] = "client.feedNext()" + if teststr notin a: + a[teststr] = "client.feedNext()" teststr.setLen(i) -proc delete(a: ptr ActionMap; k: string): bool {.jsdelprop.} = +proc delete(a: var ActionMap; k: string): bool {.jsdelprop.} = let k = getRealKey(k) - let ina = k in a[] - a[].t.del(k) + let ina = k in a + a.t.del(k) return ina -func names(ctx: JSContext; a: ptr ActionMap): JSPropertyEnumList +func names(ctx: JSContext; a: var ActionMap): JSPropertyEnumList {.jspropnames.} = - let L = uint32(a[].t.len) + let L = uint32(a.t.len) var list = newJSPropertyEnumList(ctx, L) - for key in a[].t.keys: + for key in a.t.keys: list.add(key) return list proc bindPagerKey(config: Config; key, action: string) {.jsfunc.} = - (addr config.page).setter(key, action) + config.page.setter(key, action) proc bindLineKey(config: Config; key, action: string) {.jsfunc.} = - (addr config.line).setter(key, action) + config.line.setter(key, action) -proc hasprop(a: ptr ActionMap; s: string): bool {.jshasprop.} = - return s in a[] +proc hasprop(a: var ActionMap; s: string): bool {.jshasprop.} = + return s in a proc openFileExpand(dir, file: string): FileStream = if file.len == 0: diff --git a/src/html/dom.nim b/src/html/dom.nim index 3e93de79..2293db90 100644 --- a/src/html/dom.nim +++ b/src/html/dom.nim @@ -1307,26 +1307,26 @@ func validateAttributeQName(name: string): Err[DOMException] = return errDOMException("Invalid character in attribute name", "InvalidCharacterError") -func hasprop(map: ptr DOMStringMap; name: string): bool {.jshasprop.} = - let name = map[].target.document.toAtom("data-" & name) - return map[].target.attrb(name) +func hasprop(map: var DOMStringMap; name: string): bool {.jshasprop.} = + let name = map.target.document.toAtom("data-" & name) + return map.target.attrb(name) -proc delete(map: ptr DOMStringMap; name: string): bool {.jsfunc.} = - let name = map[].target.document.toAtom("data-" & name.camelToKebabCase()) - let i = map[].target.findAttr(name) +proc delete(map: var DOMStringMap; name: string): bool {.jsfunc.} = + let name = map.target.document.toAtom("data-" & name.camelToKebabCase()) + let i = map.target.findAttr(name) if i != -1: - map[].target.delAttr(i) + map.target.delAttr(i) return i != -1 -func getter(map: ptr DOMStringMap; name: string): Option[string] +func getter(map: var DOMStringMap; name: string): Option[string] {.jsgetprop.} = - let name = map[].target.document.toAtom("data-" & name.camelToKebabCase()) - let i = map[].target.findAttr(name) + let name = map.target.document.toAtom("data-" & name.camelToKebabCase()) + let i = map.target.findAttr(name) if i != -1: - return some(map[].target.attrs[i].value) + return some(map.target.attrs[i].value) return none(string) -proc setter(map: ptr DOMStringMap; name, value: string): Err[DOMException] +proc setter(map: var DOMStringMap; name, value: string): Err[DOMException] {.jssetprop.} = var washy = false for c in name: @@ -1337,15 +1337,15 @@ proc setter(map: ptr DOMStringMap; name, value: string): Err[DOMException] "InvalidCharacterError") let name = "data-" & name.camelToKebabCase() ?name.validateAttributeName() - let aname = map[].target.document.toAtom(name) + let aname = map.target.document.toAtom(name) map.target.attr(aname, value) return ok() -func names(ctx: JSContext; map: ptr DOMStringMap): JSPropertyEnumList +func names(ctx: JSContext; map: var DOMStringMap): JSPropertyEnumList {.jspropnames.} = - var list = newJSPropertyEnumList(ctx, uint32(map[].target.attrs.len)) - for attr in map[].target.attrs: - let k = map[].target.document.toStr(attr.localName) + var list = newJSPropertyEnumList(ctx, uint32(map.target.attrs.len)) + for attr in map.target.attrs: + let k = map.target.document.toStr(attr.localName) if k.startsWith("data-") and AsciiUpperAlpha notin k: list.add(k["data-".len .. ^1].kebabToCamelCase()) return list @@ -3845,7 +3845,7 @@ proc createElement(document: Document; localName: string): proc createDocumentFragment(document: Document): DocumentFragment {.jsfunc.} = return newDocumentFragment(document) -proc createDocumentType(implementation: ptr DOMImplementation; qualifiedName, +proc createDocumentType(implementation: var DOMImplementation; qualifiedName, publicId, systemId: string): DOMResult[DocumentType] {.jsfunc.} = if not qualifiedName.matchQNameProduction(): return errDOMException("Invalid character in document type name", @@ -3853,7 +3853,7 @@ proc createDocumentType(implementation: ptr DOMImplementation; qualifiedName, let document = implementation.document return ok(document.newDocumentType(qualifiedName, publicId, systemId)) -proc createHTMLDocument(ctx: JSContext; implementation: ptr DOMImplementation; +proc createHTMLDocument(ctx: JSContext; implementation: var DOMImplementation; title = none(string)): Document {.jsfunc.} = let doc = newDocument(ctx) doc.contentType = "text/html" @@ -3870,7 +3870,7 @@ proc createHTMLDocument(ctx: JSContext; implementation: ptr DOMImplementation; #TODO set origin return doc -proc hasFeature(implementation: ptr DOMImplementation): bool {.jsfunc.} = +proc hasFeature(implementation: var DOMImplementation): bool {.jsfunc.} = return true proc createCDATASection(document: Document; data: string): diff --git a/src/html/env.nim b/src/html/env.nim index ef4b4658..dc63f790 100644 --- a/src/html/env.nim +++ b/src/html/env.nim @@ -29,27 +29,27 @@ import types/url import types/winattrs # NavigatorID -proc appCodeName(navigator: ptr Navigator): string {.jsfget.} = "Mozilla" -proc appName(navigator: ptr Navigator): string {.jsfget.} = "Netscape" -proc appVersion(navigator: ptr Navigator): string {.jsfget.} = "5.0 (Windows)" -proc platform(navigator: ptr Navigator): string {.jsfget.} = "Win32" -proc product(navigator: ptr Navigator): string {.jsfget.} = "Gecko" -proc productSub(navigator: ptr Navigator): string {.jsfget.} = "20100101" -proc userAgent(navigator: ptr Navigator): string {.jsfget.} = +proc appCodeName(navigator: var Navigator): string {.jsfget.} = "Mozilla" +proc appName(navigator: var Navigator): string {.jsfget.} = "Netscape" +proc appVersion(navigator: var Navigator): string {.jsfget.} = "5.0 (Windows)" +proc platform(navigator: var Navigator): string {.jsfget.} = "Win32" +proc product(navigator: var Navigator): string {.jsfget.} = "Gecko" +proc productSub(navigator: var Navigator): string {.jsfget.} = "20100101" +proc userAgent(navigator: var Navigator): string {.jsfget.} = #TODO TODO TODO this should be configurable "chawan" -proc vendor(navigator: ptr Navigator): string {.jsfget.} = "" -proc vendorSub(navigator: ptr Navigator): string {.jsfget.} = "" -proc taintEnabled(navigator: ptr Navigator): bool {.jsfget.} = false -proc oscpu(navigator: ptr Navigator): string {.jsfget.} = "Windows NT 10.0" +proc vendor(navigator: var Navigator): string {.jsfget.} = "" +proc vendorSub(navigator: var Navigator): string {.jsfget.} = "" +proc taintEnabled(navigator: var Navigator): bool {.jsfget.} = false +proc oscpu(navigator: var Navigator): string {.jsfget.} = "Windows NT 10.0" # NavigatorLanguage -proc language(navigator: ptr Navigator): string {.jsfget.} = "en-US" -proc languages(navigator: ptr Navigator): seq[string] {.jsfget.} = +proc language(navigator: var Navigator): string {.jsfget.} = "en-US" +proc languages(navigator: var Navigator): seq[string] {.jsfget.} = @["en-US"] #TODO frozen array? # NavigatorOnline -proc onLine(navigator: ptr Navigator): bool {.jsfget.} = +proc onLine(navigator: var Navigator): bool {.jsfget.} = true # at the very least, the terminal is on-line :) #TODO NavigatorContentUtils @@ -57,39 +57,39 @@ proc onLine(navigator: ptr Navigator): bool {.jsfget.} = # NavigatorCookies # "this website needs cookies to be enabled to function correctly" # It's probably better to lie here. -proc cookieEnabled(navigator: ptr Navigator): bool {.jsfget.} = true +proc cookieEnabled(navigator: var Navigator): bool {.jsfget.} = true # NavigatorPlugins -proc pdfViewerEnabled(navigator: ptr Navigator): bool {.jsfget.} = false -proc javaEnabled(navigator: ptr Navigator): bool {.jsfunc.} = false -proc namedItem(pluginArray: ptr PluginArray): string {.jsfunc.} = "" -proc namedItem(mimeTypeArray: ptr MimeTypeArray): string {.jsfunc.} = "" -proc item(pluginArray: ptr PluginArray): JSValue {.jsfunc.} = JS_NULL -proc length(pluginArray: ptr PluginArray): uint32 {.jsfget.} = 0 -proc item(mimeTypeArray: ptr MimeTypeArray): JSValue {.jsfunc.} = JS_NULL -proc length(mimeTypeArray: ptr MimeTypeArray): uint32 {.jsfget.} = 0 -proc getter(pluginArray: ptr PluginArray; i: uint32): Option[JSValue] +proc pdfViewerEnabled(navigator: var Navigator): bool {.jsfget.} = false +proc javaEnabled(navigator: var Navigator): bool {.jsfunc.} = false +proc namedItem(pluginArray: var PluginArray): string {.jsfunc.} = "" +proc namedItem(mimeTypeArray: var MimeTypeArray): string {.jsfunc.} = "" +proc item(pluginArray: var PluginArray): JSValue {.jsfunc.} = JS_NULL +proc length(pluginArray: var PluginArray): uint32 {.jsfget.} = 0 +proc item(mimeTypeArray: var MimeTypeArray): JSValue {.jsfunc.} = JS_NULL +proc length(mimeTypeArray: var MimeTypeArray): uint32 {.jsfget.} = 0 +proc getter(pluginArray: var PluginArray; i: uint32): Option[JSValue] {.jsgetprop.} = discard -proc getter(mimeTypeArray: ptr MimeTypeArray; i: uint32): Option[JSValue] +proc getter(mimeTypeArray: var MimeTypeArray; i: uint32): Option[JSValue] {.jsgetprop.} = discard # Screen -proc availWidth(screen: ptr Screen): int64 {.jsfget.} = +proc availWidth(screen: var Screen): int64 {.jsfget.} = #TODO this is a fingerprinting vector, but users should be able to allow it # selectively # for now just return something standard-ish 80 * 9 -proc availHeight(screen: ptr Screen): int64 {.jsfget.} = +proc availHeight(screen: var Screen): int64 {.jsfget.} = #TODO see above 24 * 18 -proc width(screen: ptr Screen): int64 {.jsfget.} = +proc width(screen: var Screen): int64 {.jsfget.} = screen.availWidth -proc height(screen: ptr Screen): int64 {.jsfget.} = +proc height(screen: var Screen): int64 {.jsfget.} = screen.availHeight -proc colorDepth(screen: ptr Screen): int64 {.jsfget.} = 24 -proc pixelDepth(screen: ptr Screen): int64 {.jsfget.} = screen.colorDepth +proc colorDepth(screen: var Screen): int64 {.jsfget.} = 24 +proc pixelDepth(screen: var Screen): int64 {.jsfget.} = screen.colorDepth proc addNavigatorModule(ctx: JSContext) = ctx.registerType(Navigator) @@ -122,9 +122,9 @@ proc screenY(window: Window): int64 {.jsfget.} = 0 proc screenLeft(window: Window): int64 {.jsfget.} = 0 proc screenTop(window: Window): int64 {.jsfget.} = 0 proc outerWidth(window: Window): int64 {.jsfget.} = - (addr window.screen).availWidth + window.screen.availWidth proc outerHeight(window: Window): int64 {.jsfget.} = - (addr window.screen).availHeight + window.screen.availHeight proc devicePixelRatio(window: Window): float64 {.jsfget.} = 1 proc setLocation(window: Window; s: string): Err[JSError] diff --git a/src/js/fromjs.nim b/src/js/fromjs.nim index ccf8abcb..055ae19e 100644 --- a/src/js/fromjs.nim +++ b/src/js/fromjs.nim @@ -98,6 +98,9 @@ func fromJSInt[T: SomeInteger](ctx: JSContext; val: JSValue): if JS_ToUint32(ctx, addr ret, val) < 0: return err() return ok(ret) + else: + static: + error($T & " cannot be converted to JS automatically") proc fromJSFloat64(ctx: JSContext; val: JSValue): JSResult[float64] = var f64: float64 diff --git a/src/js/javascript.nim b/src/js/javascript.nim index 2427b6a8..bfe45aae 100644 --- a/src/js/javascript.nim +++ b/src/js/javascript.nim @@ -334,6 +334,7 @@ type FuncParam = tuple t: NimNode val: Option[NimNode] generic: Option[NimNode] + isptr: bool func getMinArgs(params: seq[FuncParam]): int = for i in 0..<params.len: @@ -447,7 +448,8 @@ proc getParams(fun: NimNode): seq[FuncParam] = typeof(`x`) else: error("?? " & treeRepr(it)) - if t.kind in {nnkRefTy, nnkPtrTy}: + let isptr = t.kind == nnkVarTy + if t.kind in {nnkRefTy, nnkVarTy}: t = t[0] let val = if it[^1].kind != nnkEmpty: let x = it[^1] @@ -457,7 +459,7 @@ proc getParams(fun: NimNode): seq[FuncParam] = var g = none(NimNode) for i in 0 ..< it.len - 2: let name = $it[i] - funcParams.add((name, t, val, g)) + funcParams.add((name, t, val, g, isptr)) funcParams proc getReturn(fun: NimNode): Option[NimNode] = @@ -716,46 +718,46 @@ proc addUnionParam(gen: var JSFuncGenerator; tt, s: NimNode; gen.addUnionParam0(tt, s, quote do: argv[`j`], fallback) proc addFixParam(gen: var JSFuncGenerator; name: string) = - let s = ident("arg_" & $gen.i) - let t = gen.funcParams[gen.i][1] + var s = ident("arg_" & $gen.i) + let t = gen.funcParams[gen.i].t let id = ident(name) if t.typeKind == ntyGenericParam: gen.addUnionParam0(t, s, id) else: gen.addParam2(s, t, id) - if gen.jsFunCall != nil: - gen.jsFunCall.add(s) + if gen.funcParams[gen.i].isptr: + s = quote do: `s`[] + gen.jsFunCall.add(s) inc gen.i proc addRequiredParams(gen: var JSFuncGenerator) = while gen.i < gen.minArgs: - let s = ident("arg_" & $gen.i) - let tt = gen.funcParams[gen.i][1] + var s = ident("arg_" & $gen.i) + let tt = gen.funcParams[gen.i].t if tt.typeKind == ntyGenericParam: gen.addUnionParam(tt, s) else: gen.addValueParam(s, tt) - if gen.jsFunCall != nil: - gen.jsFunCall.add(s) + if gen.funcParams[gen.i].isptr: + s = quote do: `s`[] + gen.jsFunCall.add(s) inc gen.j inc gen.i proc addOptionalParams(gen: var JSFuncGenerator) = while gen.i < gen.funcParams.len: let j = gen.j - let s = ident("arg_" & $gen.i) - let tt = gen.funcParams[gen.i][1] + var s = ident("arg_" & $gen.i) + let tt = gen.funcParams[gen.i].t if tt.typeKind == varargs.getType().typeKind: # pray it's not a generic... let vt = tt[1].getType() for i in 0..gen.jsFunCallLists.high: gen.jsFunCallLists[i].add(newLetStmt(s, quote do: - ( - var valist: seq[`vt`] - for i in `j`..<argc: - let it = fromJS_or_return(`vt`, ctx, argv[i]) - valist.add(it) - valist - ) + var valist: seq[`vt`] = @[] + for i in `j`..<argc: + let it = fromJS_or_return(`vt`, ctx, argv[i]) + valist.add(it) + valist )) else: if gen.funcParams[gen.i][2].isNone: @@ -766,8 +768,9 @@ proc addOptionalParams(gen: var JSFuncGenerator) = gen.addUnionParam(tt, s, fallback) else: gen.addValueParam(s, tt, fallback) - if gen.jsFunCall != nil: - gen.jsFunCall.add(s) + if gen.funcParams[gen.i].isptr: + s = quote do: `s`[] + gen.jsFunCall.add(s) inc gen.j inc gen.i @@ -868,8 +871,8 @@ proc addJSContext(gen: var JSFuncGenerator) = proc addThisName(gen: var JSFuncGenerator; thisname: Option[string]) = if thisname.isSome: - gen.thisTypeNode = gen.funcParams[gen.i][1] - gen.thisType = $gen.funcParams[gen.i][1] + gen.thisTypeNode = gen.funcParams[gen.i].t + gen.thisType = $gen.funcParams[gen.i].t gen.newName = ident($gen.t & "_" & gen.thisType & "_" & gen.funcName) else: let rt = gen.returnType.get @@ -1597,9 +1600,9 @@ proc bindEndStmts(endstmts: NimNode; info: RegistryInfo) = ) let `classDef` = JSClassDefConst(addr cd)) -macro registerType*(ctx: typed; t: typed; parent: JSClassID = 0; - asglobal: static bool = false; nointerface = false; name: static string = ""; - has_extra_getset: static bool = false; +macro registerType*(ctx: JSContext; t: typed; parent: JSClassID = 0; + asglobal: static bool = false; nointerface = false; + name: static string = ""; has_extra_getset: static bool = false; extra_getset: static openArray[TabGetSet] = []; namespace = JS_NULL; errid = opt(JSErrorEnum); ishtmldda = false): JSClassID = var stmts = newStmtList() |