diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/config/config.nim | 18 | ||||
-rw-r--r-- | src/config/mailcap.nim | 3 | ||||
-rw-r--r-- | src/extern/runproc.nim | 2 | ||||
-rw-r--r-- | src/html/dom.nim | 18 | ||||
-rw-r--r-- | src/layout/renderdocument.nim (renamed from src/render/renderdocument.nim) | 0 | ||||
-rw-r--r-- | src/local/client.nim | 12 | ||||
-rw-r--r-- | src/local/pager.nim | 121 | ||||
-rw-r--r-- | src/render/rendertext.nim | 121 | ||||
-rw-r--r-- | src/server/buffer.nim | 147 |
9 files changed, 182 insertions, 260 deletions
diff --git a/src/config/config.nim b/src/config/config.nim index 82200334..1ae0a727 100644 --- a/src/config/config.nim +++ b/src/config/config.nim @@ -357,12 +357,12 @@ proc readUserStylesheet(dir, file: string): string = # of several individual configuration files known as mailcap files. proc getMailcap*(config: Config): tuple[mailcap: Mailcap, errs: seq[string]] = let configDir = getConfigDir() / "chawan" #TODO store this in config? - const gopherPath0 = ChaPath("${%CHA_LIBEXEC_DIR}/gopher2html -u \\$MAILCAP_URL") - let gopherPath = gopherPath0.unquote().get - const geminiPath0 = ChaPath("${%CHA_LIBEXEC_DIR}/gmi2html") - let geminiPath = geminiPath0.unquote().get - const mdPath0 = ChaPath("${%CHA_LIBEXEC_DIR}/md2html") - let mdPath = mdPath0.unquote().get + template uq(s: string): string = + ChaPath(s).unquote.get + let gopherPath = "${%CHA_LIBEXEC_DIR}/gopher2html -u \\$MAILCAP_URL".uq + let geminiPath = "${%CHA_LIBEXEC_DIR}/gmi2html".uq + let mdPath = "${%CHA_LIBEXEC_DIR}/md2html".uq + let ansiPath = "${%CHA_LIBEXEC_DIR}/ansi2html".uq var mailcap: Mailcap = @[] var errs: seq[string] var found = false @@ -393,6 +393,12 @@ proc getMailcap*(config: Config): tuple[mailcap: Mailcap, errs: seq[string]] = cmd: mdPath, flags: {HTMLOUTPUT} )) + mailcap.add(MailcapEntry( + mt: "text", + subt: "x-ansi", + cmd: ansiPath, + flags: {HTMLOUTPUT} + )) if not found: mailcap.add(MailcapEntry( mt: "*", diff --git a/src/config/mailcap.nim b/src/config/mailcap.nim index d5d17eae..89d268db 100644 --- a/src/config/mailcap.nim +++ b/src/config/mailcap.nim @@ -20,6 +20,7 @@ type NEEDSTERMINAL = "needsterminal" COPIOUSOUTPUT = "copiousoutput" HTMLOUTPUT = "x-htmloutput" # from w3m + ANSIOUTPUT = "x-ansioutput" # Chawan extension MailcapEntry* = object mt*: string @@ -122,6 +123,8 @@ proc parseFieldKey(entry: var MailcapEntry, k: string): NamedField = entry.flags.incl(COPIOUSOUTPUT) of "x-htmloutput": entry.flags.incl(HTMLOUTPUT) + of "x-ansioutput": + entry.flags.incl(ANSIOUTPUT) of "test": return NAMED_FIELD_TEST of "nametemplate": diff --git a/src/extern/runproc.nim b/src/extern/runproc.nim index 7982dbda..9d189dff 100644 --- a/src/extern/runproc.nim +++ b/src/extern/runproc.nim @@ -55,4 +55,4 @@ proc runProcessInto*(cmd, ins: string): bool = proc myExec*(cmd: string) = discard execl("/bin/sh", "sh", "-c", cmd, nil) - quit(127) + exitnow(127) diff --git a/src/html/dom.nim b/src/html/dom.nim index f8ddaad5..1104ee90 100644 --- a/src/html/dom.nim +++ b/src/html/dom.nim @@ -1781,21 +1781,19 @@ proc write(document: Document, text: varargs[string]): Err[DOMException] CDB_parseDocumentWriteChunk(document.parser) return ok() -func html*(document: Document): HTMLElement = - for element in document.elements(TAG_HTML): +func findFirst*(document: Document, tagType: TagType): HTMLElement = + for element in document.elements(tagType): return HTMLElement(element) + nil + +func html*(document: Document): HTMLElement = + return document.findFirst(TAG_HTML) func head*(document: Document): HTMLElement {.jsfget.} = - let html = document.html - if html != nil: - for element in html.elements(TAG_HEAD): - return HTMLElement(element) + return document.findFirst(TAG_HEAD) func body*(document: Document): HTMLElement {.jsfget.} = - let html = document.html - if html != nil: - for element in html.elements(TAG_BODY): - return HTMLElement(element) + return document.findFirst(TAG_BODY) func select*(option: HTMLOptionElement): HTMLSelectElement = for anc in option.ancestors: diff --git a/src/render/renderdocument.nim b/src/layout/renderdocument.nim index 7526b111..7526b111 100644 --- a/src/render/renderdocument.nim +++ b/src/layout/renderdocument.nim diff --git a/src/local/client.nim b/src/local/client.nim index e0a453db..71aaac8c 100644 --- a/src/local/client.nim +++ b/src/local/client.nim @@ -527,8 +527,8 @@ proc addConsole(pager: Pager, interactive: bool, clearFun, showFun, hideFun: if pipe(pipefd) == -1: raise newException(Defect, "Failed to open console pipe.") let url = newURL("stream:console").get - let container = pager.readPipe0(some("text/plain"), CHARSET_UNKNOWN, - pipefd[0], some(url), ConsoleTitle, canreinterpret = false) + let container = pager.readPipe0("text/plain", CHARSET_UNKNOWN, pipefd[0], + some(url), ConsoleTitle, canreinterpret = false) let err = newPosixStream(pipefd[1]) err.writeLine("Type (M-c) console.hide() to return to buffer mode.") err.flush() @@ -555,8 +555,8 @@ proc clearConsole(client: Client) = raise newException(Defect, "Failed to open console pipe.") let url = newURL("stream:console").get let pager = client.pager - let replacement = pager.readPipe0(some("text/plain"), CHARSET_UNKNOWN, - pipefd[0], some(url), ConsoleTitle, canreinterpret = false) + let replacement = pager.readPipe0("text/plain", CHARSET_UNKNOWN, pipefd[0], + some(url), ConsoleTitle, canreinterpret = false) replacement.replace = client.consoleWrapper.container pager.registerContainer(replacement) client.consoleWrapper.container = replacement @@ -621,10 +621,10 @@ proc launchClient*(client: Client, pages: seq[string], let ismodule = client.config.start.startup_script.endsWith(".mjs") client.command0(s, client.config.start.startup_script, silence = true, module = ismodule) - if not stdin.isatty(): + # stdin may very well receive ANSI text + let contentType = contentType.get("text/x-ansi") client.pager.readPipe(contentType, cs, stdin.getFileHandle(), "*stdin*") - for page in pages: client.pager.loadURL(page, ctype = contentType, cs = cs) client.pager.showAlerts() diff --git a/src/local/pager.nim b/src/local/pager.nim index c279faac..62746a4e 100644 --- a/src/local/pager.nim +++ b/src/local/pager.nim @@ -761,7 +761,7 @@ proc loadURL*(pager: Pager, url: string, ctype = none(string), if pager.container != prevc: pager.container.retry = urls -proc readPipe0*(pager: Pager, ctype: Option[string], cs: Charset, +proc readPipe0*(pager: Pager, contentType: string, cs: Charset, fd: FileHandle, location: Option[URL], title: string, canreinterpret: bool): Container = var location = location.get(newURL("stream:-").get) @@ -773,12 +773,12 @@ proc readPipe0*(pager: Pager, ctype: Option[string], cs: Charset, title = title, canreinterpret = canreinterpret, fd = fd, - contentType = some(ctype.get("text/plain")) + contentType = some(contentType) ) -proc readPipe*(pager: Pager, ctype: Option[string], cs: Charset, fd: FileHandle, +proc readPipe*(pager: Pager, contentType: string, cs: Charset, fd: FileHandle, title: string) = - let container = pager.readPipe0(ctype, cs, fd, none(URL), title, true) + let container = pager.readPipe0(contentType, cs, fd, none(URL), title, true) inc pager.numload pager.addContainer(container) @@ -948,45 +948,85 @@ proc authorize(pager: Pager) = type CheckMailcapResult = tuple[promise: EmptyPromise, connect: bool] +proc checkMailcap(pager: Pager, container: Container, + contentTypeOverride = none(string)): CheckMailcapResult + +# Pipe output of an x-ansioutput mailcap command to the text/x-ansi handler. +proc ansiDecode(pager: Pager, container: Container, fdin: cint, + ishtml: var bool, fdout: var cint) = + let cs = container.charset + let url = container.location + let entry = pager.mailcap.getMailcapEntry("text/x-ansi", "", url, cs) + var canpipe = true + let cmd = unquoteCommand(entry.cmd, "text/x-ansi", "", url, cs, canpipe) + if not canpipe: + pager.alert("Error: could not pipe to text/x-ansi, decoding as text/plain") + else: + var pipefdOutAnsi: array[2, cint] + if pipe(pipefdOutAnsi) == -1: + raise newException(Defect, "Failed to open pipe.") + case fork() + of -1: + pager.alert("Error: failed to fork ANSI decoder process") + discard close(pipefdOutAnsi[0]) + discard close(pipefdOutAnsi[1]) + of 0: # child process + if fdin != -1: + discard close(fdin) + discard close(pipefdOutAnsi[0]) + discard dup2(fdout, stdin.getFileHandle()) + discard close(fdout) + discard dup2(pipefdOutAnsi[1], stdout.getFileHandle()) + discard close(pipefdOutAnsi[1]) + closeStderr() + myExec(cmd) + assert false + else: + discard close(pipefdOutAnsi[1]) + discard close(fdout) + fdout = pipefdOutAnsi[0] + ishtml = HTMLOUTPUT in entry.flags + # Pipe input into the mailcap command, then read its output into a buffer. # needsterminal is ignored. proc runMailcapReadPipe(pager: Pager, container: Container, entry: MailcapEntry, cmd: string): CheckMailcapResult = - var pipefd_in: array[2, cint] - if pipe(pipefd_in) == -1: - raise newException(Defect, "Failed to open pipe.") - var pipefd_out: array[2, cint] - if pipe(pipefd_out) == -1: + var pipefdIn: array[2, cint] + var pipefdOut: array[2, cint] + if pipe(pipefdIn) == -1 or pipe(pipefdOut) == -1: raise newException(Defect, "Failed to open pipe.") let pid = fork() if pid == -1: + pager.alert("Failed to fork process!") return (nil, false) - elif pid == 0: - # child process - discard close(pipefd_in[1]) - discard close(pipefd_out[0]) - stdout.flushFile() - discard dup2(pipefd_in[0], stdin.getFileHandle()) - discard dup2(pipefd_out[1], stdout.getFileHandle()) + elif pid == 0: # child process + discard close(pipefdIn[1]) + discard close(pipefdOut[0]) + discard dup2(pipefdIn[0], stdin.getFileHandle()) + discard dup2(pipefdOut[1], stdout.getFileHandle()) closeStderr() - discard close(pipefd_in[0]) - discard close(pipefd_out[1]) + discard close(pipefdIn[0]) + discard close(pipefdOut[1]) myExec(cmd) assert false - # parent - discard close(pipefd_in[0]) - discard close(pipefd_out[1]) - let fdin = pipefd_in[1] - let fdout = pipefd_out[0] - let p = container.redirectToFd(fdin, wait = false, cache = true) - let p2 = p.then(proc(): auto = + else: + # parent + discard close(pipefdIn[0]) + discard close(pipefdOut[1]) + let fdin = pipefdIn[1] + var fdout = pipefdOut[0] + var ishtml = HTMLOUTPUT in entry.flags + if not ishtml and ANSIOUTPUT in entry.flags: + # decode ANSI sequence + pager.ansiDecode(container, fdin, ishtml, fdout) + let p = container.redirectToFd(fdin, wait = false, cache = true) discard close(fdin) - let ishtml = HTMLOUTPUT in entry.flags - return container.readFromFd(fdout, $pid, ishtml) - ).then(proc() = - discard close(fdout) - ) - return (p2, true) + let p2 = p.then(proc(): auto = + let p = container.readFromFd(fdout, $pid, ishtml) + discard close(fdout) + return p + ) + return (p2, true) # Pipe input into the mailcap command, and discard its output. # If needsterminal, leave stderr and stdout open and wait for the process. @@ -1048,11 +1088,13 @@ proc runMailcapReadFile(pager: Pager, container: Container, quit(ret) # parent discard close(pipefd[1]) - let fdout = pipefd[0] - let ishtml = HTMLOUTPUT in entry.flags - return container.readFromFd(fdout, $pid, ishtml).then(proc() = - discard close(fdout) - ) + var fdout = pipefd[0] + var ishtml = HTMLOUTPUT in entry.flags + if not ishtml and ANSIOUTPUT in entry.flags: + pager.ansiDecode(container, -1, ishtml, fdout) + let p = container.readFromFd(fdout, $pid, ishtml) + discard close(fdout) + return p ) return (p, true) @@ -1134,12 +1176,13 @@ proc filterBuffer(pager: Pager, container: Container): CheckMailcapResult = # pager is suspended until the command exits. #TODO add support for edit/compose, better error handling (use Promise[bool] # instead of tuple[EmptyPromise, bool]) -proc checkMailcap(pager: Pager, container: Container): CheckMailcapResult = +proc checkMailcap(pager: Pager, container: Container, + contentTypeOverride = none(string)): CheckMailcapResult = if container.filter != nil: return pager.filterBuffer(container) if container.contentType.isNone: return (nil, true) - let contentType = container.contentType.get + let contentType = contentTypeOverride.get(container.contentType.get) if contentType == "text/html": # We support HTML natively, so it would make little sense to execute # mailcap filters for it. @@ -1164,7 +1207,7 @@ proc checkMailcap(pager: Pager, container: Container): CheckMailcapResult = var canpipe = true let cmd = unquoteCommand(entry.cmd, contentType, outpath, url, cs, canpipe) putEnv("MAILCAP_URL", $url) #TODO delEnv this after command is finished? - if {COPIOUSOUTPUT, HTMLOUTPUT} * entry.flags == {}: + if {COPIOUSOUTPUT, HTMLOUTPUT, ANSIOUTPUT} * entry.flags == {}: # no output. if canpipe: return pager.runMailcapWritePipe(container, entry[], cmd) diff --git a/src/render/rendertext.nim b/src/render/rendertext.nim deleted file mode 100644 index 27992215..00000000 --- a/src/render/rendertext.nim +++ /dev/null @@ -1,121 +0,0 @@ -import std/streams -import std/strutils -import std/unicode - -import types/cell -import utils/strwidth - -type StreamRenderer* = ref object - ansiparser: AnsiCodeParser - format: Format - af: bool - stream: Stream - newline: bool - w: int - j: int # byte in line - -proc newStreamRenderer*(): StreamRenderer = - return StreamRenderer(ansiparser: AnsiCodeParser(state: PARSE_DONE)) - -proc rewind*(renderer: StreamRenderer) = - renderer.format = Format() - renderer.ansiparser.state = PARSE_DONE - -proc addFormat(grid: var FlexibleGrid, renderer: StreamRenderer) = - if renderer.af: - renderer.af = false - if renderer.j == grid[^1].str.len: - grid[^1].addFormat(renderer.w, renderer.format) - -proc processBackspace(grid: var FlexibleGrid, renderer: StreamRenderer, - r: Rune): bool = - let pj = renderer.j - var cr: Rune - fastRuneAt(grid[^1].str, renderer.j, cr) - if r == Rune('_') or cr == Rune('_') or r == cr: - let flag = if r == cr: FLAG_BOLD else: FLAG_UNDERLINE - if r != cr and cr == Rune('_'): - # original is _, we must replace :( - # like less, we assume no double _ for double width characters. - grid[^1].str.delete(pj..<renderer.j) - let s = $r - grid[^1].str.insert(s, pj) - renderer.j = pj + s.len - let n = grid[^1].findFormatN(renderer.w) - 1 - if n != -1 and grid[^1].formats[n].pos == renderer.w: - let flags = grid[^1].formats[n].format.flags - if r == cr and r == Rune('_') and flag in flags: - # double overstrike of _, this is nonsensical on a teletype but less(1) - # treats it as an underline so we do that too - grid[^1].formats[n].format.flags.incl(FLAG_UNDERLINE) - else: - grid[^1].formats[n].format.flags.incl(flag) - elif n != -1: - var format = grid[^1].formats[n].format - format.flags.incl(flag) - grid[^1].insertFormat(renderer.w, n + 1, format) - else: - grid[^1].addFormat(renderer.w, Format(flags: {flag})) - renderer.w += r.twidth(renderer.w) - if renderer.j == grid[^1].str.len: - grid[^1].addFormat(renderer.w, Format()) - return true - let n = grid[^1].findFormatN(renderer.w) - grid[^1].formats.setLen(n) - grid[^1].str.setLen(renderer.j) - return false - -proc processAscii(grid: var FlexibleGrid, renderer: StreamRenderer, c: char) = - case c - of '\b': - if renderer.j == 0: - grid[^1].str &= c - inc renderer.j - renderer.w += Rune(c).twidth(renderer.w) - else: - let (r, len) = lastRune(grid[^1].str, grid[^1].str.high) - renderer.j -= len - renderer.w -= r.twidth(renderer.w) - of '\n': - grid.addFormat(renderer) - renderer.newline = true - of '\r': discard - of '\e': - renderer.ansiparser.reset() - else: - grid.addFormat(renderer) - grid[^1].str &= c - renderer.w += Rune(c).twidth(renderer.w) - inc renderer.j - -proc renderChunk*(grid: var FlexibleGrid, renderer: StreamRenderer, - buf: openArray[char]) = - if grid.len == 0: - grid.addLine() - var i = 0 - while i < buf.len: - if renderer.newline: - # avoid newline at end of stream - grid.addLine() - renderer.newline = false - renderer.w = 0 - renderer.j = 0 - let pi = i - var r: Rune - fastRuneAt(buf, i, r) - if renderer.j < grid[^1].str.len: - if grid.processBackspace(renderer, r): - continue - if uint32(r) < 0x80: - let c = char(r) - if renderer.ansiparser.state != PARSE_DONE: - if not renderer.ansiparser.parseAnsiCode(renderer.format, c): - if renderer.ansiparser.state == PARSE_DONE: - renderer.af = true - continue - grid.processAscii(renderer, c) - else: - grid.addFormat(renderer) - grid[^1].str &= r - renderer.w += r.twidth(renderer.w) - renderer.j += i - pi diff --git a/src/server/buffer.nim b/src/server/buffer.nim index 9ed49c96..783da17b 100644 --- a/src/server/buffer.nim +++ b/src/server/buffer.nim @@ -36,10 +36,9 @@ import js/javascript import js/regex import js/timeout import js/tojs +import layout/renderdocument import loader/headers import loader/loader -import render/renderdocument -import render/rendertext import types/cell import types/color import types/cookie @@ -109,7 +108,6 @@ type quirkstyle: CSSStylesheet userstyle: CSSStylesheet htmlParser: HTML5ParserWrapper - srenderer: StreamRenderer bgcolor: CellColor needsBOMSniff: bool decoder: TextDecoder @@ -610,34 +608,43 @@ proc gotoAnchor*(buffer: Buffer): Opt[tuple[x, y: int]] {.proxy.} = return err() proc do_reshape(buffer: Buffer) = - if buffer.ishtml: - if buffer.document == nil: - return # not parsed yet, nothing to render - let uastyle = if buffer.document.mode != QUIRKS: - buffer.uastyle - else: - buffer.quirkstyle - if buffer.document.cachedSheetsInvalid: - buffer.prevStyled = nil - let styledRoot = buffer.document.applyStylesheets(uastyle, - buffer.userstyle, buffer.prevStyled) - buffer.lines.renderDocument(buffer.bgcolor, styledRoot, buffer.attrs) - buffer.prevStyled = styledRoot + if buffer.document == nil: + return # not parsed yet, nothing to render + let uastyle = if buffer.document.mode != QUIRKS: + buffer.uastyle + else: + buffer.quirkstyle + if buffer.document.cachedSheetsInvalid: + buffer.prevStyled = nil + let styledRoot = buffer.document.applyStylesheets(uastyle, + buffer.userstyle, buffer.prevStyled) + buffer.lines.renderDocument(buffer.bgcolor, styledRoot, buffer.attrs) + buffer.prevStyled = styledRoot proc processData0(buffer: Buffer, data: openArray[char]): bool = if buffer.ishtml: if buffer.htmlParser.parseBuffer(data) == PRES_STOP: buffer.charsetStack = @[buffer.htmlParser.builder.charset] return false - buffer.document = buffer.htmlParser.builder.document else: - buffer.lines.renderChunk(buffer.srenderer, data) + var plaintext = buffer.document.findFirst(TAG_PLAINTEXT) + if plaintext == nil: + const s = "<plaintext id='text'>" + doAssert buffer.htmlParser.parseBuffer(s) != PRES_STOP + plaintext = buffer.document.findFirst(TAG_PLAINTEXT) + if data.len > 0: + let lastChild = plaintext.lastChild + var text = newString(data.len) + copyMem(addr text[0], unsafeAddr data[0], data.len) + if lastChild != nil and lastChild of Text: + Text(lastChild).data &= text + else: + plaintext.insert(buffer.document.createTextNode(text), nil) true func canSwitch(buffer: Buffer): bool {.inline.} = - if buffer.ishtml and buffer.htmlParser.builder.confidence != ccTentative: - return false - return buffer.charsetStack.len > 0 + return buffer.htmlParser.builder.confidence == ccTentative and + buffer.charsetStack.len > 0 proc initDecoder(buffer: Buffer) = if buffer.charset != CHARSET_UTF_8: @@ -648,11 +655,8 @@ proc initDecoder(buffer: Buffer) = proc switchCharset(buffer: Buffer) = buffer.charset = buffer.charsetStack.pop() buffer.initDecoder() - if buffer.ishtml: - buffer.htmlParser.restart(buffer.charset) - else: - buffer.srenderer.rewind() - buffer.lines.setLen(0) + buffer.htmlParser.restart(buffer.charset) + buffer.document = buffer.htmlParser.builder.document const BufferSize = 16384 @@ -812,41 +816,39 @@ proc rewind(buffer: Buffer): bool = proc setHTML(buffer: Buffer, ishtml: bool) = buffer.ishtml = ishtml buffer.initDecoder() - if ishtml: - let factory = newCAtomFactory() - buffer.factory = factory - let navigate = if buffer.config.scripting: - proc(url: URL) = buffer.navigate(url) - else: - nil - buffer.window = newWindow( - buffer.config.scripting, - buffer.config.images, - buffer.selector, - buffer.attrs, - factory, - navigate, - some(buffer.loader) - ) - let confidence = if buffer.config.charsetOverride == CHARSET_UNKNOWN: - ccTentative - else: - ccCertain - buffer.htmlParser = newHTML5ParserWrapper( - buffer.window, - buffer.url, - buffer.factory, - confidence, - buffer.charset - ) - assert buffer.htmlParser.builder.document != nil - const css = staticRead"res/ua.css" - const quirk = css & staticRead"res/quirk.css" - buffer.uastyle = css.parseStylesheet(factory) - buffer.quirkstyle = quirk.parseStylesheet(factory) - buffer.userstyle = parseStylesheet(buffer.config.userstyle, factory) + let factory = newCAtomFactory() + buffer.factory = factory + let navigate = if buffer.config.scripting: + proc(url: URL) = buffer.navigate(url) + else: + nil + buffer.window = newWindow( + buffer.config.scripting, + buffer.config.images, + buffer.selector, + buffer.attrs, + factory, + navigate, + some(buffer.loader) + ) + let confidence = if buffer.config.charsetOverride == CHARSET_UNKNOWN: + ccTentative else: - buffer.srenderer = newStreamRenderer() + ccCertain + buffer.htmlParser = newHTML5ParserWrapper( + buffer.window, + buffer.url, + buffer.factory, + confidence, + buffer.charset + ) + assert buffer.htmlParser.builder.document != nil + const css = staticRead"res/ua.css" + const quirk = css & staticRead"res/quirk.css" + buffer.uastyle = css.parseStylesheet(factory) + buffer.quirkstyle = quirk.parseStylesheet(factory) + buffer.userstyle = parseStylesheet(buffer.config.userstyle, factory) + buffer.document = buffer.htmlParser.builder.document proc extractCookies(response: Response): seq[Cookie] = result = @[] @@ -1122,21 +1124,14 @@ proc finishLoad(buffer: Buffer): EmptyPromise = if buffer.decoder != nil and buffer.decoder.finish() == tdfrError or buffer.validator != nil and buffer.validator[].finish() == tvrError: doAssert buffer.processData0("\uFFFD") - var p: EmptyPromise - if buffer.ishtml: - buffer.htmlParser.finish() - buffer.document = buffer.htmlParser.builder.document - buffer.document.readyState = rsInteractive - buffer.dispatchDOMContentLoadedEvent() - p = buffer.loadResources() - else: - p = EmptyPromise() - p.resolve() + buffer.htmlParser.finish() + buffer.document.readyState = rsInteractive + buffer.dispatchDOMContentLoadedEvent() buffer.selector.unregister(buffer.fd) buffer.loader.unregistered.add(buffer.fd) buffer.fd = -1 buffer.istream.close() - return p + return buffer.loadResources() type LoadResult* = tuple[ atend: bool, @@ -1235,12 +1230,10 @@ proc cancel*(buffer: Buffer): int {.proxy.} = buffer.loader.unregistered.add(buffer.fd) buffer.fd = -1 buffer.istream.close() - if buffer.ishtml: - buffer.htmlParser.finish() - buffer.document = buffer.htmlParser.builder.document - buffer.document.readyState = rsInteractive - buffer.state = bsLoaded - buffer.do_reshape() + buffer.htmlParser.finish() + buffer.document.readyState = rsInteractive + buffer.state = bsLoaded + buffer.do_reshape() return buffer.lines.len #https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#multipart/form-data-encoding-algorithm |