### Build and Install Chawan Source: https://github.com/devskale/chawan/blob/main/README.md Builds the Chawan application using make and installs it. Requires root privileges for installation. ```bash make ``` ```bash sudo make install ``` -------------------------------- ### Buffer Configuration Example Source: https://github.com/devskale/chawan/blob/main/doc/config.md Example TOML configuration for buffer settings, including image display, styling, and custom user styles. Demonstrates how to enable/disable features and define inline CSS. ```toml [buffer] # show images on all websites images = true # disable website CSS styling = false # Specify user styles. user-style = ''' /* you can import external UA styles like this: */ @import 'user.css'; /* or just insert the style inline as follows. */ /* enforce the default text-decoration for links (i.e. underline). */ a[href] { text-decoration: revert !important } @media (monochrome) { /* only in color-mode "monochrome" (or -M) */ /* disable UA style of bold font (no need for important here) */ a[href]:hover { font-weight: initial } /* ...and italicize the font on hover instead. * here we use important because we don't want websites to * override the value. */ a[href]:hover { font-style: italic !important } } ''' # You *can* set scripting to true here, but I strongly recommend using # [[siteconf]] to enable it on a per-site basis instead. ``` -------------------------------- ### Build and Install Chawan Source: https://github.com/devskale/chawan/blob/main/doc/build.md Standard commands to build and install Chawan. Ensure environment variables are set consistently for both targets. ```bash make make install ``` -------------------------------- ### Passing Build Variables via Environment Source: https://github.com/devskale/chawan/blob/main/doc/build.md Example of setting the PREFIX variable in the environment before running make. This ensures consistency across build and install targets. ```bash export PREFIX=/usr make ``` -------------------------------- ### chaseccomp Input File Example Source: https://github.com/devskale/chawan/blob/main/lib/chaseccomp/README.md This example demonstrates the syntax for a chaseccomp input file, including loading syscall numbers, conditional checks, and defining actions like 'allow' or 'kill'. ```chaseccomp load nr ifeq SYS_exit_group allow ret kill : allow ret allow ``` -------------------------------- ### mime.types File Format Example Source: https://github.com/devskale/chawan/blob/main/doc/mime.types.md An example demonstrating the format of a mime.types file. Lines starting with '#' are comments. The first column is the MIME type, followed by file extensions. ```plaintext # comment application/x-example exmpl ex ``` -------------------------------- ### Install Debian Dependencies Source: https://github.com/devskale/chawan/blob/main/README.md Installs necessary development dependencies for Chawan on Debian-based systems using apt. ```bash apt install libssh2-1-dev libssl-dev libbrotli-dev pkg-config make ``` -------------------------------- ### Shorthand for CGI Scripts (Translation Example) Source: https://github.com/devskale/chawan/blob/main/doc/urimethodmap.md This example shows how to create a shorthand 'tl:' for a translation CGI script, allowing users to translate words via `tl:word`. For more complex substitutions, omni-rules are recommended. ```plaintext # (trans.cgi is a script you can find and study in the bonus/ directory.) tl: /cgi-bin/trans.cgi?%s ``` -------------------------------- ### Map Keybinding to Line Begin Action Source: https://github.com/devskale/chawan/blob/main/doc/config.md Assigns the 'line.begin' action to the 'C-a' keybinding. This is useful for quickly moving the cursor to the start of the line. ```shell 'C-a' = 'line.begin' ``` -------------------------------- ### Mailcap Entry Example with Variable Assignment Source: https://github.com/devskale/chawan/blob/main/doc/mailcap.md This example demonstrates how to assign a template string to a variable before using it in a mailcap entry. This can help prevent issues with other software misinterpreting templates. ```mailcap text/x-example; s=%s cat "$s"; copiousoutput ``` -------------------------------- ### Run Chawan Commands Source: https://github.com/devskale/chawan/blob/main/README.md Examples of how to run Chawan from the command line for various purposes, including checking version, opening websites, and viewing man pages. ```bash $ cha -V # open in visual mode for a list of default keybindings ``` ```bash $ cha example.org # open your favorite website directly from the shell ``` ```bash $ mancha cha # read the cha(1) man page using `mancha' ``` -------------------------------- ### Passing Build Variables as Arguments Source: https://github.com/devskale/chawan/blob/main/doc/build.md Example of setting the PREFIX variable as an argument to the make command. This method is an alternative to environment variables. ```bash make PREFIX=/usr ``` -------------------------------- ### CSS Counter Set and Increment Example Source: https://github.com/devskale/chawan/blob/main/test/layout/counter-set-syntax.html Demonstrates setting initial counter values and incrementing them. Use this to manage ordered lists or custom numbering. ```css #a { counter-set: a b c 2 } #b { counter-increment: b } #c::before { content: counter(b) } ``` -------------------------------- ### Basic Document Write with Checkpoint Source: https://github.com/devskale/chawan/blob/main/test/js/docwrite1.html A simple example of using document.write to insert an H2 element and a script tag with a checkpoint. ```javascript document.write("

Subtitle

"); ``` -------------------------------- ### Customizing Link Hint Markers Source: https://github.com/devskale/chawan/blob/main/doc/css.md Example of customizing the background of link hint markers using the ::-cha-link-hint pseudo-element. ```css ::-cha-link-hint { background: gainsboro } ``` -------------------------------- ### Code Block Example Source: https://github.com/devskale/chawan/blob/main/test/md/nested-block.md A basic code block example. ```plaintext code *code* cod ``` -------------------------------- ### Create Cowsay CGI Script Source: https://github.com/devskale/chawan/blob/main/doc/protocols.md Example of a CGI script for a custom 'cowsay' protocol. It simulates a delay and prints a 'Cha-Control: Connected' header. Assumes configuration in ~/.chawan/cgi-bin. ```sh #!/bin/sh # Signal to the browser that the connection has succeeded. After this, # Chawan will now "Downloading" instead of "Connecting". printf 'Cha-Control: Connected\n' sleep 1 # simulate a delay ``` -------------------------------- ### Special Case CGI Template Equivalents Source: https://github.com/devskale/chawan/blob/main/doc/urimethodmap.md Demonstrates how Chawan treats templates starting with '/cgi-bin/' or 'file:/cgi-bin/' as equivalent to 'cgi-bin:', simplifying redirection to CGI scripts. ```plaintext # The following are the same in Chawan protocol: /cgi-bin/interpret-protocol?%s protocol: file:/cgi-bin/interpret-protocol?%s # Note: this last entry does not work in w3m. protocol: cgi-bin:interpret-protocol?%s ``` -------------------------------- ### Vi Word Example Source: https://github.com/devskale/chawan/blob/main/doc/config.md Demonstrates a sequence containing two 'vi words' separated by symbols, highlighting that words from different character categories do not need to be whitespace-separated. ```text hello[]+{}@`! ``` -------------------------------- ### Keybinding to TOML Defined Command Source: https://github.com/devskale/chawan/blob/main/doc/api.md Example of binding a keypress combination to a command defined in the TOML configuration file. The 'cmd.' prefix is optional when calling these commands. ```toml 'g p n' = 'my.namespace.showNumber' # same as 'g p n' = 'cmd.my.namespace.showNumber' ``` -------------------------------- ### List Text Content from URL using Chame Minidom Source: https://github.com/devskale/chawan/blob/main/lib/chame0/doc/manual.md This example demonstrates how to fetch HTML content from a URL and extract all plain text nodes using the Chame minidom parser. It requires the 'ssl' compilation flag. ```nim # Compile with nim c -d:ssl # List text found between HTML tags on the target website. import std/httpclient import std/os import std/strutils import chame/minidom if paramCount() != 1: echo "Usage: " & paramStr(0) & " [URL]" quit(1) let client = newHttpClient() let res = client.get(paramStr(1)) let document = parseHTML(res.bodyStream) var stack = @[Node(document)] while stack.len > 0: let node = stack.pop() if node of Text: let s = Text(node).data.strip() if s != "": echo s for i in countdown(node.childList.high, 0): stack.add(node.childList[i]) ``` -------------------------------- ### Configuring C Compiler Path for Nim Source: https://github.com/devskale/chawan/blob/main/doc/build.md Example of configuring the path and executable for a C compiler not directly supported by Nim, by emulating a supported compiler driver. This is done via the FLAGS variable. ```bash export FLAGS=--gcc.path=/usr/local/musl/bin --gcc.exe=musl-gcc --gcc.linkerexe=musl-gcc ``` -------------------------------- ### Dynamic Module Imports with Error Handling Source: https://github.com/devskale/chawan/blob/main/test/net/module.html Imports modules dynamically using `import()`. Includes examples with direct paths, `URL` objects, and basic error handling with `.catch()`. ```javascript window.seen = 0; import("./module.http"); import(new URL("module4.http", window.location)).catch(x => 0); import('module3.http').catch(x => 0); import './module2.http'; ``` ```javascript window.onload = () => { if (window.seen == 3) document.getElementById("x").textContent = "Success" /* TODO use this once the eval test works window.x.then(() => { if (window.seen == 4) document.getElementById("x").textContent = "Success" }); */ } ``` -------------------------------- ### Configure Finger Protocol Mapping Source: https://github.com/devskale/chawan/blob/main/doc/protocols.md Maps the 'finger' protocol to a CGI script for handling requests. This example shows how to configure Chawan to use a specific CGI script for a protocol. ```text finger: cgi-bin:finger ``` -------------------------------- ### Write Paragraph and Nested Script Source: https://github.com/devskale/chawan/blob/main/test/js/docwrite3.html Shows how to write a paragraph followed by a script that inserts nested content. This example highlights string concatenation for script tag construction. ```javascript document.write('

before subtext

document.write(\`third nest\`)') ``` -------------------------------- ### Registering Types with Inheritance in Monoucha Source: https://github.com/devskale/chawan/blob/main/lib/monoucha0/doc/manual.md Illustrates how to set up inheritance chains for Nim types exposed to JavaScript using the `parent` parameter in `registerType`. This example sets up 'Planet' as a parent for 'Earth' and 'Moon'. ```nim type Planet = ref object of RootObj Earth = ref object of Planet Moon = ref object of Planet # [...] let planetCID = ctx.registerType(Planet) ctx.registerType(Earth, parent = planetCID, asglobal = true) ctx.registerType(Moon, parent = planetCID) ctx.setGlobal(Earth()) # make sure to set a global so global functions work const code = "assert(globalThis instanceof Planet)" let val = ctx.eval(code) assert not JS_IsException(val) JS_FreeValue(ctx, val) ``` -------------------------------- ### Invalid Media Query Syntaxes Source: https://github.com/devskale/chawan/blob/main/test/layout/media-query.html Illustrates common mistakes and invalid syntaxes in media queries. These examples show incorrect usage of logical operators, keywords, and value formats. ```css /* invalid */ @media (width >= 1px 2px) { #red { color: blue !important } } ``` ```css @media screen yahoo{ #purple { color: red !important } } ``` ```css @media screen or (min-width: 2px) { #blue { color: red !important } } ``` ```css @media screen and (min-width: 2px) or (min-width: 2px) { #blue { color: red !important } } ``` ```css @media (color) test { #blue { color: red !important } } ``` -------------------------------- ### Setting and Getting onclick Handlers Source: https://github.com/devskale/chawan/blob/main/test/js/click_setter.html Illustrates setting an onclick handler to an anonymous function, then to a named function, and finally to null. It also shows retrieving the assigned handler. ```javascript const x = document.getElementById("x"); assertEquals(x.onclick, null); function myFunction() { this.textContent = "hello" } x.onclick = () => ""; x.onclick = myFunction; assertEquals(x.onclick, myFunction); x.onclick = null; assertEquals(x.onclick, null); const y = document.getElementById("y"); y.onclick = myFunction; assertEquals(y.onclick, myFunction); y.remove(); x.textContent = "Success"; ``` -------------------------------- ### Hello World with Monoucha Source: https://github.com/devskale/chawan/blob/main/lib/monoucha0/doc/manual.md Demonstrates basic JavaScript evaluation and type conversion using Monoucha. Ensure to free JSValue, context, and runtime handles manually. ```nim import monoucha/javascript let rt = newGlobalJSRuntime() let ctx = rt.newJSContext() const code = "'Hello from JS!'" let val = ctx.eval(code) var res: string assert ctx.fromJS(val, res).isOk # no error echo res # Hello from JS! JS_FreeValue(ctx, val) ctx.free() rt.free() ``` -------------------------------- ### Substring Matching Attribute Selector (Starts With) Source: https://github.com/devskale/chawan/blob/main/test/layout/attribute-selector.html Selects elements where the attribute value starts with a specific substring. This is useful for selecting elements with dynamic or prefixed attribute values. ```css div[test|=test] { color: green } ``` -------------------------------- ### Nim Object Initialization Source: https://github.com/devskale/chawan/blob/main/doc/hacking.md Demonstrates the correct way to initialize objects in Nim, explicitly listing parameters. Avoids implicit initialization for clarity and safety. ```nim let myObj = MyObject( param1: x, param2: y # if there's e.g. a param3 too, it's OK to leave it out and let it be # default initialized. ) ``` -------------------------------- ### Build Chawan with Static Linking Source: https://github.com/devskale/chawan/blob/main/doc/build.md Set environment variables for `PKG_CONFIG_PATH` and `CC` to point to Musl, then clean and build Chawan for static linking. ```sh $ export PKG_CONFIG_PATH=/usr/local/musl/lib/pkgconfig:/usr/local/musl/lib64/pkgconfig $ export CC=musl-gcc STATIC_LINK=1 $ make distclean $ make ``` -------------------------------- ### Set white-space and get BoundingClientRect Source: https://github.com/devskale/chawan/blob/main/test/dhtml/input-invalidate-on-parent-white-space-change.html This snippet gets a reference to an element by its ID, retrieves its bounding client rectangle, and then sets its white-space style to 'nowrap' when the window loads. This is useful for observing layout changes. ```javascript const x = document.getElementById("x"); x.getBoundingClientRect(); window.onload = () => { x.style.whiteSpace = "nowrap"; } ``` -------------------------------- ### Initialize HTML5 Parser (htmlparser) Source: https://github.com/devskale/chawan/blob/main/lib/chame0/doc/manual.md Initializes the HTML5 parser. This is the first step when using the low-level htmlparser API. ```nim proc initHTML5Parser*(parser: var HTMLParser, factory: MAtomFactory, getInsertionPoint: TGetInsertionPointProc, errorHook: TErrorHookProc): void ``` -------------------------------- ### Invalid :nth-last-child() selector Source: https://github.com/devskale/chawan/blob/main/test/layout/nth-child.html An example of an invalid :nth-last-child() selector, which would typically be ignored by browsers. ```css ol[first] :nth-last-child(0n++1) { color: purple } /* invalid */ ``` -------------------------------- ### Redefine Keybinding for Omnirule Search Source: https://github.com/devskale/chawan/blob/main/doc/config.md Customize keybindings, for example, to trigger a specific omnirule search directly. ```toml [page] 'C-k' = '() => pager.load("ddg:")' ``` -------------------------------- ### Alerts and User Input Source: https://github.com/devskale/chawan/blob/main/doc/api.md Functions for displaying alerts, asking for user confirmation, and getting character input. ```APIDOC ## peek() ### Description Display an alert message of the current URL. ### Method `peek` ## peekCursor() ### Description Display an alert message of the URL or title under the cursor. Multiple calls allow cycling through the two. ### Method `peekCursor` ## showFullAlert() ### Description Show the last alert inside the line editor. ### Method `showFullAlert` ## ask(prompt) ### Description Ask the user for confirmation. Returns a promise which resolves to a boolean value indicating whether the user responded with yes. ### Method `ask` ### Parameters #### Path Parameters - **prompt** (string) - Required - The message to display to the user. ## askChar(prompt) ### Description Ask the user for any character. Like `pager.ask`, but the return value is a character, and (y/n) is not appended to the prompt. ### Method `askChar` ### Parameters #### Path Parameters - **prompt** (string) - Required - The message to display to the user. ``` -------------------------------- ### localStorage Basic Operations Source: https://github.com/devskale/chawan/blob/main/test/js/localstorage.html Demonstrates setting and retrieving items from localStorage. Note that direct property assignment is supported, and getItem can be used for retrieval. ```javascript localStorage.testKey = "test value"; assertEquals(localStorage.key(localStorage.length - 1), "testKey"); assertEquals(localStorage.key(-1), null); assertEquals(localStorage.getItem("testKey"), "test value"); document.getElementById("x").textContent = "Success"; ``` -------------------------------- ### Proprietary Media Feature for Content Type Source: https://github.com/devskale/chawan/blob/main/doc/css.md Example of using the -cha-content-type media feature to filter documents by content type. ```css @media (-cha-content-type: "text/markdown") { body { width: 80ch } } ``` -------------------------------- ### Test Local Storage Operations Source: https://github.com/devskale/chawan/blob/main/test/js/window.html Demonstrates setting and retrieving items from localStorage using both dot notation and bracket notation, and verifies deletion. ```javascript window.localStorage.setItem("a", "x"); window.localStorage["b"] = "y"; assertEquals(window.localStorage["b"], "y") delete window.localStorage.b; assertEquals(window.localStorage["b"], undefined); window.localStorage["b"] = "y"; ``` -------------------------------- ### :nth-child() with n+2 and even keywords Source: https://github.com/devskale/chawan/blob/main/test/layout/nth-child.html Illustrates using :nth-child() with a formula starting from the second element (n+2) and the 'even' keyword. ```css ol[third] :nth-child(n+2) { color: red } ol[third] :nth-child(eVeN) { color: green } ``` -------------------------------- ### Event Listener and Propagation Checks Source: https://github.com/devskale/chawan/blob/main/test/js/event.html Sets up event listeners for 'load' and 'click' events on document and window. Asserts various event properties and listener behaviors. ```javascript let ok8 = true; document.addEventListener("load", e => { ok8 = false; }); let ok9 = false; window.addEventListener("click", e => { ok9 = true; }); let ok10 = false; window.addEventListener("load", e => { assert(ok7); assert(ok8); assert(ok9); assert(ok10); assertEquals(e.target, document); assertEquals(e.currentTarget, window); let x = document.getElementById("x"); x.textContent = "Success"; }); document.addEventListener("DOMContentLoaded", e => { ok10 = e.bubbles && e.isTrusted; }); ``` -------------------------------- ### Invalid URI Method Map Entry Source: https://github.com/devskale/chawan/blob/main/doc/urimethodmap.md This example shows an incorrect urimethodmap entry due to the missing colon after the protocol name. ```plaintext # However, this is incorrect, because the colon sign is missing: protocol /cgi-bin/interpret-protocol?%s ``` -------------------------------- ### NodeIterator with Custom Filter Source: https://github.com/devskale/chawan/blob/main/test/js/nodeiterator.html Iterates through nodes, filtering elements by ID and excluding those starting with 'test'. Demonstrates nextNode and previousNode after element removal. ```javascript const iter = document.createNodeIterator(test1, 1, x => { if (x instanceof Element && x.id && !x.id.startsWith("test")) return 1; return 2; }, 1); assertEquals(iter.referenceNode, test1); assertEquals(iter.nextNode(), a); assertEquals(iter.nextNode(), b); a.remove(); assertEquals(iter.nextNode(), c) assertEquals(iter.previousNode(), c); assertEquals(iter.previousNode(), b); assertEquals(iter.previousNode(), null); b.remove(); assertInstanceof(iter.referenceNode, Text); assertEquals(iter.nextNode(), c); c.remove(); test1.remove(); ``` -------------------------------- ### URI Method Map Format Source: https://github.com/devskale/chawan/blob/main/doc/urimethodmap.md This illustrates the basic structure of a urimethodmap file, defining protocols and their corresponding redirection templates. Comments start with '#'. ```plaintext URIMethodMap-File = *URIMethodMap-line URIMethodMap-Line = Comment / URIMethodMap-Entry URIMethodMap-Entry = Protocol *WHITESPACE Template *WHITESPACE CR Protocol = 1*CHAR COLON Template = [see below] Comment = *WHITESPACE CR / "#" *CHAR CR ``` -------------------------------- ### URL Construction and String Conversion Source: https://github.com/devskale/chawan/blob/main/test/js/url.html Demonstrates how URLs are constructed and converted to strings, including handling of missing schemes and trailing slashes. ```javascript assertEquals(new URL("https:example.org") + "", "https://example.org/"); ``` ```javascript assertEquals(new URL("https://////example.com///") + "", "https://example.com///"); ``` ```javascript assertEquals(new URL("https://example.com/././foo") + "", "https://example.com/foo"); ``` ```javascript assertEquals(new URL("hello:world", "https://example.com/") + "", "hello:world"); ``` ```javascript assertEquals(new URL("https:example.org", "https://example.com/") + "", "https://example.com/example.org"); ``` ```javascript assertEquals(new URL(String.raw`\example\..\demo/.\ `, "https://example.com/") + "", "https://example.com/demo/"); ``` ```javascript assertEquals(new URL("example", "https://example.com/demo") + "", "https://example.com/example"); ``` ```javascript assertEquals(new URL("https://example.org//") + "", "https://example.org//"); ``` ```javascript assertEquals(new URL("https://example.com/foo bar") + "", "https://example.com/foo%20bar"); ``` ```javascript assertEquals(new URL("https://EXAMPLE.com/../x") + "", "https://example.com/x"); ``` ```javascript assertEquals(new URL("https://example.com/[]?[]#[]") + "", "https://example.com/[]?[]#[]"); ``` ```javascript assertEquals(new URL("https://example/%?%#%") + "", "https://example/%?%#%"); ``` ```javascript assertEquals(new URL("https://example/%25?%25#%25") + "", "https://example/%25?%25#%25"); ``` ```javascript assertEquals(new URL(" https:exa\tmple\n.org\n/ ") + "", "https://example.org/"); ``` ```javascript assertEquals(new URL(" https:exa\tmple.org\n:\n2\n4\n5\n2\n\n/ ") + "", "https://example.org:2452/"); ``` ```javascript assertEquals(new URL(" h\nt\tt\np\ts\n:\t/\n/\te\nx\ta\nm\tp\nl\te\n/\tp\na\tt\n\nh\t?\nq\tu\ne\tr\ny\t#\nf\tr\na\tg\nm\te\nnt") + "", "https://example/path?query#fragment"); ``` ```javascript assertEquals(new URL(" h\nt\tt\np\ts\n:\t/\n/\tu\ns\ne\nr\nn\na\n\nm\ne\n:\np\na\ns\ns\nw\no\nr\nd\n@\ne\nx\ta\nm\tp\nl\te\n/\tp\na\tt\n\nh\t?\nq\tu\ne\tr\ny\t#\nf\tr\na\tg\nm\te\nnt") + "", "https://username:password@example/path?query#fragment"); ``` ```javascript assertEquals(new URL("abcd?efgh", "https://example.com/") + "", "https://example.com/abcd?efgh"); ``` ```javascript assertEquals(new URL("abcd#ijkl", "https://example.com/") + "", "https://example.com/abcd#ijkl"); ``` ```javascript assertEquals(new URL("abcd?efgh#ijkl", "https://example.com/") + "", "https://example.com/abcd?efgh#ijkl"); ``` -------------------------------- ### Accessing document.all in JavaScript Source: https://github.com/devskale/chawan/blob/main/test/js/documentall.html Demonstrates how to access and assert properties of document.all. Note that document.all is falsy and has a specific length. ```javascript const abc = document.all; assert(!document.all, "document.all must be falsy"); assert(!abc, "document.all must be falsy"); assertEquals(document.all.length, 10); const styles = [abc[6], abc[7], abc[8]]; assertEquals(styles[0].textContent, "style 1"); assertEquals(styles[1].textContent, "style 2"); assertEquals(styles[2].textContent, "style 3"); const result = document.getElementById("result"); result.textContent = "Success"; ``` -------------------------------- ### JSFile Destructor and Finalizer Example Source: https://github.com/devskale/chawan/blob/main/lib/monoucha0/doc/manual.md Defines a destructor for JSFile and a finalizer procedure to clean up managed memory. The finalizer increments a counter for each deallocated file. ```nim type JSFile = ref object path: string buffer: pointer # some internal buffer handled as managed memory jsDestructor(JSFile) proc newJSFile(path: string): JSFile {.jsctor.} = return JSFile( path: path, buffer: alloc(4096) ) var unrefd {.global.} = 0 proc finalize(file: JSFile) {.jsfin.} = if file.buffer != nil: dealloc(file.buffer) # Note: it is not necessary to nil out the pointer; it's just me being # paranoid :P file.buffer = nil inc unrefd ``` -------------------------------- ### Fetch and Get Text Response Source: https://github.com/devskale/chawan/blob/main/test/net/fetch.html Fetches a CSS file and asserts its text content length. Also sets the text alignment style of an element. ```javascript const x = document.getElementById("x"); { const res = await fetch("/utf16-bom.css"); const s = await res.text(); assertEquals(window.getComputedStyle(x).textAlign, "right"); assertEquals(s.length, 53); x.style.textAlign = "left"; assertInstanceof(new Response().headers, Headers); } ``` -------------------------------- ### Authenticating and Verifying Headers Source: https://github.com/devskale/chawan/blob/main/test/net/xhr.html Demonstrates making an XMLHttpRequest with basic authentication and then verifying specific headers in the response using a helper function. ```javascript let z = new XMLHttpRequest(); z.onreadystatechange = function() { if (z.readyState != XMLHttpRequest.DONE) return function assertHeaderEquals(name, value) { const header = z.response.split('\n') .find(x => x.startsWith(name + ':')); assertEquals(header, name + ': ' + value); } assertHeaderEquals("authorization", "Basic Y2hhLXRlc3QtdXNlckA6Y2hhLXRlc3QtcGFzczo="); assertHeaderEquals("referer", window.origin); } z.open("GET", "headers", false, "cha-test-user@", "cha-test-pass:"); z.withCredentials = true; z.send() ``` -------------------------------- ### Initialize HTML5 Parser Source: https://github.com/devskale/chawan/blob/main/lib/chame0/doc/manual.md Initializes an HTML5 parser with a custom DOM builder. Ensure your DOM builder implements the `htmlparseriface` for full compatibility. The returned parser object is large and passed by value; avoid unnecessary copying. ```nim proc initHTML5Parser[Handle, Atom](dombuilder: DOMBuilder[Handle, Atom], opts: HTML5ParserOpts[Handle, Atom]): HTML5Parser[Handle, Atom] ``` -------------------------------- ### Client Interface: setenv(name, value) Source: https://github.com/devskale/chawan/blob/main/doc/api.md Sets an environment variable. Throws a TypeError if the operation fails, for example, due to OS-imposed limits on variable size. ```javascript setenv(name, value) ``` -------------------------------- ### JavaScript Expression Keybinding Source: https://github.com/devskale/chawan/blob/main/doc/api.md Example of binding a keypress combination to a JavaScript expression that calls a function with an argument. Ensure functions are called with the correct 'this' context. ```javascript 'g p n' = 'n => pager.alert(n)' # e.g. 2gpn prints `2' to the status line ``` -------------------------------- ### ProgressEvent Initialization Source: https://github.com/devskale/chawan/blob/main/test/js/event.html Demonstrates the initialization of a ProgressEvent with custom loaded data. Verifies that the loaded property is set correctly. ```javascript assertEquals(new ProgressEvent("test", {loaded: .5}).loaded, .5); ``` -------------------------------- ### Valid URI Method Map Entries Source: https://github.com/devskale/chawan/blob/main/doc/urimethodmap.md These examples demonstrate correct syntax for urimethodmap entries, showing that whitespace around the colon is optional and tabs are allowed. ```plaintext # This is ok: protocol: /cgi-bin/interpret-protocol?%s # This is ok too: protocol:/cgi-bin/interpret-protocol?%s # Spaces and tabs are both allowed, so this is also ok: protocol: /cgi-bin/interpret-protocol?%s ``` -------------------------------- ### Using Option and Opt for Nullable Values and Errors Source: https://github.com/devskale/chawan/blob/main/lib/monoucha0/doc/manual.md Explains the use of `Option[T]` for representing nullable values (like strings or refs) and `Opt[T]` for error handling in Monoucha converters. It also notes that Nim exceptions are not used and can lead to undefined behavior. ```nim import std/options import monoucha/jsnull import monoucha/jserror ``` -------------------------------- ### Get Element Bounding Box and Clear Style Source: https://github.com/devskale/chawan/blob/main/test/dhtml/layout-cache-updates.html Retrieves an element's bounding box and sets its clear style. Ensure the element exists before calling. ```javascript var x = document.getElementById("x"); x.getBoundingClientRect(); x.style.clear = "both"; ``` -------------------------------- ### Fetch POST Request with File Source: https://github.com/devskale/chawan/blob/main/test/net/fetch.html Creates a POST request with a File object as the body and asserts the content-length and user-agent headers in the response. ```javascript const file = new File(["test"], "name"); const req = new Request("/headers", {method: "POST", body: file}); const res = await fetch(req); const s = await res.text(); const ss = s.split('\n'); const cl = ss.find(x => x.startsWith("content-length")); assertEquals(cl, "content-length: 4"); const ua = ss.find(x => x.startsWith("user-agent")); assertEquals(ua, "user-agent: chawan"); ``` -------------------------------- ### Iterating URL Search Parameters Source: https://github.com/devskale/chawan/blob/main/test/js/url.html Demonstrates how to iterate over the values of a URL's search parameters and assert their expected values. ```javascript x.searchParams.values()) { assertEquals(it[0], "b"); i++; } assertEquals(i, 1); } ``` -------------------------------- ### Configure URI Method Mapping Source: https://github.com/devskale/chawan/blob/main/doc/protocols.md Map URIs to CGI scripts in the .urimethodmap file. ```sh cowsay:\t/cgi-bin/cowsay.cgi ``` -------------------------------- ### Set and Get Property on HTML Element in JavaScript Source: https://github.com/devskale/chawan/blob/main/lib/monoucha0/doc/manual.md Demonstrates how to set a custom property on an HTML element and then retrieve it. This is useful for associating arbitrary data with DOM elements. ```javascript document.querySelector("html").canary = "chirp"; console.log(document.querySelector("html").canary); /* chirp */ ``` -------------------------------- ### Create and Append Text Node Source: https://github.com/devskale/chawan/blob/main/test/js/node.html Demonstrates creating a new Document, creating a text node, creating an element, and appending the text node to the element. Asserts that the text node's owner document is the created document. ```javascript let doc = new Document(); let text = doc.createTextNode("test"); let elem = document.createElement("div"); elem.append(text); assertEquals(text.ownerDocument, document); ``` -------------------------------- ### URL Pathname and Hash Manipulation Source: https://github.com/devskale/chawan/blob/main/test/js/url.html Shows how to create a URL with a data scheme, modify its hash, and observe the effect on the pathname. ```javascript const url = new URL("data:blah #a"); assertEquals(url.pathname, "blah %20"); url.hash = ""; assertEquals(url.pathname, "blah %20"); ``` -------------------------------- ### Setting and Testing onreadystatechange Source: https://github.com/devskale/chawan/blob/main/test/net/xhr.html Demonstrates setting the onreadystatechange handler and verifying its initial state and behavior during an XMLHttpRequest. ```javascript const x = new XMLHttpRequest(); assert(x.onreadystatechange === null); let changed = false; function myFunction(event) { changed = true; assert(!event.bubbles); assert(!event.cancelable); assert(event.isTrusted); } x.onreadystatechange = myFunction; assertEquals(x.status, 0); assertEquals(myFunction, x.onreadystatechange); assertEquals(x.readyState, XMLHttpRequest.UNSENT); assertEquals(x.UNSENT, XMLHttpRequest.UNSENT); x.open("GET", "ping", false); assertThrows(() => x.responseType = 'document', DOMException); x.overrideMimeType("text/plain"); x.send(); assertThrows(() => x.overrideMimeType("text/plain"), DOMException); assertEquals(x.readyState, XMLHttpRequest.DONE); assert(changed); ``` -------------------------------- ### Configuring Nim Compiler Flags Source: https://github.com/devskale/chawan/blob/main/doc/build.md Example of setting compiler flags for the Nim compiler using the FLAGS variable. This is useful for specifying compiler options like the C compiler. ```bash export FLAGS=--cc:clang ``` -------------------------------- ### Local Module Imports in Nim Source: https://github.com/devskale/chawan/blob/main/AGENTS.md Local module imports in Nim should follow standard library imports and use relative paths. Example includes config and utils modules. ```nim import config/config import utils/myposix ``` -------------------------------- ### Client Interface: config.dir Source: https://github.com/devskale/chawan/blob/main/doc/api.md Accesses the configuration directory path. Note that the config interface is experimental and may not expose all settings or propagate changes reliably. ```javascript config.dir ``` -------------------------------- ### Get File Owner in Nim Source: https://github.com/devskale/chawan/blob/main/lib/monoucha0/doc/manual.md Retrieves the owner ID of a file using Nim's file system operations. Returns -1 if the file cannot be opened or its stats cannot be retrieved. ```nim proc owner(file: JSFile): int {.jsuffget.} = let fd = open(cstring(file.path), O_RDONLY, 0) if fd == -1: return -1 var stats = Stat.default if fstat(fd, stats) == -1: discard close(fd) return -1 return int(stats.st_uid) ``` ```nim proc getOwner(file: JSFile): int {.jsuffget.} = return file.owner ``` -------------------------------- ### Valid Media Queries with Different Conditions Source: https://github.com/devskale/chawan/blob/main/test/layout/media-query.html Demonstrates valid media queries using width, height, and grid conditions. These are useful for applying styles based on viewport or device characteristics. ```css /* valid */ @mediA (WiDtH >= 1px) and (HeiGhT < 10000px) { #red { color: red } } ``` ```css @media screen and (WiDtH >= 1px) { #green { color: green } } ``` ```css @media (grid: 1) { #purple { color: purple } } ``` ```css @media screen and (min-width: 2px) { #blue { color: blue } } ``` -------------------------------- ### Handling of Native Text/HTML Content Source: https://github.com/devskale/chawan/blob/main/doc/mailcap.md This entry demonstrates that `text/html` is handled natively by Chawan and would be ignored if `copiousoutput` is specified. It shows an example of how Chawan might process HTML content. ```mailcap text/html; cha -dT text/html -I %{charset}; copiousoutput ``` -------------------------------- ### Enable image support in Chawan Source: https://github.com/devskale/chawan/blob/main/doc/troubleshooting.md Configure Chawan to display images by setting 'images' to true in the buffer configuration. ```toml [buffer] images = true ``` -------------------------------- ### Get Element Bounding Box, Clear, and Set Margin Source: https://github.com/devskale/chawan/blob/main/test/dhtml/layout-cache-updates.html Retrieves an element's bounding box, sets its clear style, and then adjusts its left margin. Ensure the element exists. ```javascript var x = document.getElementById("y"); x.getBoundingClientRect(); x.style.clear = "both"; x.getBoundingClientRect(); x.style.marginLeft = "1ch"; ``` -------------------------------- ### Disabling Sandbox During Build Source: https://github.com/devskale/chawan/blob/main/doc/build.md Demonstrates how to disable syscall filtering using the DANGER_DISABLE_SANDBOX variable. This is a rarely optimal solution and must be passed directly to make. ```bash make DANGER_DISABLE_SANDBOX=1 ``` -------------------------------- ### Nim Array Initialization Source: https://github.com/devskale/chawan/blob/main/doc/hacking.md Shows different ways to initialize arrays in Nim. `var buf1` is zero-initialized, while `var buf2 {.noinit.}` avoids zero-initialization, which can be unsafe for GC'ed types. ```nim var buf1: array[1234, char] # when you need 0-initialization ``` ```nim var buf2 {.noinit.}: array[1234, char] # when you don't need 0-initialization ``` -------------------------------- ### File URL Handling Source: https://github.com/devskale/chawan/blob/main/test/js/url.html Tests the construction and string representation of file URLs, including different path formats and base URLs. ```javascript assertEquals(new URL('file:///C|/demo') + "", "file:///C:/demo"); ``` ```javascript assertEquals(new URL('..', 'file:///C:/demo') + "", "file:///C:/"); ``` ```javascript assertEquals(new URL("x", "file:///A:y") + "", "file:///x"); ``` ```javascript assertEquals(new URL("x", "file:///A:/y") + "", "file:///A:/x"); ``` ```javascript assertEquals(new URL("/x", "file:///A:") + "", "file:///A:/x"); ``` ```javascript assertEquals(new URL('file://C:/') + "", "file:///C:/"); ``` ```javascript assertEquals(new URL('file://C|/') + "", "file:///C:/"); ``` -------------------------------- ### Substring Matching Attribute Selector (Hyphen or Space) Source: https://github.com/devskale/chawan/blob/main/test/layout/attribute-selector.html Selects elements where the attribute value starts with a specific string, followed immediately by a hyphen or a space. This is often used for language codes or similar delimited values. ```css div[test2|=test-] { color: green } ``` -------------------------------- ### Create a Wrapper Script for Pager Source: https://github.com/devskale/chawan/blob/main/doc/troubleshooting.md Create a shell script to act as a wrapper for Chawan, ensuring it correctly handles the '-T text/x-ansi' argument even when programs call the pager directly without shell expansion. This script should be placed in your PATH. ```sh #!/bin/sh exec cha -T text/x-ansi "$@" ``` -------------------------------- ### Enable Vi Numeric Prefix in Input Source: https://github.com/devskale/chawan/blob/main/doc/config.md Sets the `vi-numeric-prefix` option to true, enabling vi-style numeric prefixes for commands within the [input] section. This setting is relevant for keybindings defined in the [page] section. ```toml [input] vi-numeric-prefix = true ``` -------------------------------- ### Explicit Environment for Closures Source: https://github.com/devskale/chawan/blob/main/doc/hacking.md To prevent implicit GC'ed environments and potential memory leaks with closures, explicitly pass the environment. This example shows how to define a callback type and a `Foo` object that includes an explicit `opaque` environment. ```nim type FooCallback = proc(foo: Foo; opaque: RootRef) {.nimcall, raises: [].} Foo = ref object callback: FooCallback opaque: RootRef # add an explicit environment like this if needed ``` -------------------------------- ### Configure Status Bar Options Source: https://github.com/devskale/chawan/blob/main/doc/config.md Set preferences for the status bar, such as displaying the cursor position or hover link information. ```toml show-cursor-position = true show-hover-link = true format-mode = "reverse" ``` -------------------------------- ### Client Interface Source: https://github.com/devskale/chawan/blob/main/doc/api.md The global object implements the Client interface, providing functions to control the browser, manage files, and access configuration. ```APIDOC ## Client Interface The global object (`globalThis`) implements the `Client` interface. Public functions include: ### `quit()` : Exit the browser. ### `suspend()` : Temporarily suspend the browser by delivering the client process a SIGTSTP signal. This suspends all processes, including buffers, the loader, and CGI. ### `readFile(path)` : Read a file at `path`. Returns the file's content as a string, or null if the file does not exist. ### `writeFile(path, content)` : Write `content` to the file at `path`. Throws a TypeError if this failed for any reason. ### `getenv(name, fallback = null)` : Get an environment variable by `name`. Returns `fallback` if the variable does not exist. ### `setenv(name, value)` : Set an environment variable by `name`. Throws a `TypeError` if the operation failed (e.g., because the variable's size exceeded an OS-specified limit). ### `pager` : The pager object. Implements `Pager`, as described below. ### `line` : The line editor. Implements `LineEdit`, as described below. ### `config` : The config object. An incomplete interface for retrieving and setting configuration options. Names generally match `config.toml`, with hyphens stripped and the next character capitalized (e.g., `external.cgi-dir` becomes `config.external.cgiDir`). Setting individual options may not always propagate as expected. The configuration directory can be queried as `config.dir`. ``` -------------------------------- ### Headers Object Manipulation Test Source: https://github.com/devskale/chawan/blob/main/test/js/headers.html Tests the append, delete, and get methods of the Headers object. It verifies case-insensitivity for header retrieval and checks for correct handling of multiple values for the same header. Also tests error conditions for invalid header names and constructor arguments. ```javascript const x = new Headers(); x.append("hi", "world"); x.append("test", "test") x.append("test", "a") x.append("test", "b") x.append("z", "g") x.delete("z") assertEquals(x.get("hi"), "world"); assertEquals(x.get("Hi"), "world"); assertEquals(x.get("hI"), "world"); assertEquals(x.get("test"), "test, a, b"); x.append("q", "a"); x.append("r", "b"); x.delete("q"); let fail = false; assertThrows(() => x.append("\u0100", {toString: () => fail = true}), TypeError); assert(!fail); assertEquals(x.get("q"), null); assertThrows(() => new Headers(null), TypeError); document.getElementById("x").textContent = "Success"; ```