diff options
-rw-r--r-- | src/buffer/buffer.nim | 29 | ||||
-rw-r--r-- | src/display/client.nim | 2 | ||||
-rw-r--r-- | src/html/dom.nim | 7 | ||||
-rw-r--r-- | src/html/env.nim | 2 | ||||
-rw-r--r-- | src/io/loader.nim | 16 | ||||
-rw-r--r-- | src/io/response.nim | 2 | ||||
-rw-r--r-- | src/js/javascript.nim | 2 |
7 files changed, 33 insertions, 27 deletions
diff --git a/src/buffer/buffer.nim b/src/buffer/buffer.nim index 74f0545e..e8f8eaaa 100644 --- a/src/buffer/buffer.nim +++ b/src/buffer/buffer.nim @@ -34,6 +34,7 @@ import io/window import ips/serialize import ips/serversocket import ips/socketstream +import js/javascript import js/regex import js/timeout import layout/box @@ -560,14 +561,15 @@ proc loadResource(buffer: Buffer, elem: HTMLLinkElement): EmptyPromise = let cvals = parseListOfComponentValues(newStringStream(media)) let media = parseMediaQueryList(cvals) if not media.applies(document.window): return - return buffer.loader.fetch(newRequest(url)).then(proc(res: Response): - Opt[Promise[string]] = - if res.res == 0: #TODO remove res - #TODO we should use ReadableStreams for this (which would allow us to - # parse CSS asynchronously) - if res.contenttype == "text/css": - return ok(res.text()) - res.unregisterFun() + return buffer.loader.fetch(newRequest(url)) + .then(proc(res: Result[Response, JSError]): Opt[Promise[string]] = + if res.isOk: + let res = res.get + #TODO we should use ReadableStreams for this (which would allow us to + # parse CSS asynchronously) + if res.contenttype == "text/css": + return ok(res.text()) + res.unregisterFun() ).then(proc(s: Opt[string]) = if s.isOk: #TODO this is extremely inefficient, and text() should return @@ -585,10 +587,13 @@ proc loadResource(buffer: Buffer, elem: HTMLImageElement): EmptyPromise = let url = parseURL(src, document.url.some) if url.isSome: let url = url.get - return buffer.loader.fetch(newRequest(url)).then(proc(res: Response): Promise[string] = - if res.contenttype == "image/png": - #TODO using text() for PNG is wrong - return res.text() + return buffer.loader.fetch(newRequest(url)) + .then(proc(res: Result[Response, JSError]): Promise[string] = + if res.isOk: + let res = res.get + if res.contenttype == "image/png": + #TODO using text() for PNG is wrong + return res.text() ).then(proc(pngData: string) = elem.bitmap = fromPNG(toOpenArrayByte(pngData, 0, pngData.high))) diff --git a/src/display/client.nim b/src/display/client.nim index af4b3fb2..1c9e0b1f 100644 --- a/src/display/client.nim +++ b/src/display/client.nim @@ -91,7 +91,7 @@ proc `=destroy`(client: var ClientObj) = proc doRequest(client: Client, req: Request): Response {.jsfunc.} = return client.loader.doRequest(req) -proc fetch(client: Client, req: Request): Promise[Response] {.jsfunc.} = +proc fetch(client: Client, req: Request): FetchPromise {.jsfunc.} = return client.loader.fetch(req) proc interruptHandler(rt: JSRuntime, opaque: pointer): int {.cdecl.} = diff --git a/src/html/dom.nim b/src/html/dom.nim index 1fa3b043..3bf67b05 100644 --- a/src/html/dom.nim +++ b/src/html/dom.nim @@ -2396,14 +2396,13 @@ proc fetchClassicScript(element: HTMLScriptElement, url: URL, let loader = element.document.window.loader if loader.isSome: let request = createPotentialCORSRequest(url, RequestDestination.SCRIPT, cors) - loader.get.fetch(request).then(proc(r: Response): auto = - if r.res != 0 or r.body == nil: - #TODO remove res + loader.get.fetch(request).then(proc(r: Result[Response, JSError]): auto = + if r.isErr or r.get.body == nil: element.onComplete(ScriptResult(t: RESULT_NULL)) else: #TODO use charset from content-type #TODO text() should decode - return r.text() + return r.get.text() ).then(proc(s: string) = let ss = newStringStream(s) #TODO unnecessary copy let cs = if cs == CHARSET_UNKNOWN: CHARSET_UTF_8 else: cs diff --git a/src/html/env.nim b/src/html/env.nim index a70508be..eba067a8 100644 --- a/src/html/env.nim +++ b/src/html/env.nim @@ -61,7 +61,7 @@ proc addNavigatorModule(ctx: JSContext) = ctx.registerType(PluginArray) ctx.registerType(MimeTypeArray) -proc fetch(window: Window, req: Request): Promise[Response] {.jsfunc.} = +proc fetch(window: Window, req: Request): FetchPromise {.jsfunc.} = if window.loader.isSome: return window.loader.get.fetch(req) diff --git a/src/io/loader.nim b/src/io/loader.nim index 1b5d8847..9f2682d9 100644 --- a/src/io/loader.nim +++ b/src/io/loader.nim @@ -31,6 +31,7 @@ import io/urlfilter import ips/serialize import ips/serversocket import ips/socketstream +import js/exception import js/javascript import types/cookie import types/mime @@ -51,7 +52,7 @@ type unregisterFun*: proc(fd: int) ConnectData = object - promise: Promise[Response] + promise: Promise[Result[Response, JSError]] stream: Stream request: Request @@ -83,6 +84,8 @@ type cookiejar*: CookieJar referrerpolicy*: ReferrerPolicy + FetchPromise* = Promise[Result[Response, JSError]] + converter toInt*(code: ConnectErrorCode): int = return int(code) @@ -249,14 +252,14 @@ proc applyHeaders(request: Request, response: Response) = destination = request.destination) #TODO: add init -proc fetch*(loader: FileLoader, input: Request): Promise[Response] = +proc fetch*(loader: FileLoader, input: Request): FetchPromise = let stream = connectSocketStream(loader.process, false, blocking = true) stream.swrite(LOAD) stream.swrite(input) stream.flush() let fd = int(stream.source.getFd()) loader.registerFun(fd) - let promise = Promise[Response]() + let promise = FetchPromise() loader.connecting[fd] = ConnectData( promise: promise, request: input, @@ -292,13 +295,12 @@ proc onConnected*(loader: FileLoader, fd: int) = readbufsize: BufferSize, ) SocketStream(stream).source.getFd().setBlocking(false) - promise.resolve(response) + promise.resolve(Result[Response, JSError].ok(response)) else: loader.unregisterFun(fd) loader.unregistered.add(fd) - #TODO: reject promise instead. - let response = newResponse(res, request) - promise.resolve(response) + let err = newTypeError("NetworkError when attempting to fetch resource") + promise.resolve(Result[Response, JSError].err(err)) loader.connecting.del(fd) proc onRead*(loader: FileLoader, fd: int) = diff --git a/src/io/response.nim b/src/io/response.nim index 7d0f789a..ae418318 100644 --- a/src/io/response.nim +++ b/src/io/response.nim @@ -11,7 +11,7 @@ type fd*: int body*: Stream bodyUsed* {.jsget.}: bool - res* {.jsget.}: int + res*: int contenttype* {.jsget.}: string status* {.jsget.}: int headers* {.jsget.}: Headers diff --git a/src/js/javascript.nim b/src/js/javascript.nim index ced12bf7..c1028537 100644 --- a/src/js/javascript.nim +++ b/src/js/javascript.nim @@ -932,7 +932,7 @@ proc toJS[T, E](ctx: JSContext, promise: Promise[Result[T, E]]): JSValue = let x = when E is void: JS_UNDEFINED else: - toJS(ctx, x.get) + toJS(ctx, x.error) let res = JS_Call(ctx, resolving_funcs[1], JS_UNDEFINED, 1, unsafeAddr x) JS_FreeValue(ctx, res) JS_FreeValue(ctx, x) |