rx

package module
v0.0.0-...-cb7dbc6 Latest Latest
Warning

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

Go to latest
Published: Feb 4, 2024 License: BSD-2-Clause Imports: 13 Imported by: 0

Documentation

Overview

package rx is a work in progress to cleanly separate the code in rendering from the domain logic it is meant to be dot-imported.

Index

Constants

This section is empty.

Variables

View Source
var LogLevel slog.LevelVar

Functions

func Actions_

func Actions_(ctx Context) chan Action

func CellHeight_

func CellHeight_(ctx Context) int

func CleanValue

func CleanValue(ctx Context, key ContextKey)

CleanValue deletes all values corresponding for a given key.

func DumpETree

func DumpETree(n *Node)

DumpETree is a debug utility printing all entities in a node subtree as a tree

func FreePool

func FreePool()

FreePool de-allocate all nodes at once.

func Logger_

func Logger_(ctx Context) *slog.Logger

func Point_

func Point_(ctx Context) int

func R1

func R1(ctx Context) string

func R2

func R2(ctx Context) string

func R3

func R3(ctx Context) string

func R4

func R4(ctx Context) string

func S1

func S1(ctx Context, v any)

Continuation outputs

func S2

func S2(ctx Context, v any)

func S3

func S3(ctx Context, v any)

func S4

func S4(ctx Context, v any)

func Value

func Value(ctx Context, key ContextKey) any

Value retrieves the value matching the corresponding key. If no such value exists, nil is returned.

Types

type Action

type Action func(Context) Context

type Attr

type Attr struct{ Name, Value string }

type CallFrame

type CallFrame struct {
	IntentType
	Entity

	Mouse     Coord
	Point     int
	Registers [4]JSValue
	Returns   [4]JSValue
	Modifiers struct {
		CTRL, SHIFT, ALT bool
	}

	Continuation chan CallFrame

	Gen int
}

CallFrame mock implementation for Unix

type Context

type Context struct {
	// contains filtered or unexported fields
}

Context carries a set of values down the rendering tree. This is used by UI elements to pass values between rendering passes. A build context can safely be shared between goroutines, and so can the children. The zero build context is valid, but only marginally useful, as it cannot be used to link nodes to widgets. Do not confuse it with the standard library’s context.Context, which does allow to pass values, but also a lot more.

For a good intruduction and uses, the Dart InheritedWidget class is a good start.

var NoAction Context

NoAction is a marker context, which is going to prevent a render cycle from happening. This is only useful as a performance optimisation for reacting to events, preventing an otherwise useless re-rendering. The engine enforces this by randomly ignoring the optimisation.

func DoNothing

func DoNothing(ctx Context) Context

func WithValue

func WithValue(ctx Context, key ContextKey, value any) Context

WithValue adds a new value in the context, which should be passed down the building stack. Existing values of the same key are hidden, but not overwritten.

Concurrency note

The happens-after relationship could look a bit counter-intuitive; without further synchronization, two goroutines G1 and G2 would be able to write their value, but read the value from the other goroutine. We believe this is an acceptable tradeoff as this is not a common case, and adding synchronization (e.g. through channels) is both trivial, and clearer anyway. We do ensure that the data structure remains valid from concurrent access.

type ContextKey

type ContextKey uint16
const (
	NoKey ContextKey = iota
	ErrorKey
	RootKey
	LastRXKey // use as starting point
)

type Coord

type Coord struct{ X, Y int }

Coordinate of any object in the viewport

As per UI convention, X is left to right, and Y is top to bottom

func Mouse_

func Mouse_(ctx Context) Coord

func Screen_

func Screen_(ctx Context) Coord

type Counter

type Counter Entity

func (*Counter) Inc

func (c *Counter) Inc() Entity

type Engine

type Engine struct {
	Actions chan Action
	XAS     chan XAS

	Root       Widget
	Screen     Coord
	CellHeight int
	// derived from jsWorld
	// @see rx-browser/main_js.go
	CallFrame
	// contains filtered or unexported fields
}

func New

func New(root Widget) (*Engine, func())

New initializes a rendering engine, rooted at root. The second value is a start function, to execute when rendering the engine:

ngx, start := rx.New()
// finish initialization with ngx
start()

func (*Engine) ReactToIntent

func (ng *Engine) ReactToIntent(cf CallFrame)

func (*Engine) ReleaseXAS

func (ng *Engine) ReleaseXAS(buf XAS)

ReleaseXAS is used by the main routine to prevent too much allocations

type Entity

type Entity = uint32

func Entity_

func Entity_(ctx Context) Entity

type IntentType

type IntentType int
const (
	NoIntent IntentType = iota
	Click
	DoubleClick
	DragStart
	DragOver
	DragEnd
	Drop
	EscPress
	Scroll
	Filter
	Change
	Blur
	ChangeView
	CellIDChange
	ShowDebugMenu
	CellSizeChange
	Seppuku // must be last, used to size intentHandler

)

func (IntentType) String

func (i IntentType) String() string

type JSValue

