Web Wire:   Low-Level Web  UI Command Layer
1 Startup and shutdown
ww-start
ww-stop
2 Debugging and log inspection
ww-set-debug
ww-debug
ww-error
ww-set-log-lines!
ww-display-log
ww-tail-log
3 Backend settings and protocol info
ww-log-level
ww-protocol
ww-cwd
4 Global stylesheet
ww-set-stylesheet
ww-get-stylesheet
5 Window handles and window management
ww-win
ww-new
ww-close
ww-move
ww-resize
ww-set-title
ww-set-icon
ww-set-menu
ww-set-show-state
ww-get-show-state
6 HTML /   URL content
ww-set-html-file
ww-set-url
ww-set-inner-html
ww-get-inner-html
7 Attributes, CSS, classes
ww-set-attr
ww-get-attr
ww-get-attrs
ww-del-attr
ww-add-style
ww-set-style
ww-get-style
ww-add-class
ww-remove-class
ww-has-class?
8 Values and element queries
ww-get-value
ww-set-value
ww-get-elements
ww-element-info
9 Events
ww-bind
ww-on
10 File and directory dialogs
ww-file-open
ww-file-save
ww-choose-dir
11 Low-level command access
ww-cmd
ww-cmd-nok?
ww-from-string
12 Window tables
windows
windows-evt-handlers
ww-get-window-for-id
13 Helper predicates used in contracts
stylesheet-or-string?
is-icon-file?
html-file-exists?
html-or-file?
symbol-or-string?
any?
path-or-string?
selector?
9.0

Web Wire: Low-Level WebUI Command Layer🔗ℹ

Hans Dijkema <hans@dijkewijk.nl>

 (require web-wire)

The web-wire module is the low-level bridge between Racket and the external webui-wire helper process.

On the Racket side it exposes functions like:

  • starting and stopping the backend (ww-start, ww-stop);

  • log inspection and debugging helpers;

  • window management (create, move, resize, set title/icon/menu);

  • DOM operations (HTML content, attributes, CSS, classes, values);

  • element queries and event binding;

  • file/directory chooser dialogs.

Most of these functions ultimately send a textual command to webui-wire (via webui-ipc) and convert the reply into a convenient Racket value.

1 Startup and shutdown🔗ℹ

procedure

(ww-start log-level)  web-rkt?

  log-level : symbol?
Starts the Web Wire backend (if it is not already running) and returns the current web-rkt handle.

Internally this:

  • creates queues and semaphores for events and logs;

  • starts an IPC connection via webui-ipc;

  • spawns a background thread that handles incoming events and log lines;

  • stores the handle in an internal variable.

If log-level is supplied, it is passed to ww-log-level to configure the remote log level.

Calling ww-start when the backend is already running is a no-op: the existing handle is returned.

The backend type is currently always 'ipc; FFI integration is not implemented yet.

procedure

(ww-stop)  void?

Stops the Web Wire backend.

This function:

  • notifies registered window event handlers that windows are being destroyed;

  • sends an "exit"-style command to webui-wire;

  • stops the event-handling thread;

  • clears the current backend handle.

After ww-stop, calling window/DOM functions will fail until ww-start is used again.

2 Debugging and log inspection🔗ℹ

These functions control and inspect the logging used by this module and its event thread.

procedure

(ww-set-debug on?)  void?

  on? : boolean?
Enables or disables verbose internal debug logging in web-wire. This affects calls through ww-debug, but does not change the remote log level of webui-wire; for that, use ww-log-level.

syntax

(ww-debug msg-expr)

#:contracts
([msg-expr any/c])
(ww-debug id-expr msg-expr)
#:contracts
([id-expr any/c] [msg-expr any/c])
Debug logging macros used inside the module.

When ww-set-debug has been enabled, these macros:

  • format msg-expr (and optionally id-expr);

  • enqueue a debug log line in the in-memory log buffer.

They are primarily intended for development and diagnostics.

syntax

(ww-error msg-expr)

#:contracts
([msg-expr any/c])
(ww-error id-expr msg-expr)
#:contracts
([id-expr any/c] [msg-expr any/c])
Error logging macros.

These always log, regardless of the debug flag, and are used for internal error conditions. Log lines are stored in the same log buffer used by ww-display-log and ww-tail-log.

procedure

(ww-set-log-lines! n)  void?

  n : exact-nonnegative-integer?
Sets the maximum number of log lines kept in the in-memory ring buffer.

