bind

package
v0.501.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 3, 2026 License: MIT Imports: 8 Imported by: 3

Documentation

Overview

Package bind adapts Go values to JaWS getter, setter, HTML and tag interfaces.

The constructors in this package accept either existing bind interfaces or static values and return small adapters that can be used by package ui widgets.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrFloatNotFinite reports that a float value is NaN or infinite.
	//
	// Such values, typically from the untrusted browser, corrupt the bound value;
	// NaN in particular defeats the equality-based update dedup (NaN != NaN). They
	// are rejected at the binding boundary.
	ErrFloatNotFinite = errors.New("float value is not finite")
	// ErrFloatOutOfRange reports that a finite float does not fit the target type.
	//
	// The float-to-int conversion of an out-of-range value is implementation-defined
	// and silently wraps, so it is rejected rather than performed.
	ErrFloatOutOfRange = errors.New("float value out of range for target type")
)
View Source
var ErrValueNotSettable = errors.New("value not settable")

ErrValueNotSettable is returned by read-only adapters when [Setter.JawsSet] is called.

Functions

This section is empty.

Types

type Binder

type Binder[T comparable] interface {
	RWLocker
	Setter[T]
	tag.TagGetter
	jaws.ClickHandler
	jaws.ContextMenuHandler
	jaws.InitialHTMLAttrHandler

	JawsGetLocked(elem *jaws.Element) (value T)
	JawsSetLocked(elem *jaws.Element, value T) (err error)

	// JawsInitialHTMLAttrLocked returns the initial HTML attribute while
	// the Binder lock is held.
	JawsInitialHTMLAttrLocked(elem *jaws.Element) (s template.HTMLAttr)

	// SetLocked returns a [Binder] that will call fn instead of [Binder.JawsSetLocked].
	//
	// The lock will be held at this point.
	// Do not lock or unlock the [Binder] within fn. Do not call [Setter.JawsSet].
	//
	// The bind argument to the function is the previous Binder in the chain,
	// and you probably want to call its [Binder.JawsSetLocked] first.
	SetLocked(fn SetHook[T]) (newbind Binder[T])

	// GetLocked returns a [Binder] that will call fn instead of [Binder.JawsGetLocked].
	//
	// The lock will be held at this point, preferring RLock over Lock, if available.
	// Do not lock or unlock the [Binder] within fn. Do not call [Getter.JawsGet].
	//
	// The bind argument to the function is the previous Binder in the chain,
	// and you probably want to call its [Binder.JawsGetLocked] first.
	GetLocked(fn GetHook[T]) (newbind Binder[T])

	// Success returns a [Binder] that will call fn after the value has been set
	// with no errors. No locks are held when the function is called.
	// If the function returns an error, that will be returned from [Setter.JawsSet].
	//
	// The function must have one of the following signatures:
	//  * func()
	//  * func() error
	//  * func(*jaws.Element)
	//  * func(*jaws.Element) error
	Success(fn any) (newbind Binder[T])

	// GetHTML returns a [Binder] that will call fn instead of the default
	// escaped fmt.Sprint(JawsGetLocked(elem)) HTML rendering.
	//
	// The lock will be held at this point, preferring RLock over Lock, if available.
	// Do not lock or unlock the [Binder] within fn. Do not call [Getter.JawsGet].
	//
	// Unlike [Binder.GetLocked] and [Binder.SetLocked], the bind argument to fn is
	// the current Binder, not the previous one; read the value with its
	// JawsGetLocked to render it. See [GetHTMLHook].
	GetHTML(fn GetHTMLHook[T]) (newbind Binder[T])

	// Format returns a [Binder] that implements [HTMLGetter] and
	// calls html.EscapeString on either fmt.Sprintf(format, JawsGetLocked(elem))
	// or, if T implements [Formatter], T.Format(format).
	Format(format string) (newbind Binder[T])

	// Clicked returns a [Binder] that will call fn when [jaws.ClickHandler.JawsClick] is invoked.
	//
	// The [Binder] locks are not held when the function is called.
	Clicked(fn ClickedHook[T]) (newbind Binder[T])

	// ContextMenu returns a [Binder] that will call fn when
	// [jaws.ContextMenuHandler.JawsContextMenu] is invoked.
	//
	// The [Binder] locks are not held when the function is called.
	ContextMenu(fn ContextMenuHook[T]) (newbind Binder[T])

	// InitialHTMLAttr returns a [Binder] that will call fn when
	// [jaws.InitialHTMLAttrHandler.JawsInitialHTMLAttr] is invoked.
	//
	// The lock will be held at this point, preferring RLock over Lock, if available.
	// Do not lock or unlock the [Binder] within fn. Do not call [Getter.JawsGet].
	// To call the previous handler in the chain, call [Binder.JawsInitialHTMLAttrLocked].
	InitialHTMLAttr(fn InitialHTMLAttrHook[T]) (newbind Binder[T])
}

