Files
racket-webview/scrbl/racket-webview.scrbl
2026-04-01 16:23:56 +02:00

595 lines
15 KiB
Racket

#lang scribble/manual
@(require racket/base
scribble/core)
@title{racket-webview}
@author[@author+email["Hans Dijkema" "hans@dijkewijk.nl"]]
@defmodule[racket-webview]
Higher-level interface built on top of @racketmodname[racket-webview-qt].
This module provides a structured programming model around the lower-level
webview bindings. It introduces contexts, a local HTTPS server, JSON-based
event handling, and DOM and JavaScript utilities.
@section{Architecture}
The module builds on the lower-level bindings from
@racketmodname[racket-webview-qt]. It adds:
@itemlist[#:style 'compact
@item{structured Racket values instead of raw strings}
@item{JSON decoding of events and JavaScript results}
@item{a local HTTPS server per context}
@item{convenience functions for DOM manipulation}]
A context encapsulates a native webview context together with a local HTTPS
server. Windows are created within a context and communicate through events and
JavaScript calls. When an HTML file is
served, the context's CSS boilerplate is injected immediately before the
closing @tt{</head>} tag.
@section{Contexts}
@defproc[(webview-new-context
[file-getter procedure?]
[#:boilerplate-js boilerplate-js string?
(webview-default-boilerplate-js)]
[#:boilerplate-css boilerplate-css string?
(webview-default-boilerplate-css)])
wv-context?]{
Creates a new context.
The function:
@itemlist[#:style 'compact
@item{starts a local HTTPS server on a dynamically chosen port}
@item{generates a self-signed certificate}
@item{creates a native context}
@item{installs the provided JavaScript boilerplate in the native context}
@item{stores the provided CSS boilerplate in the context}]
The @racket[file-getter] procedure maps request paths to files. The
@racket[#:boilerplate-js] argument provides JavaScript support code passed to
the native context constructor. The javascript is injected by the native
QtWebEngine software. The @racket[#:boilerplate-css] argument provides
CSS boilerplate that is stored in the context and injected into served HTML
documents.
Certificate files are removed automatically when the context is garbage
collected.
}
@defproc[(wv-context-base-url [ctx wv-context?]) string?]{
Returns the base URL of the context.
This URL can be used to construct URLs from relative path information.
}
@defproc[(wv-context? [v any/c]) boolean?]{
Recognizes context values.
}
@section{Windows}
@defproc[(webview-create
[context wv-context?]
[url-path string?]
[event-callback procedure?]
[#:parent parent (or/c wv-win? #f) #f])
wv-win?]{
Creates a window in @racket[context], navigates it to @racket[url-path], and
returns a window handle.
@itemlist[#:style 'compact
@item{a native window is created}
@item{an event handler is installed}
@item{the context security token is applied}
@item{navigation is performed via the local server}]
The callback is invoked as:
@racketblock[
(event-callback wv evt)
]
where @racket[evt] is a parsed event hash table.
If @racket[parent] is provided, the new window becomes a child of that window.
}
@defproc[(wv-win-window-nr [wv wv-win?]) exact-integer?]{
Returns the native window number.
}
@defproc[(webview-close [wv wv-win?]) symbol?]{
Closes the window. Always returns @racket['oke].
}
@defproc[(webview-devtools [wv wv-win?]) symbol?]{
Opens developer tools for the window.
}
@defproc[(webview-move [wv wv-win?] [x number?] [y number?]) symbol?]{
Moves the window.
}
@defproc[(webview-resize [wv wv-win?] [w number?] [h number?]) symbol?]{
Resizes the window.
}
@defproc[(webview-show [wv wv-win?]) symbol?]{Shows the window.}
@defproc[(webview-hide [wv wv-win?]) symbol?]{Hides the window.}
@defproc[(webview-show-normal [wv wv-win?]) symbol?]{Shows the window in normal state.}
@defproc[(webview-maximize [wv wv-win?]) symbol?]{Maximizes the window.}
@defproc[(webview-minimize [wv wv-win?]) symbol?]{Minimizes the window.}
@defproc[(webview-window-state [wv wv-win?]) symbol?]{
Returns the current window state.
}
@section{Navigation and Content}
@defproc[(webview-set-url! [wv wv-win?] [url (or/c string? url?)])
symbol?]{
Loads @racket[url].
}
@defproc[(webview-navigate! [wv wv-win?] [place string?]) symbol?]{
Navigates by assigning @tt{window.location} via JavaScript.
}
@defproc[(webview-base-url [wv wv-win?]) url?]{
Returns the context base URL as a URL value.
}
@defproc[(webview-set-html! [wv wv-win?] [html (or/c string? xexpr?)])
symbol?]{
Replaces the current document contents.
X-expressions are converted to strings before being passed to JavaScript.
}
@defproc[(webview-set-menu! [wv wv-win?] [menu is-wv-menu?])
symbol?]{
Installs @racket[menu] in @racket[wv].
The menu is converted to JSON using @racket[wv-menu->json] and then passed to
the browser by evaluating JavaScript through @racket[webview-run-js].
The result is the symbol returned by @racket[webview-run-js].
}
@defproc[(webview-set-title! [wv wv-win?] [title string?]) symbol?]{
Sets the window title.
}
@section{JavaScript}
@defproc[(webview-run-js [wv wv-win?] [js string?]) symbol?]{
Evaluates JavaScript.
}
@defproc[(webview-call-js-result? [x any/c]) boolean?]{
Recognizes lower-level JavaScript call results.
}
@defproc[(webview-call-js [wv wv-win?] [js string?])
(or/c string? list? boolean? hash?)]{
Evaluates JavaScript and returns a decoded value.
If the lower-level call fails or the result does not match the expected
structure, an exception is raised.
}
@section{Dialogs}
Dialog functions return immediately. Results are delivered asynchronously via
events.
@defproc[(webview-messagebox
[wv wv-win?]
[type symbol?]
[title string?]
[message string?]
[#:sub submessage string? ""])
symbol?]{
Shows a message box.
The user response is delivered asynchronously via events. If dismissed or
canceled, this is indicated through the event.
}
@defproc[(webview-choose-dir
[wv wv-win?]
[title string?]
[base-dir (or/c path? string?)])
symbol?]{
Shows a directory chooser.
The selected directory is delivered asynchronously via events. If canceled,
this is indicated through the event.
}
@defproc[(webview-file-open
[wv wv-win?]
[title string?]
[base-dir (or/c path? string?)]
[permitted-exts (or/c wv-permitted-exts? wv-list-of-permitted-exts?)])
symbol?]{
Shows an open-file dialog.
The selected file is delivered asynchronously via events. If canceled, this is
indicated through the event.
}
@defproc[(webview-file-save
[wv wv-win?]
[title string?]
[base-dir (or/c path? string?)]
[permitted-exts (or/c wv-permitted-exts? wv-list-of-permitted-exts?)])
symbol?]{
Shows a save-file dialog.
The file to be saved is delivered asynchronously via events. If canceled, this
is indicated through the event.
}
@section{DOM Interaction}
@subsection{Selectors and Element Identifiers}
Many functions accept either an element identifier or a CSS selector.
If a symbol is provided, it is interpreted as an element id. The symbol is
converted to a string and prefixed with @tt{"#"}.
If a string is provided, it is used directly as a CSS selector.
@itemlist[#:style 'compact
@item{a symbol refers to a single element by id}
@item{a string may refer to one or more elements}
@item{CSS selector semantics are those of the browser engine}]
Functions apply their effect to all matched elements.
@subsection{Event Binding}
@defproc[(webview-bind!
[wv wv-win?]
[selector (or/c symbol? string?)]
[event (or/c symbol? list-of-symbol?)])
list?]{
Installs one or more DOM event bindings.
If @racket[selector] is a symbol, it is interpreted as an element id and
converted to a CSS selector by prefixing @tt{"#"}.
The result is a list describing the installed bindings.
}
@defproc[(webview-unbind!
[wv wv-win?]
[selector (or/c symbol? string?)]
[event (or/c symbol? list-of-symbol?)])
list?]{
Removes one or more DOM event bindings.
Selector handling is the same as for @racket[webview-bind!]. The result is a
list describing the removed bindings.
}
@subsection{DOM Values}
@defproc[(webview-set-value!
[wv wv-win?]
[id symbol?]
[val (or/c symbol? string? number? boolean?
g:date? g:time? g:datetime? rgba?)])
symbol?]{
Sets the value of the element identified by @racket[id] using JavaScript.
For checkboxes and radio buttons, the checked state is updated. Other elements
receive a string value. Dates, times, datetimes, and colors are converted to
strings before being passed to JavaScript.
}
@defproc[(webview-value [wv wv-win?] [id symbol?])
(or/c string? boolean?)]{
Returns the value of the element identified by @racket[id].
For checkboxes and radio buttons, the result reflects the checked state. Other
elements return their @tt{value} property.
}
@defproc[(webview-value/boolean [wv wv-win?] [id symbol?])
(or/c boolean? #f)]{
Returns the value converted to a boolean.
}
@defproc[(webview-value/symbol [wv wv-win?] [id symbol?])
(or/c symbol? #f)]{
Returns the value converted to a symbol.
}
@defproc[(webview-value/number [wv wv-win?] [id symbol?])
(or/c number? #f)]{
Returns the value converted to a number.
}
@defproc[(webview-value/date [wv wv-win?] [id symbol?])
(or/c g:date? #f)]{
Returns the value converted to a date.
}
@defproc[(webview-value/time [wv wv-win?] [id symbol?])
(or/c g:time? #f)]{
Returns the value converted to a time.
}
@defproc[(webview-value/datetime [wv wv-win?] [id symbol?])
(or/c g:datetime? #f)]{
Returns the value converted to a datetime.
}
@defproc[(webview-value/color [wv wv-win?] [id symbol?])
(or/c rgba? #f)]{
Returns the value converted to a color.
}
@subsection{Classes, Styles}
@defproc[(webview-add-class!
[wv wv-win?]
[selector (or/c symbol? string?)]
[class (or/c symbol? string? list?)])
hash?]{
Adds one or more CSS classes using JavaScript.
If @racket[selector] is a symbol, it is treated as an element id. If it is a
string, it is used directly as a CSS selector.
The effect is applied to all matched elements.
}
@defproc[(webview-remove-class!
[wv wv-win?]
[selector (or/c symbol? string?)]
[class (or/c symbol? string? list?)])
hash?]{
Removes one or more CSS classes using JavaScript.
Selector handling is the same as for @racket[webview-add-class!].
}
@defproc[(webview-set-style!
[wv wv-win?]
[selector (or/c symbol? string?)]
[style-entries (or/c kv? list-of-kv?)])
hash?]{
Sets inline style properties using JavaScript.
The effect is applied to all elements matched by @racket[selector].
}
@defproc[(webview-unset-style!
[wv wv-win?]
[selector (or/c symbol? string?)]
[style-entries (or/c symbol? list-of-symbol?)])
hash?]{
Clears inline style properties using JavaScript.
The effect is applied to all elements matched by @racket[selector].
}
@defproc[(webview-get-style
[wv wv-win?]
[selector (or/c symbol? string?)]
[styles (or/c symbol? list-of-symbol?)])
(or/c list? hash?)]{
Retrieves computed style values.
If @racket[selector] is a symbol, the result for that single element is returned
directly. Otherwise the result covers all matched elements.
}
@subsection{Attributes}
@defproc[(webview-set-attr!
[wv wv-win?]
[selector (or/c symbol? string?)]
[attr-entries (or/c kv? list-of-kv?)])
hash?]{
Sets attributes using JavaScript.
Dates, times, datetimes, and colors are converted to strings before being passed
to JavaScript. The effect is applied to all elements matched by
@racket[selector].
}
@defproc[(webview-attr
[wv wv-win?]
[id symbol?]
[attr (or/c symbol? string?)])
(or/c string? boolean?)]{
Returns the attribute value of the element identified by @racket[id].
If the JavaScript result is @tt{null}, the function returns @racket[#f].
}
@defproc[(webview-attr/boolean
[wv wv-win?]
[id symbol?]
[attr (or/c symbol? string?)])
(or/c boolean? #f)]{
Returns the attribute value converted to a boolean.
}
@defproc[(webview-attr/symbol
[wv wv-win?]
[id symbol?]
[attr (or/c symbol? string?)])
(or/c symbol? #f)]{
Returns the attribute value converted to a symbol.
}
@defproc[(webview-attr/number
[wv wv-win?]
[id symbol?]
[attr (or/c symbol? string?)])
(or/c number? #f)]{
Returns the attribute value converted to a number.
}
@defproc[(webview-attr/date
[wv wv-win?]
[id symbol?]
[attr (or/c symbol? string?)])
(or/c g:date? #f)]{
Returns the attribute value converted to a date.
}
@defproc[(webview-attr/time
[wv wv-win?]
[id symbol?]
[attr (or/c symbol? string?)])
(or/c g:time? #f)]{
Returns the attribute value converted to a time.
}
@defproc[(webview-attr/datetime
[wv wv-win?]
[id symbol?]
[attr (or/c symbol? string?)])
(or/c g:datetime? #f)]{
Returns the attribute value converted to a datetime.
}
@defproc[(webview-attr/color
[wv wv-win?]
[id symbol?]
[attr (or/c symbol? string?)])
(or/c rgba? #f)]{
Returns the attribute value converted to a color.
}
@subsection{Inner HTML}
@defproc[(webview-set-innerHTML!
[wv wv-win?]
[id symbol?]
[html (or/c string? xexpr?)])
symbol?]{
Sets the innerHTML of the element identified by @racket[id] using JavaScript.
Returns @racket['oke] if the injected JavaScript yields a true value, and
@racket['failed] otherwise.
}
@section{File Filters}
@defstruct*[wv-permitted-exts ([name string?]
[exts (listof symbol?)])]{
Represents a file dialog filter entry.
}
@defproc[(make-wv-permitted-exts [name string?] [exts (listof symbol?)])
wv-permitted-exts?]{Creates a filter entry.}
@defproc[(wv-permitted-exts? [v any/c]) boolean?]{Recognizes filter entries.}
@defproc[(wv-list-of-permitted-exts? [v any/c]) boolean?]{
Recognizes lists of filter entries.
}
@section{Utilities}
@defproc[(webview-default-boilerplate-js [custom-js procedure?] ...)
string?]{
Returns the default JavaScript boilerplate.
The result is constructed by concatenating the contents of @tt{js/*.js}.
If an additional procedure is supplied, its returned string is appended
to that JavaScript.
}
@defproc[(webview-default-boilerplate-css [custom-css procedure?] ...)
string?]{
Returns the default CSS boilerplate.
The result is constructed by concatenating the contents of @tt{js/*.css}.
If an additional procedure is supplied, its returned string is appended to that CSS.
}
@defproc[(webview-standard-file-getter
[base-path path-string?]
[#:not-exist f procedure?])
procedure?]{
Creates a standard file getter.
}
@section{Diagnostics}
@defproc[(webview-version) list?]{
Returns version information.
}
@defproc[(webview-info) list?]{
Returns runtime information.
}
@defproc[(webview-set-loglevel [l (or/c 'error 'warning 'info 'debug)])
void?]{
Sets the native log level.
The native log file path can be obtained via @racket[webview-info].
}