The value is clamped between 10 and 10,000. When the buffer exceeds this limit, the oldest entries are dropped.

procedure

(ww-display-log [filter])  void?

  filter : (or/c #f string? regexp? (listof string?)) = #f
Prints the contents of the log buffer to current-output-port.

The optional filter controls which lines are shown:

  • #f — show all entries;

  • string? — case-insensitive substring match;

  • regexp? — regular expression match;

  • (listof string?) — OR-combination of substring filters.

procedure

(ww-tail-log args ...)  void?

  args : any/c
Shows the last part of the log buffer and then follows new entries, similar to tail -f.

The optional args are interpreted as:

  • a number: how many last lines to show initially;

  • a filter (string, regexp, or list of strings) as in ww-display-log;

  • a boolean #f to stop an existing tail session.

This is mainly intended for interactive debugging.

3 Backend settings and protocol info🔗ℹ

procedure

(ww-log-level level)  symbol?

  level : symbol?
Configures the log level inside the webui-wire helper.

This function is defined via:

(def-cmd ww-log-level
  loglevel () ((level symbol?)) -> symbol)

so level is optional:

  • with an argument, the remote log level is set to level and the effective level is returned;

  • without arguments, the current remote log level is queried and returned.

procedure

(ww-protocol)  exact-integer?

Returns the protocol version spoken by the webui-wire helper.

Definition (simplified):

(def-cmd ww-protocol
  protocol () () -> int)

The result is an integer that should match the protocol version that the Racket side expects.

procedure

(ww-cwd path)  path?

  path : path-or-string?
Gets or sets the current working directory used by webui-wire.

This function is defined as:

(def-cmd ww-cwd
  cwd () [(path path-or-string?)] -> path)

Semantics:

  • With a path, the helper’s working directory is set and the new directory (as a path) is returned.

  • Without arguments, the current directory (as seen by the helper) is returned.

This directory is used to resolve relative file names (HTML files, icons, etc.).

4 Global stylesheet🔗ℹ

procedure

(ww-set-stylesheet st)  void?

  st : stylesheet-or-string?
Sets the global stylesheet used by WebUI windows:

(def-cmd ww-set-stylesheet
  set-stylesheet ((st stylesheet-or-string?)) () -> void)

The argument st may be either:

  • a stylesheet value understood by the WebUI side;

  • a raw CSS string.

procedure

(ww-get-stylesheet)  stylesheet?

Returns the currently configured global stylesheet:

(def-cmd ww-get-stylesheet
  get-stylesheet () () -> stylesheet)

5 Window handles and window management🔗ℹ

struct

(struct ww-win (id))

  id : exact-integer?
Opaque handle representing a WebUI window.

The internal id field corresponds to the numeric window id used by the webui-wire backend.

procedure

(ww-new profile use-browser parent)  ww-win?

  profile : symbol?
  use-browser : boolean?
  parent : ww-win?
Creates a new WebUI window:

(def-cmd ww-new
  new ((profile symbol?)) [(use-browser boolean?) (parent ww-win?)]
  -> ww-win)

Arguments:

  • profile symbolic profile name used by the helper to select configuration (e.g. 'default).

  • use-browser when true, prefers an external browser instead of an embedded webview where supported.

  • parent optional parent window (for dialog-like windows).

Returns a ww-win handle.

procedure

(ww-close win-id)  void?

  win-id : ww-win?
Closes the given window:

(def-cmd ww-close
  close ((win-id ww-win?)) [] -> void)

procedure

(ww-move win-id x y)  void?

  win-id : ww-win?
  x : number?
  y : number?
Moves the window to position (x, y) in pixels:

(def-cmd ww-move
  move ((win-id ww-win?) (x number?) (y number?)) [] -> void)

procedure

(ww-resize win-id width height)  void?

  win-id : ww-win?
  width : number?
  height : number?
Resizes the window to the given pixel width and height:

(def-cmd ww-resize
  resize ((win-id ww-win?) (width? number?) (height number?)) [] -> void)

procedure

(ww-set-title win-id title)  void?

  win-id : ww-win?
  title : string?
Sets the window title:

(def-cmd ww-set-title
  set-title ((win-id ww-win?) (title string?)) [] -> void)

procedure

(ww-set-icon win-id svg-file png-file)  void?

  win-id : ww-win?
  svg-file : (is-icon-file? 'svg)
  png-file : (is-icon-file? 'png)
Sets the window icon, given paths to an SVG and PNG file:

(def-cmd ww-set-icon
  set-icon ((win-id ww-win?)
            (svg-file (is-icon-file? 'svg))
            (png-file (is-icon-file? 'png))) [] -> void)

The predicates (is-icon-file? 'svg) and (is-icon-file? 'png) ensure that the paths refer to existing files with the correct file extension.

procedure

(ww-set-menu win-id menu)  void?

  win-id : ww-win?
  menu : is-menu?
Configures the window menu:

(def-cmd ww-set-menu
  set-menu ((win-id ww-win?)
            (menu is-menu?)) [] -> void)

The menu value is a menu structure as defined in "menu.rkt".

procedure

(ww-set-show-state win-id state)  void?

  win-id : ww-win?
  state : symbol?
Sets the show state of the window:

(def-cmd ww-set-show-state
  set-show-state ((win-id ww-win?)
                  (state symbol?)) () -> void)

Typical states are things like 'normal, 'maximized, etc., depending on what the backend supports.

procedure

(ww-get-show-state win-id)  symbol?

  win-id : ww-win?
Returns the current show state of the window:

(def-cmd ww-get-show-state
  show-state ((win-id ww-win?)) () -> symbol)

6 HTML / URL content🔗ℹ

procedure

(ww-set-html-file win-id html-file)  exact-integer?

  win-id : ww-win?
  html-file : html-file-exists?
Loads the given HTML file into the window:

(def-cmd ww-set-html-file
  set-html ((win-id ww-win?)
            (html-file html-file-exists?)) ()
  -> number)

The html-file argument must exist (resolved against ww-cwd); otherwise an error is raised. The return value is a numeric status code from the helper.

procedure

(ww-set-url win-id url)  void?

  win-id : ww-win?
  url : string?
Navigates the window to the given URL:

(def-cmd ww-set-url
  set-url ((win-id ww-win?)
           (url string?)) () -> void)

procedure

(ww-set-inner-html win-id    
  element-id    
  html-of-file)  void?
  win-id : ww-win?
  element-id : symbol-or-string?
  html-of-file : html-or-file?
Replaces the innerHTML of the given element:

(def-cmd ww-set-inner-html
  set-inner-html ((win-id ww-win?)
                  (element-id symbol-or-string?)
                  (html-of-file html-or-file?)) () -> void)

The html-of-file value is either a string containing HTML or a path to a file whose contents are used as HTML.

procedure

(ww-get-inner-html win-id element-id)  jsexpr?

  win-id : ww-win?
  element-id : symbol-or-string?
Gets the innerHTML of the element as JSON:

(def-cmd ww-get-inner-html
  get-inner-html ((win-id ww-win?)
                  (element-id symbol-or-string?)) () -> json)

7 Attributes, CSS, classes🔗ℹ

procedure

(ww-set-attr win-id element-id attr val)  void?

  win-id : ww-win?
  element-id : symbol-or-string?
  attr : symbol-or-string?
  val : any?
Sets an attribute on an element:

(def-cmd ww-set-attr
  set-attr ((win-id ww-win?)
            (element-id symbol-or-string?)
            (attr symbol-or-string?)
            (val any?)) () -> void)

procedure

(ww-get-attr win-id element-id attr)  jsexpr?

  win-id : ww-win?
  element-id : symbol-or-string?
  attr : symbol-or-string?
Returns the value of a specific attribute as JSON:

(def-cmd ww-get-attr
  get-attr ((win-id ww-win?)
            (element-id symbol-or-string?)
            (attr symbol-or-string?)) () -> json)

procedure

(ww-get-attrs win-id element-id)  jsexpr?

  win-id : ww-win?
  element-id : symbol-or-string?
Returns all attributes of the element in JSON form, converted on the Racket side by a helper:

(def-cmd ww-get-attrs
  get-attrs ((win-id ww-win?)
             (element-id symbol-or-string?)) () -> json
  -> mk-attrs)

procedure

(ww-del-attr win-id element-id attr)  void?

  win-id : ww-win?
  element-id : symbol-or-string?
  attr : symbol-or-string?
Removes an attribute from the element:

(def-cmd ww-del-attr
  del-attr ((win-id ww-win?)
            (element-id symbol-or-string?)
            (attr symbol-or-string?)) () -> void)

procedure

(ww-add-style win-id element-id css-style)  void?

  win-id : ww-win?
  element-id : symbol-or-string?
  css-style : css-style?
Adds or merges CSS style for an element:

(def-cmd ww-add-style
  add-style ((win-id ww-win?)
             (element-id symbol-or-string?)
             (css-style css-style?)) () -> void)

procedure

(ww-set-style win-id element-id css-style)  void?

  win-id : ww-win?
  element-id : symbol-or-string?
  css-style : css-style?
Replaces the CSS style of an element:

(def-cmd ww-set-style
  set-style ((win-id ww-win?)
             (element-id symbol-or-string?)
             (css-style css-style?)) () -> void)

procedure

(ww-get-style win-id element-id)  css-style?

  win-id : ww-win?
  element-id : symbol-or-string?
Gets the CSS style of an element:

(def-cmd ww-get-style
  get-style ((win-id ww-win?)
             (element-id symbol-or-string?)) ()
  -> css-style)

procedure

(ww-add-class win-id element-id class)  void?

  win-id : ww-win?
  element-id : symbol-or-string?
  class : symbol-or-string?
Adds a CSS class:

(def-cmd ww-add-class
  add-class ((win-id ww-win?)
             (element-id symbol-or-string?)
             (class symbol-or-string?))
  () -> void)

procedure

(ww-remove-class win-id element-id class)  void?

  win-id : ww-win?
  element-id : symbol-or-string?
  class : symbol-or-string?
Removes a CSS class:

(def-cmd ww-remove-class
  remove-class ((win-id ww-win?)
                (element-id symbol-or-string?)
                (class symbol-or-string?))
  () -> void)

procedure

(ww-has-class? win-id element-id class)  boolean?

  win-id : ww-win?
  element-id : symbol-or-string?
  class : symbol-or-string?
Tests for a CSS class:

(def-cmd ww-has-class?
  has-class ((win-id ww-win?)
             (element-id symbol-or-string?)
             (class symbol-or-string?)) ()
  -> bool)

8 Values and element queries🔗ℹ

procedure

(ww-get-value win-id element-id)  string?

  win-id : ww-win?
  element-id : symbol-or-string?
Gets the “value” of an element:

(def-cmd ww-get-value
  value ((win-id ww-win?)
         (element-id symbol-or-string?)) () -> string)

procedure

(ww-set-value win-id element-id value)  void?

  win-id : ww-win?
  element-id : symbol-or-string?
  value : any?
Sets the “value” of an element:

(def-cmd ww-set-value
  value ((win-id ww-win?)
         (element-id symbol-or-string?)
         (value any?)) () -> void)

procedure

(ww-get-elements win-id selector)  jsexpr?

  win-id : ww-win?
  selector : selector?
Queries elements matching a CSS-like selector:

(def-cmd ww-get-elements
  get-elements ((win-id ww-win?)
                (selector selector?)) () -> json
  -> (λ (r) ...))

The raw JSON result is converted by a small helper into a more usable Racket structure (see the implementation).

procedure

(ww-element-info win-id element-id)  jsexpr?

  win-id : ww-win?
  element-id : symbol-or-string?
Returns structural information about an element:

(def-cmd ww-element-info
  element-info ((win-id ww-win?)
                (element-id symbol-or-string?)) ()
  -> json
  -> (λ (r) ...))

9 Events🔗ℹ

procedure

(ww-bind win-id event selector)  jsexpr?

  win-id : ww-win?
  event : symbol-or-string?
  selector : selector?
Binds an event to all elements matching selector:

(def-cmd ww-bind
  bind ((win-id ww-win?)
        (event symbol-or-string?)
        (selector selector?)) () -> json
  -> (λ (r) ...))

The JSON result includes information about the bound elements.

procedure

(ww-on win-id event id)  void?

  win-id : ww-win?
  event : symbol-or-string?
  id : symbol-or-string?
Binds event for a single element id:

(def-cmd ww-on
  on ((win-id ww-win?)
      (event symbol-or-string?)
      (id symbol-or-string?)) () -> void)

10 File and directory dialogs🔗ℹ

procedure

(ww-file-open win-id    
  caption    
  dir    
  file-filters)  string?
  win-id : ww-win?
  caption : string?
  dir : string?
  file-filters : string?
Opens a file-open dialog:

(def-cmd ww-file-open
  file-open ((win-id ww-win?)
             (caption string?)
             (dir string?)
             (file-filters string?)) ()
  -> string)

Returns the selected path as a string, or an empty string on cancel.

procedure

(ww-file-save win-id    
  caption    
  dir    
  file-filters    
  overwrite)  string?
  win-id : ww-win?
  caption : string?
  dir : string?
  file-filters : string?
  overwrite : boolean?
Opens a file-save dialog:

(def-cmd ww-file-save
  file-save ((win-id ww-win?)
             (caption string?)
             (dir string?)
             (file-filters string?)
             (overwrite boolean?)) ()
  -> string)

Returns the chosen file path as a string, or an empty string if the user cancels.

procedure

(ww-choose-dir win-id caption dir)  string?

  win-id : ww-win?
  caption : string?
  dir : string?
Opens a directory chooser dialog:

(def-cmd ww-choose-dir
  choose-dir ((win-id ww-win?)
              (caption string?)
              (dir string?)) ()
  -> string)

Returns the selected directory path as a string, or an empty string on cancel.

11 Low-level command access🔗ℹ

procedure

(ww-cmd cmd)  cmdr?

  cmd : string?
Sends a raw command string cmd to webui-wire and returns a cmdr struct describing the reply.

This is the lowest-level escape hatch; all def-cmd-generated functions use this under the hood.

procedure

(ww-cmd-nok? r)  boolean?

  r : any/c
Predicate that recognises a failed command reply:

  • returns #t if r is a cmdr with a false ok field, or the symbol 'cmd-nok;

  • returns #f otherwise.

procedure

(ww-from-string s)  string?

  s : string?
Helper that “unquotes” and unescapes a string previously encoded for transmission over the wire:

  • removes surrounding quotes;

  • replaces escaped quotes (\"\\\"\") by plain quotes.

12 Window tables🔗ℹ

value

windows : (hash/c exact-integer? ww-win?)

Hash table containing the currently known windows, keyed by numeric id.

This is mainly useful for diagnostics and advanced introspection; most application code keeps explicit ww-win handles instead.

value

windows-evt-handlers

 : (hash/c exact-integer? (-> symbol? any/c any))
Hash table mapping window ids to their registered event handlers. Handlers are called with an event kind (a symbol) and associated data.

procedure

(ww-get-window-for-id win-id)  (or/c ww-win? #f)

  win-id : exact-integer?
Looks up the ww-win struct for a numeric win-id in the windows table. Returns #f if no such window is known.

13 Helper predicates used in contracts🔗ℹ

The following predicates are used as argument checkers in the def-cmd-generated functions above.

procedure

(stylesheet-or-string? st)  boolean?

  st : any/c
Returns #t if st is either a stylesheet value or a string:

(define (stylesheet-or-string? st)
  (or (stylesheet? st) (string? st)))

procedure

(is-icon-file? ext)  (-> any/c boolean?)

  ext : symbol?
Returns a predicate that checks “existing file with the right extension”:

(define (is-icon-file? ext)
  (lambda (v)
    (and (string? v)
         (string-suffix? v (string-append "." (symbol->string ext)))
         (file-exists? v))))

Used in ww-set-icon with 'svg and 'png.

procedure

(html-file-exists? f)  boolean?

  f : path-or-string?
Checks whether f refers to an existing file, either directly or resolved relative to ww-cwd:

(define (html-file-exists? f)
  (if (file-exists? f)
      #t
      (let* ((cwd (ww-cwd))
             (full-file (build-path cwd f)))
        (ww-debug (format "file-exists? '~a'" full-file))
        (file-exists? full-file))))

procedure

(html-or-file? v)  boolean?

  v : any/c
Returns #t if v is either an existing file or a string:

(define (html-or-file? v)
  (if (file-exists? v)
      #t
      (string? v)))

procedure

(symbol-or-string? s)  boolean?

  s : any/c
True if s is a symbol or a string:

(define (symbol-or-string? s)
  (or (symbol? s) (string? s)))

procedure

(any? v)  boolean?

  v : any/c
Predicate that always returns #t; used in contracts when no extra checking is required.

procedure

(path-or-string? s)  boolean?

  s : any/c
True if s is a path or string:

(define (path-or-string? s)
  (or (path? s) (string? s)))

procedure

(selector? s)  boolean?

  s : any/c
Predicate for element selectors:

  • symbol? — a single symbolic selector;

  • string? — a string selector;

  • a non-empty list of symbols/strings.

Implementation sketch:

(define (selector? s)
  (or (symbol? s) (string? s)
      (and (list? s)
           (not (null? s))
           (letrec ([f (λ (l)
                         (if (null? l)
                             #t
                             (and (or (symbol? (car l))
                                      (string? (car l)))
                                  (f (cdr l)))))]
             (f s))))))