Binder binds a comparable Go value to JaWS getter, setter, tag and event interfaces.

Binder methods are safe for concurrent use when the locker passed to New is safe for concurrent use.

func New

func New[T comparable](l sync.Locker, p *T) Binder[T]

New returns a Binder with l protecting the value pointed to by p.

If l implements RWLocker, reads use its read lock. Otherwise reads and writes both use l. The pointer p is also exposed as the UI tag.

type ClickedHook added in v0.400.0

type ClickedHook[T comparable] func(bind Binder[T], elem *jaws.Element, click jaws.Click) (err error)

ClickedHook is a function to call when a click event is received.

The Binder locks are not held when the function is called.

type ContextMenuHook added in v0.400.0

type ContextMenuHook[T comparable] func(bind Binder[T], elem *jaws.Element, click jaws.Click) (err error)

ContextMenuHook is a function to call when a context menu event is received.

The Binder locks are not held when the function is called.

type Formatter

type Formatter interface {
	Format(string) string
}

Formatter customizes [Binder.Format] output for a value.

type GetHTMLHook added in v0.400.0

type GetHTMLHook[T comparable] func(bind Binder[T], elem *jaws.Element) (s template.HTML)

GetHTMLHook is a function to call when [HTMLGetter.JawsGetHTML] is called.

The lock will be held before calling the function, preferring RLock over Lock, if available. Do not lock or unlock the Binder in the function. Do not call [Getter.JawsGet] or [HTMLGetter.JawsGetHTML] (either would deadlock or recurse).

Unlike GetHook and SetHook, the bind argument is the current Binder (the one whose hook is being invoked), not the previous one. Read the bound value with bind.JawsGetLocked(elem) to render it; that skips this hook and so does not recurse.

type GetHook added in v0.400.0

type GetHook[T comparable] func(bind Binder[T], elem *jaws.Element) (value T)

GetHook is a function that replaces [Binder.JawsGetLocked].

The lock will be held before calling the function, preferring RLock over Lock, if available. Do not lock or unlock the Binder in the function. Do not call [Getter.JawsGet].

The bind argument is the previous Binder in the chain, and you probably want to call its [Binder.JawsGetLocked] first.

type Getter

type Getter[T comparable] interface {
	JawsGet(elem *jaws.Element) (value T)
}

Getter exposes a value for a jaws.Element.

func MakeGetter

func MakeGetter[T comparable](value any) Getter[T]

MakeGetter returns v as a Getter.

v may be a Getter of the same type or a static value of type T. It panics for any other type.

func StringGetterFunc

func StringGetterFunc(fn func(elem *jaws.Element) (s string), tags ...any) Getter[string]

StringGetterFunc wraps fn as a Getter for string values.

Optional tags are exposed through tag.TagGetter.

type HTMLGetter

type HTMLGetter interface {
	JawsGetHTML(elem *jaws.Element) template.HTML
}

HTMLGetter is the primary way to deliver generated HTML content to dynamic HTML nodes.

func HTMLGetterFunc

