diff options
-rw-r--r-- | src/html/dom.nim | 14 | ||||
-rw-r--r-- | src/io/request.nim | 10 | ||||
-rw-r--r-- | src/js/intl.nim | 2 | ||||
-rw-r--r-- | src/js/javascript.nim | 6 | ||||
-rw-r--r-- | src/types/blob.nim | 44 | ||||
-rw-r--r-- | src/xhr/formdata.nim | 14 |
6 files changed, 62 insertions, 28 deletions
diff --git a/src/html/dom.nim b/src/html/dom.nim index 190dd479..b022d858 100644 --- a/src/html/dom.nim +++ b/src/html/dom.nim @@ -370,7 +370,8 @@ proc resetState(state: var DrawingState) = state.strokeStyle = rgba(0, 0, 0, 255) state.path = newPath() -proc create2DContext*(target: HTMLCanvasElement, options: Option[JSObject]): +proc create2DContext*(jctx: JSContext, target: HTMLCanvasElement, + options: Option[JSValue]): CanvasRenderingContext2D = let ctx = CanvasRenderingContext2D( bitmap: target.bitmap, @@ -2720,23 +2721,22 @@ func getElementReflectFunctions(): seq[TabGetSet] = result.add(TabGetSet(name: ReflectTable[i].funcname, get: jsReflectGet, set: jsReflectSet, magic: i)) inc i -proc getContext*(this: HTMLCanvasElement, contextId: string, - options = none(JSObject)): RenderingContext {.jsfunc.} = +proc getContext*(jctx: JSContext, this: HTMLCanvasElement, contextId: string, + options = none(JSValue)): RenderingContext {.jsfunc.} = if contextId == "2d": if this.ctx2d != nil: return this.ctx2d - return create2DContext(this, options) + return create2DContext(jctx, this, options) return nil #TODO quality should be `any' -proc toBlob(this: HTMLCanvasElement, callback: JSObject, +proc toBlob(ctx: JSContext, this: HTMLCanvasElement, callback: JSValue, s = "image/png", quality: float64 = 1): JSValue {.jsfunc.} = - let ctx = callback.ctx var outlen: int let buf = this.bitmap.toPNG(outlen) let blob = newBlob(buf, outlen, "image/png", dealloc) var jsBlob = toJS(ctx, blob) - let res = JS_Call(ctx, callback.val, JS_UNDEFINED, 1, addr jsBlob) + let res = JS_Call(ctx, callback, JS_UNDEFINED, 1, addr jsBlob) # Hack. TODO: implement JSValue to callback if res == JS_EXCEPTION: return JS_EXCEPTION diff --git a/src/io/request.nim b/src/io/request.nim index 08947bd5..ed38ad47 100644 --- a/src/io/request.nim +++ b/src/io/request.nim @@ -186,10 +186,13 @@ proc fill(headers: Headers, ctx: JSContext, val: JSValue) = else: headers.table[k] = @[v] -func newHeaders*(obj = none(JSObject)): Headers {.jsctor.} = +func newHeaders*(): Headers = + new(result) + +func newHeaders*(ctx: JSContext, obj = none(JSValue)): Headers {.jsctor.} = new(result) if obj.isSome: - result.fill(obj.get.ctx, obj.get.val) + result.fill(ctx, obj.get) func newHeaders*(table: Table[string, string]): Headers = new(result) @@ -239,8 +242,7 @@ func createPotentialCORSRequest*(url: URL, destination: RequestDestination, cors return newRequest(url, destination = destination, mode = mode, credentialsMode = credentialsMode) #TODO resource as Request -#TODO also, I'm not sure what to do with init. For now I've re-introduced -# JSObject to make this work, but I really wish we had a better solution. +#TODO init as an actual dictionary func newRequest*(ctx: JSContext, resource: string, init = none(JSValue)): Request {.jserr, jsctor.} = let x = parseURL(resource) diff --git a/src/js/intl.nim b/src/js/intl.nim index 28cc42d5..f37789ad 100644 --- a/src/js/intl.nim +++ b/src/js/intl.nim @@ -8,7 +8,7 @@ type #TODO ...yeah proc newNumberFormat(name: string = "en-US", - options = none(JSObject)): NumberFormat {.jsctor.} = + options = none(JSValue)): NumberFormat {.jsctor.} = return NumberFormat() #TODO: this should accept string/BigInt too diff --git a/src/js/javascript.nim b/src/js/javascript.nim index 4eefd1b6..17bc555a 100644 --- a/src/js/javascript.nim +++ b/src/js/javascript.nim @@ -85,10 +85,6 @@ type JSFunctionList* = openArray[JSCFunctionListEntry] - JSObject* = object - ctx*: JSContext - val*: JSValue - func getOpaque*(ctx: JSContext): JSContextOpaque = return cast[JSContextOpaque](JS_GetContextOpaque(ctx)) @@ -703,8 +699,6 @@ proc fromJS*[T](ctx: JSContext, val: JSValue): Option[T] = return none(T) elif T is JSValue: return some(val) - elif T is JSObject: - return some(JSObject(ctx: ctx, val: val)) elif T is object: doAssert false, "Dictionary case has not been implemented yet!" #TODO TODO TODO implement dictionary case diff --git a/src/types/blob.nim b/src/types/blob.nim index 677fb037..4a5627c3 100644 --- a/src/types/blob.nim +++ b/src/types/blob.nim @@ -1,3 +1,5 @@ +import options + import js/javascript import types/mime import utils/twtstr @@ -37,17 +39,47 @@ proc newWebFile*(path: string, webkitRelativePath = ""): WebFile = isfile: true, path: path, file: file, + ctype: guessContentType(path), webkitRelativePath: webkitRelativePath ) +proc newWebFile(ctx: JSContext, fileBits: seq[string], fileName: string, + options = none(JSValue)): WebFile {.jsctor.} = + let file = WebFile( + isfile: false, + path: fileName, + deallocFun: dealloc + ) + var len = 0 + for blobPart in fileBits: + len += blobPart.len + file.buffer = alloc(len) + var buf = cast[ptr UncheckedArray[uint8]](file.buffer) + var i = 0 + for blobPart in fileBits: + if blobPart.len > 0: + copyMem(addr buf[i], unsafeAddr blobPart[0], blobPart.len) + i += blobPart.len + file.size = uint64(len) + if options.isSome: + block ctype: + let t = fromJS[string](ctx, JS_GetPropertyStr(ctx, options.get, "type")) + if t.isNone: + break ctype + for c in t.get: + if c notin char(0x20)..char(0x7E): + break ctype + file.ctype &= c.tolower() + #TODO lastmodified + return file + #TODO File, Blob constructors func size*(this: WebFile): uint64 {.jsfget.} = #TODO use stat instead - return uint64(this.file.getFileSize()) - -func ctype*(this: WebFile): string {.jsfget: "type".} = - return guessContentType(this.path) + if this.isfile: + return uint64(this.file.getFileSize()) + return this.size func name*(this: WebFile): string {.jsfget.} = if this.path.len > 0 and this.path[^1] != '/': @@ -57,5 +89,5 @@ func name*(this: WebFile): string {.jsfget.} = #TODO lastModified proc addBlobModule*(ctx: JSContext) = - ctx.registerType(Blob) - ctx.registerType(WebFile, name = "File") + let blobCID = ctx.registerType(Blob) + ctx.registerType(WebFile, parent = blobCID, name = "File") diff --git a/src/xhr/formdata.nim b/src/xhr/formdata.nim index 9b45e7ba..cbb9f63e 100644 --- a/src/xhr/formdata.nim +++ b/src/xhr/formdata.nim @@ -40,13 +40,19 @@ proc append*(this: FormData, name: string, value: Blob, )) #TODO hack -proc append(this: FormData, name: string, value: JSObject, +proc append(ctx: JSContext, this: FormData, name: string, value: JSValue, filename = none(string)) {.jsfunc.} = - let blob = fromJS[Blob](value.ctx, value.val) + let blob = fromJS[Blob](ctx, value) if blob.isSome: - this.append(name, blob.get, filename.get("blob")) + let filename = if filename.isSome: + filename.get + elif blob.get of WebFile: + WebFile(blob.get).name + else: + "blob" + this.append(name, blob.get, filename) else: - let s = fromJS[string](value.ctx, value.val) + let s = fromJS[string](ctx, value) # toString should never fail (?) this.append(name, s.get, filename.get("")) |