#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{} 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]. }