type JSValue interface {
	Bool() bool
	Call(m string, args ...any) JSValue
	Delete(p string)
	Equal(w JSValue) bool
	Float() float64
	Get(p string) JSValue
	Index(i int) JSValue
	InstanceOf(t JSValue) bool
	Int() int
	Invoke(args ...any) JSValue
	IsNaN() bool
	IsNull() bool
	IsUndefined() bool
	Length() int
	New(args ...any) JSValue
	Set(p string, x any)
	SetIndex(i int, x any)
	String() string
	Truthy() bool
	Type() Type
}

from syscall/js.Value TODO(rdo) make this available for unit testing

func Pipe

func Pipe() (JSValue, io.WriteCloser)

func ValueOf

func ValueOf(any) JSValue

type Modifiers

type Modifiers struct{ CTRL, SHIFT, ALT bool }

func Modifers_

func Modifers_(ctx Context) Modifiers

type Node

type Node struct {
	Entity   // simple reference
	TagName  string
	Classes  string
	Text     string
	Focused  bool
	Children []*Node
	Attrs    []Attr // for arbitrary HTML elements
	// contains filtered or unexported fields
}

func BuildWidgets

func BuildWidgets(ctx Context, ws []Widget) []*Node

BuildWidgets creates a slice of nodes by rendering each widget. It takes care of ignoring nil values.

func Get

func Get(tpl string) *Node

Get parses the Get text in tpl, and returns a node matching it. This is a short hand for the GetNode, Node.AddAttr, … constructors, optimized for easy definition. The node returned can be further modified.

When used in the short form (defining a single element), the element need not be closed:

Get(`<div class="flex">`)

Get can also create a full tree:

Get(`<div class="flex"><button>Click me</button></div>`)

Get panics if the template is not valid, and should not be used for untrusted inputs. Get uses a caching mechanism to prevent unecessary parsing, so it works best with static strings.

func GetNode

func GetNode(tagname string) *Node

GetNode returns a node from the pool, minimizing allocations. The pool is re-initialized as a whole during each cycle.

func Nothing

func Nothing(ws ...*Node) *Node

Nothing returns a node that does not appear in the DOM. This is useful in conditionals, making branches regular, e.g.:

  x := Nothing()
  if val > threshold {
		x = alert()
  }

During the rendering phase, Nothing is optimized away; which means that:

  1. Terminal nodes will simply not exist
  2. Children of Nothing nodes will become children of the parent of the Nothing node.

func ReuseFrom

func ReuseFrom(ctx Context, nt Entity) *Node

CopyFrom creates a node that will be copied from its previous value in the DOM.

func (*Node) AddAttr

func (n *Node) AddAttr(kv ...string) *Node

func (*Node) AddBoolAttr

func (n *Node) AddBoolAttr(key string, val bool) *Node

Can be used for attributes such as checkbox "checked", button "disabled" Example: GetNode("button").AddBoolAttr("disabled", isDisabled)

func (*Node) AddChildren

func (n *Node) AddChildren(cs ...*Node) *Node

func (*Node) AddClasses

func (n *Node) AddClasses(cls ...string) *Node

AddClasses to a node. If the classes already exists, they are not modified. Empty classes are simply ignored.

Example:

GetNode("td").SetClass("table-cell"); td().AddClass("bg-blue")

func (*Node) AddRole

func (n *Node) AddRole(role string) *Node

Set ARIA role, using the "role" property Useful for reliable tests

func (*Node) Build

func (n *Node) Build(_ Context) *Node

Build bottoms-out the rendering tree: a node is a widget that is self

func (*Node) Focus

func (n *Node) Focus(ctx Context) *Node

func (*Node) GiveKey

func (n *Node) GiveKey(ctx Context) *Node

func (*Node) IsNothing

func (n *Node) IsNothing() bool

func (*Node) OnIntent

func (n *Node) OnIntent(evt IntentType, h Action) *Node

func (*Node) PrintEntityTree

func (n *Node) PrintEntityTree() string

PrintEntityTree for debugging Running on the root node should show all entities

func (*Node) PrintInline

func (n *Node) PrintInline() string

func (*Node) SetText

func (n *Node) SetText(text string) *Node

func (*Node) ToHTML

func (n *Node) ToHTML() string

ToHTML creates a textual representation of the node tree. This is useful for server-side rendering. As such, there is no way to attach a callback to an entity.

type OpType

type OpType = byte

using an alias let's us run go generate but do not alter existing code

const (
	OpTerm OpType = iota
	OpCreateElement
	OpSetClass
	OpSetID
	OpSetAttr
	OpAddText
	OpReuse
	OpReID
	OpNext
)

type TokenType

type TokenType uint32

A TokenType is the type of a Token.

func (TokenType) String

func (t TokenType) String() string

String returns a string representation of the TokenType.

type Type

type Type int

type Widget

type Widget interface{ Build(Context) *Node }

type WidgetFunc

type WidgetFunc func(Context) *Node

WidgetFunc represents the simples form of a widget, without state, nor handlers.

func (WidgetFunc) Build

func (f WidgetFunc) Build(ctx Context) *Node

type XAS

type XAS []byte

func (XAS) AddInstr

func (vm XAS) AddInstr(code byte, val ...string) XAS

Jump to

Keyboard shortcuts

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