import tables import options import os import streams import config/chapath import config/mailcap import config/mimetypes import config/toml import io/urlfilter import js/error import js/javascript import js/propertyenumlist import js/regex import loader/headers import loader/loader import types/cell import types/color import types/cookie import types/opt import types/referer import types/urimethodmap import types/url import utils/mimeguess import utils/twtstr import chakasu/charset type ColorMode* = enum MONOCHROME, ANSI, EIGHT_BIT, TRUE_COLOR FormatMode* = set[FormatFlags] ActionMap = object t: Table[string, string] StaticSiteConfig = object url: Opt[string] host: Opt[string] rewrite_url: Opt[string] cookie: Opt[bool] third_party_cookie: seq[string] share_cookie_jar: Opt[string] referer_from*: Opt[bool] scripting: Opt[bool] document_charset: seq[Charset] images: Opt[bool] stylesheet: Opt[string] proxy: Opt[string] StaticOmniRule = object match: string substitute_url: string SiteConfig* = object url*: Opt[Regex] host*: Opt[Regex] rewrite_url*: (proc(s: URL): JSResult[URL]) cookie*: Opt[bool] third_party_cookie*: seq[Regex] share_cookie_jar*: Opt[string] referer_from*: Opt[bool] scripting*: Opt[bool] document_charset*: seq[Charset] images*: Opt[bool] stylesheet*: Opt[string] proxy*: Opt[URL] OmniRule* = object match*: Regex substitute_url*: (proc(s: string): JSResult[string]) StartConfig = object visual_home* {.jsgetset.}: string startup_script* {.jsgetset.}: string headless* {.jsgetset.}: bool CSSConfig = object stylesheet* {.jsgetset.}: string SearchConfig = object wrap* {.jsgetset.}: bool EncodingConfig = object display_charset* {.jsgetset.}: Opt[Charset] document_charset* {.jsgetset.}: seq[Charset] ExternalConfig = object tmpdir* {.jsgetset.}: ChaPath editor* {.jsgetset.}: string mailcap* {.jsgetset.}: seq[ChaPath] mime_types* {.jsgetset.}: seq[ChaPath] cgi_dir* {.jsgetset.}: seq[ChaPath] urimethodmap* {.jsgetset.}: seq[ChaPath] w3m_cgi_compat* {.jsgetset.}: bool InputConfig = object vi_numeric_prefix* {.jsgetset.}: bool NetworkConfig = object max_redirect* {.jsgetset.}: int32 prepend_https* {.jsgetset.}: bool proxy* {.jsgetset.}: Opt[string] default_headers* {.jsgetset.}: Table[string, string] DisplayConfig = object color_mode* {.jsgetset.}: Opt[ColorMode] format_mode*: Opt[FormatMode] #TODO getset no_format_mode*: FormatMode #TODO getset emulate_overline* {.jsgetset.}: bool alt_screen* {.jsgetset.}: Opt[bool] highlight_color* {.jsgetset.}: RGBAColor highlight_marks* {.jsgetset.}: bool double_width_ambiguous* {.jsgetset.}: bool minimum_contrast* {.jsgetset.}: int32 force_clear* {.jsgetset.}: bool set_title* {.jsgetset.}: bool default_background_color* {.jsgetset.}: RGBColor default_foreground_color* {.jsgetset.}: RGBColor Config* = ref ConfigObj ConfigObj* = object configdir {.jsget.}: string `include` {.jsget.}: seq[ChaPath] start* {.jsget.}: StartConfig search* {.jsget.}: SearchConfig css* {.jsget.}: CSSConfig encoding* {.jsget.}: EncodingConfig external* {.jsget.}: ExternalConfig network* {.jsget.}: NetworkConfig input* {.jsget.}: InputConfig display* {.jsget.}: DisplayConfig #TODO getset siteconf: seq[StaticSiteConfig] omnirule: seq[StaticOmniRule] page* {.jsget.}: ActionMap line* {.jsget.}: ActionMap BufferConfig* = object userstyle*: string referer_from*: bool referrerpolicy*: ReferrerPolicy scripting*: bool charsets*: seq[Charset] images*: bool loaderConfig*: LoaderConfig mimeTypes*: MimeTypes cgiDir*: seq[string] ForkServerConfig* = object tmpdir*: string ambiguous_double*: bool jsDestructor(ActionMap) jsDestructor(StartConfig) jsDestructor(CSSConfig) jsDestructor(SearchConfig) jsDestructor(EncodingConfig) jsDestructor(ExternalConfig) jsDestructor(NetworkConfig) jsDestructor(DisplayConfig) jsDestructor(Config) proc `[]=`(a: var ActionMap, b, c: string) = a.t[b] = c proc `[]`*(a: ActionMap, b: string): string = a.t[b] proc contains*(a: ActionMap, b: string): bool = b in a.t proc getOrDefault(a: ActionMap, b: string): string = a.t.getOrDefault(b) proc hasKeyOrPut(a: var ActionMap, b, c: string): bool = a.t.hasKeyOrPut(b, c) func getRealKey(key: string): string proc getter(a: ptr ActionMap, s: string): Opt[string] {.jsgetprop.} = a.t.withValue(s, p): return opt(p[]) proc setter(a: ptr ActionMap, k, v: string) {.jssetprop.} = let k = getRealKey(k) if k == "": return 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()" teststr.setLen(i) proc delete(a: ptr ActionMap, k: string): bool {.jsdelprop.} = let k = getRealKey(k) let ina = k in a[] a[].t.del(k) return ina func names(ctx: JSContext, a: ptr ActionMap): JSPropertyEnumList {.jspropnames.} = let L = uint32(a[].t.len) var list = newJSPropertyEnumList(ctx, L) 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) proc bindLineKey(config: Config, key, action: string) {.jsfunc.} = (addr config.line).setter(key, action) proc hasprop(a: ptr ActionMap, s: string): bool {.jshasprop.} = return s in a[] func getProxy*(config: Config): URL = if config.network.proxy.isSome: let s = config.network.proxy.get let x = parseURL(s) if x.isSome: return x.get else: raise newException(Defect, "Invalid proxy URL: " & s) return nil func getDefaultHeaders*(config: Config): Headers = return newHeaders(config.network.default_headers) proc getBufferConfig*(config: Config, location: URL, cookiejar: CookieJar, headers: Headers, referer_from, scripting: bool, charsets: seq[Charset], images: bool, userstyle: string, proxy: URL, mimeTypes: MimeTypes, urimethodmap: URIMethodMap, cgiDir: seq[string]): BufferConfig = let filter = newURLFilter( scheme = some(location.scheme), allowschemes = @["data"], default = true ) return BufferConfig( userstyle: userstyle, referer_from: referer_from, scripting: scripting, charsets: charsets, images: images, mimeTypes: mimeTypes, loaderConfig: LoaderConfig( defaultHeaders: headers, filter: filter, cookiejar: cookiejar, proxy: proxy, cgiDir: cgiDir, urimethodmap: urimethodmap, w3mCGICompat: config.external.w3m_cgi_compat ) ) proc getSiteConfig*(config: Config, jsctx: JSContext): seq[SiteConfig] = for sc in config.siteconf: var conf = SiteConfig( cookie: sc.cookie, scripting: sc.scripting, share_cookie_jar: sc.share_cookie_jar, referer_from: sc
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html><head><title>Python: module test.test</title>
</head><body bgcolor="#f0f0f8">
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
<tr bgcolor="#7799ee">
<td valign=bottom> <br>
<font color="#ffffff" face="helvetica, arial"> <br><big><big><strong><a href="test.html"><font color="#ffffff">test</font></a>.test</strong></big></big></font></td
><td align=right valign=bottom
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/home/hut/ranger/test/test.py">/home/hut/ranger/test/test.py</a></font></td></tr></table>
<p><tt>Workaround to allow running single test cases directly</tt></p>
</body></html>