### 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";
```