func HTMLGetterFunc(fn func(elem *jaws.Element) (tmpl template.HTML), tags ...any) HTMLGetter

HTMLGetterFunc wraps fn as an HTMLGetter.

Optional tags are exposed through tag.TagGetter.

func MakeHTMLGetter

func MakeHTMLGetter(value any) HTMLGetter

MakeHTMLGetter returns an HTMLGetter for v.

Depending on the type of v, we return:

WARNING: Plain string values are NOT HTML-escaped. This is intentional so that HTML markup can be passed conveniently from Go templates (e.g. `{{$.Span "<i>text</i>"}}`). Never pass untrusted user input as a plain string; use template.HTML to signal that the content is trusted, or wrap user input in a Getter or fmt.Stringer so it will be escaped automatically.

type InitialHTMLAttrHook added in v0.400.0

type InitialHTMLAttrHook[T comparable] func(bind Binder[T], elem *jaws.Element) (s template.HTMLAttr)

InitialHTMLAttrHook is a function to call when an Element is initially rendered.

The lock will be held at this point, preferring RLock over Lock, if available. Do not lock or unlock the Binder within fn. Do not call [Getter.JawsGet].

type RWLocker

type RWLocker interface {
	sync.Locker
	RLock()
	RUnlock()
}

RWLocker is the subset of sync.RWMutex used by binders.

func AsRWLocker added in v0.500.0

func AsRWLocker(l sync.Locker) RWLocker

AsRWLocker returns an RWLocker backed by l.

If l already implements RWLocker it is returned unchanged; otherwise its Lock and Unlock are used for both read and write locking.

type SetHook added in v0.400.0

type SetHook[T comparable] func(bind Binder[T], elem *jaws.Element, value T) (err error)

SetHook is a function that replaces [Binder.JawsSetLocked].

The Binder write lock will be held before calling the function. Do not lock or unlock the Binder in the function. Do not call [Binder.JawsSet].

The bind argument is the previous Binder in the chain, and you probably want to call its [Binder.JawsSetLocked] first.

type Setter

type Setter[T comparable] interface {
	Getter[T]
	// JawsSet may return [jaws.ErrValueUnchanged] to indicate value was already set.
	JawsSet(elem *jaws.Element, value T) (err error)
}

Setter exposes and updates a value for a jaws.Element.

func MakeSetter

func MakeSetter[T comparable](value any) Setter[T]

MakeSetter returns v as a Setter.

v may be a Setter of the same type, a Getter of the same type or a static value of type T. Getter and static adapters are read-only and return ErrValueNotSettable from [Setter.JawsSet]. MakeSetter panics for any other type.

func MakeSetterFloat64

func MakeSetterFloat64(value any) (s Setter[float64])

MakeSetterFloat64 returns v as a Setter for float64 values.

v may be a float64 setter/getter/static value, or a setter/getter/static value of another supported numeric type (the predeclared signed and unsigned integer types and float32), which is bridged to float64 by ordinary Go conversion. That bridge can lose precision: int64/uint64 magnitudes beyond 2^53 are not exactly representable as float64.

Only the predeclared numeric types are matched, by their exact type. Named (defined) numeric types such as "type Celsius float64" are NOT matched: neither the value itself nor a Setter[Celsius]/Getter[Celsius] over it is accepted (Setter[Celsius] is not a Setter[float64]), and passing one causes a panic. To bind such a value, expose it as a Setter[float64] / Getter[float64] (or a plain float64) — for example with a small adapter that converts to and from float64. Getter and static adapters are read-only and return ErrValueNotSettable from [Setter.JawsSet]. MakeSetterFloat64 panics for unsupported types.

type SuccessHook added in v0.400.0

type SuccessHook func(elem *jaws.Element) (err error)

SuccessHook is a function to call when [Setter.JawsSet] returns with no error.

The Binder locks are not held when the function is called.

Success hooks in a Binder chain are called in reverse registration order. If one of them returns an error, that error is returned from [Setter.JawsSet] and no more success hooks are called.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL