Documentation ¶
Overview ¶
Package vugu provides core functionality including vugu->go codegen and in-browser DOM syncing running in WebAssembly. See http://www.vugu.org/
Since Vugu projects can have both client-side (running in WebAssembly) as well as server-side functionality many of the items in this package are available in both environments. Some however are either only available or only generally useful in one environment.
Common functionality includes the ComponentType interface, and ComponentInst struct corresponding to an instantiated componnet. VGNode and related structs are used to represent a virtual Document Object Model. It is based on golang.org/x/net/html but with additional fields needed for Vugu. Data hashing is performed by ComputeHash() and can be customized by implementing the DataHasher interface.
Client-side code uses JSEnv to maintain a render loop and regenerate virtual DOM and efficiently synchronize it with the browser as needed. DOMEvent is a wrapper around events from the browser and EventEnv is used to synchronize data access when writing event handler code that spawns goroutines. Where appropriate, server-side stubs are available so components can be compiled for both client (WebAssembly) and server (server-side rendering and testing).
Server-side code can use ParserGo and ParserGoPkg to parse .vugu files and code generate a corresponding .go file. StaticHTMLEnv can be used to generate static HTML, similar to the output of JSEnv but can be run on the server. Supported features are approximately the same minus event handling, unapplicable to static output.
Index ¶
- Constants
- Variables
- func ComputeHash(i interface{}) uint64
- func RegisterComponentType(tagName string, ct ComponentType)
- type ComponentInst
- type ComponentType
- type ComponentTypeMap
- type DOMEvent
- type DOMEventHandler
- type DataHasher
- type Env
- type EventEnv
- type JSEnv
- type ParserGo
- type ParserGoPkg
- type ParserGoPkgOpts
- type Props
- type StaticHTMLEnv
- type VGAtom
- type VGAttribute
- type VGNode
- type VGNodeType
Examples ¶
Constants ¶
const ( ErrorNode = VGNodeType(html.ErrorNode) TextNode = VGNodeType(html.TextNode) DocumentNode = VGNodeType(html.DocumentNode) ElementNode = VGNodeType(html.ElementNode) CommentNode = VGNodeType(html.CommentNode) DoctypeNode = VGNodeType(html.DoctypeNode) )
Available VGNodeTypes.
Variables ¶
var DOMEventStub = &DOMEvent{}
DOMEventStub is used as a value to mean "replace this with the actual event that came in". In .vugu files, "event" points to this.
Functions ¶
func ComputeHash ¶
func ComputeHash(i interface{}) uint64
ComputeHash performs data hashing. It walks your data structure and hashes the information as it goes. It uses xxhash internally and returns a uint64. It is intended to be both fast and have good hash distribution to avoid collision-related bugs. Maps are sorted by key and then both keys and values are hashed. Nil values are skipped. Behavior is undefined for circular references via interface or pointer. Will call DataHash() method if present (see DataHasher) on a type. Otherwise will walk the data and find primitive values and hash them byte for byte. No guarantee is made about the exact hash algorithm used or how type information is or is not hashed - only that the same data structure should consistently hash to the same value and changing any value in the data tree should change the hash.
Example ¶
type D struct { A string } data1 := &D{A: "test1"} data2 := &D{A: "test2"} fmt.Println(ComputeHash(data1) == ComputeHash(data1)) fmt.Println(ComputeHash(data1) == ComputeHash(data2))
Output: true false
func RegisterComponentType ¶
func RegisterComponentType(tagName string, ct ComponentType)
RegisterComponentType can be called during init to register a component and make it available by default to the rest of the application. A program may retrieved these by calling RegisteredComponentTypes() or it may choose to form its own set. RegisterComponentType() just makes it available in case that's useful. It is good practice for components to register themselves in an init function.
Types ¶
type ComponentInst ¶
type ComponentInst struct { Type ComponentType // type of component Data interface{} // data as returned by NewData }
ComponentInst corresponds to a ComponentType that has been instantiated.
func New ¶
func New(ct ComponentType, props Props) (*ComponentInst, error)
New instantiates a component based on its ComponentType and a set of Props. It essentially just calls NewData and returns a ComponentInst.
type ComponentType ¶
type ComponentType interface { BuildVDOM(data interface{}) (vdom *VGNode, css *VGNode, reterr error) // based on the given data, build the VGNode tree NewData(props Props) (interface{}, error) // initial data when component is instanciated }
ComponentType is implemented by any type that wants to be a component. The BuildVDOM method is called to generate the virtual DOM for a component; and this method is usually code generated (by ParserGo) from a .vugu file. NewData provides for specific behavior when a component is initialized.
type ComponentTypeMap ¶
type ComponentTypeMap map[string]ComponentType
ComponentTypeMap is a map of the component tag name to a ComponentType.
func RegisteredComponentTypes ¶
func RegisteredComponentTypes() ComponentTypeMap
RegisteredComponentTypes returns a copy of the map of registered component types.
type DOMEvent ¶
type DOMEvent struct { }
DOMEvent is an event originated in the browser. It wraps the JS event that comes in. It is meant to be used in WebAssembly but some methods exist here so code can compile server-side as well (although DOMEvents should not ever be generated server-side).
func (*DOMEvent) EventEnv ¶
EventEnv returns the EventEnv for the current environment and allows locking and unlocking around modifications. See EventEnv struct. Non-wasm implementation returns nil.
func (*DOMEvent) JSEvent ¶
func (e *DOMEvent) JSEvent() interface{}
JSEvent this returns a js.Value in wasm that corresponds to the event object. Non-wasm implementation returns nil.
func (*DOMEvent) JSEventThis ¶
func (e *DOMEvent) JSEventThis() interface{}
JSEventThis returns a js.Value in wasm that corresponds to the "this" variable from the event callback. It is the DOM element the event was attached to. Non-wasm implementation returns nil.
func (*DOMEvent) PreventDefault ¶
func (e *DOMEvent) PreventDefault()
PreventDefault calls preventDefault() on the JS event object. Non-wasm implementation is nop.
func (*DOMEvent) RequestRender ¶
func (e *DOMEvent) RequestRender()
RequestRender tells the environment it should be re-rendered as soon as possible (as soon as it can obtain a read lock). Non-wasm implementation is nop.
type DOMEventHandler ¶
type DOMEventHandler struct { ReceiverAndMethodHash uint64 // hash value corresponding to the method and receiver, so we get a unique value for each combination of method and receiver Method reflect.Value // method to be called, with receiver baked into it if needed (see reflect/Value.MethodByName) Args []interface{} // arguments to be passed in when calling (special case for eventStub) }
DOMEventHandler is created in BuildVDOM to represent a method call that is performed to handle an event.
type DataHasher ¶
type DataHasher interface {
DataHash() uint64
}
DataHasher can be implemented by types to override the hashing behavior. ComputeHash() will call DataHash() on an instance of a type if the method is present. Useful for providing fast and stable hashing for structures that are large but only require a small amount data to be examined to determine if changed, or are already hashed internally, etc.
type Env ¶
type Env interface { RegisterComponentType(tagName string, ct ComponentType) Render() error }
Env specifies the common methods for environment implementations. See JSEnv and StaticHtmlEnv for implementations.
type EventEnv ¶
type EventEnv interface { Lock() // acquire write lock UnlockOnly() // release write lock UnlockRender() // release write lock and request re-render RLock() // acquire read lock RUnlock() // release read lock }
EventEnv provides locking mechanism to for rendering environment to events so data access and rendering can be synchronized and avoid race conditions.
type JSEnv ¶
type JSEnv struct { MountParent string // query selector DebugWriter io.Writer // write debug information about render details to this Writer if not nil }
JSEnv is responsible for rendering (efficiently synchronizing) HTML in the browser in a WebAssembly application. Browser calls are performed using syscall/js. Various internal hashing and other optimizations are performed to attempt to make rendering as effience as possible. If used outside of a wasm program all methods will panic.
func NewJSEnv ¶
func NewJSEnv(mountParent string, rootInst *ComponentInst, components ComponentTypeMap) *JSEnv
NewJSEnv returns a new instance with the specified mountParent (CSS selector of where in the HTML the ouptut will go), the root component instance, and any other component types available.
func (*JSEnv) EventWait ¶
EventWait blocks until an event occurs and re-rendering is needed. Returns true unless the browser has gone away and the program should exit.
func (*JSEnv) RegisterComponentType ¶
func (e *JSEnv) RegisterComponentType(tagName string, ct ComponentType)
RegisterComponentType assigns a component type to a tag name.
func (*JSEnv) Render ¶
Render is where the magic happens and your root component instance has its virtual DOM rendered and synchronized to the browser DOM. Render attempts to perform as few operations as possible and uses hashing to avoid unnecessary work. Component instances of children of the root component (referenced with HTML tags that have the components tag name), are managed as rendering occurs. Child components are created according to a hash of their properties and are recreated if their position in the DOM changes OR if their properties (HTML attributes on the referencing tag) change. Render is normally called in a loop with EventWait() being used to block until re-rendering is needed.
type ParserGo ¶
type ParserGo struct { PackageName string // name of package to use at top of files ComponentType string // just the struct name, no "*" DataType string // just the struct name, no "*" OutDir string // output dir OutFile string // output file name with ".go" suffix }
ParserGo is a template parser that emits Go source code that will construct the appropriately wired VGNodes.
type ParserGoPkg ¶
type ParserGoPkg struct {
// contains filtered or unexported fields
}
ParserGoPkg knows how to perform source file generation in relation to a package folder. Whereas ParserGo handles converting a single template, ParserGoPkg is a higher level interface and provides the functionality of the vugugen command line tool. It will scan a package folder for .vugu files and convert them to .go, with the appropriate defaults and logic.
func NewParserGoPkg ¶
func NewParserGoPkg(pkgPath string, opts *ParserGoPkgOpts) *ParserGoPkg
NewParserGoPkg returns a new ParserGoPkg with the specified options or default if nil. The pkgPath is required and must be an absolute path.
func (*ParserGoPkg) Run ¶
func (p *ParserGoPkg) Run() error
Run does the work and generates the appropriate .go files from .vugu files. It will also create a go.mod file if not present and not SkipGoMod. Same for main.go and SkipMainGo (will also skip if package already has file with package name something other than main). Per-file code generation is performed by ParserGo.
type ParserGoPkgOpts ¶
type ParserGoPkgOpts struct { SkipRegisterComponentTypes bool // indicates func init() { vugu.RegisterComponentType(...) } code should not be emitted in each file SkipGoMod bool // do not try and create go.mod if it doesn't exist SkipMainGo bool // do not try and create main_wasm.go if it doesn't exist in a main package }
ParserGoPkgOpts is the options for ParserGoPkg.
type Props ¶
type Props map[string]interface{}
Props is a map that corresponds to property names and values. The name can correspond to an HTML attribute, or a property being passed in during component instantiation, depending on the context.
func (Props) Merge ¶
Merge will copy everything from p2 into p and return p for ease of use. Does not copy p.
func (Props) OrderedKeys ¶
OrderedKeys returns the keys sorted alphabetically.
type StaticHTMLEnv ¶
type StaticHTMLEnv struct {
// contains filtered or unexported fields
}
StaticHTMLEnv is an environment that renders to static HTML. Can be used to implement "server side rendering" as well as during testing.
func NewStaticHTMLEnv ¶
func NewStaticHTMLEnv(out io.Writer, rootInst *ComponentInst, components ComponentTypeMap) *StaticHTMLEnv
NewStaticHTMLEnv returns a new instance of StaticHTMLEnv initialized properly. The out and rootInst are required, components may be nil.
func (*StaticHTMLEnv) RegisterComponentType ¶
func (e *StaticHTMLEnv) RegisterComponentType(tagName string, ct ComponentType)
RegisterComponentType sets a component type with its tag name.
func (*StaticHTMLEnv) Render ¶
func (e *StaticHTMLEnv) Render() error
Render performs redering to static HTML. The logic used is similar to JSEnv.Render however it will discard DOM events and is less careful about managing component lifecycle: components are simply created when needed and discarded after.
type VGAtom ¶
type VGAtom uint32
VGAtom is an integer corresponding to golang.org/x/net/html/atom.Atom. Note that this may be removed for simplicity and to remove the dependency on the package above. Suggest you don't use it.
type VGAttribute ¶
type VGAttribute struct {
Namespace, Key, Val string
}
VGAttribute is the attribute on an HTML tag.
type VGNode ¶
type VGNode struct {
Parent, FirstChild, LastChild, PrevSibling, NextSibling *VGNode
Type VGNodeType
DataAtom VGAtom
Data string
Namespace string
Attr []VGAttribute
Props Props // dynamic attributes, used as input for components or converted to attributes for regular HTML elements
InnerHTML string // indicates that children should be ignored and this raw HTML is the children of this tag
DOMEventHandlers map[string]DOMEventHandler // describes invocations when DOM events happen
// contains filtered or unexported fields
}
VGNode represents a node from our virtual DOM with the dynamic parts wired up into functions.
func (*VGNode) AppendChild ¶
AppendChild adds a node c as a child of n.
It will panic if c already has a parent or siblings.
func (*VGNode) InsertBefore ¶
InsertBefore inserts newChild as a child of n, immediately before oldChild in the sequence of n's children. oldChild may be nil, in which case newChild is appended to the end of n's children.
It will panic if newChild already has a parent or siblings.
func (*VGNode) RemoveChild ¶
RemoveChild removes a node c that is a child of n. Afterwards, c will have no parent and no siblings.
It will panic if c's parent is not n.
func (*VGNode) SetDOMEventHandler ¶
func (n *VGNode) SetDOMEventHandler(name string, h DOMEventHandler)
SetDOMEventHandler will assign a named event to DOMEventHandlers (will allocate the map if nil). Used during VDOM construction and during render to determine browser events to hook up.
func (*VGNode) Walk ¶
Walk will walk the tree under a VGNode using the specified callback function. If the function provided returns a non-nil error then walking will be stopped and this error will be returned. Only FirstChild and NextSibling are used while walking and so with well-formed documents should not loop. (But loops created manually by modifying FirstChild or NextSibling pointers could cause this function to recurse indefinitely.) Note that f may modify nodes as it visits them with predictable results as long as it does not modify elements higher on the tree (up, toward the parent); it is safe to modify self and children.
type VGNodeType ¶
type VGNodeType uint32
VGNodeType is one of the valid node types (error, text, docuemnt, element, comment, doctype). Note that only text, element and comment are currently used.
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
cmd
|
|
vugugen
vugugen is a command line tool to convert .vugu files into Go source code.
|
vugugen is a command line tool to convert .vugu files into Go source code. |
Package distutil has some useful functions for building your Vugu application's distribution Rather than introducing third party build tools.
|
Package distutil has some useful functions for building your Vugu application's distribution Rather than introducing third party build tools. |
examples
|
|
fetch-and-display
Module
|
|
full-test-data
|
|
test1
Module
|
|
test2
Module
|
|
test3
Module
|
|
internal
|
|
htmlx
Package htmlx is a fork of https://github.com/golang/net/html.
|
Package htmlx is a fork of https://github.com/golang/net/html. |
htmlx/atom
Package atom provides integer codes (also known as atoms) for a fixed set of frequently occurring HTML strings: tag names and attribute keys such as "p" and "id".
|
Package atom provides integer codes (also known as atoms) for a fixed set of frequently occurring HTML strings: tag names and attribute keys such as "p" and "id". |
htmlx/charset
Package charset provides common text encodings for HTML documents.
|
Package charset provides common text encodings for HTML documents. |
Package js is a drop-in replacement for syscall/js that provides identical behavior in a WebAssembly environment, and useful non-functional behavior outside of WebAssembly.
|
Package js is a drop-in replacement for syscall/js that provides identical behavior in a WebAssembly environment, and useful non-functional behavior outside of WebAssembly. |
magefiles
module
|
|
Package simplehttp provides an http.Handler that makes it easy to serve Vugu applications.
|
Package simplehttp provides an http.Handler that makes it easy to serve Vugu applications. |
Package vugufmt provides gofmt-like functionality for vugu files.
|
Package vugufmt provides gofmt-like functionality for vugu files. |
wasm-test-suite
|
|
test-001-simple
Module
|
|
test-002-click
Module
|
|
test-003-prop
Module
|
|
test-004-component
Module
|
|
test-005-issue-80
Module
|
|
test-006-issue-81
Module
|
|
test-007-issue-85
Module
|
|
test-008-for-i
Module
|
|
test-008-for-keyvalue
Module
|
|
test-008-for-kv
Module
|
|
test-009-trim-unused
Module
|
|
test-010-listener-readd
Module
|
|
test-011-wire
Module
|
|
test-012-router
Module
|
|
test-013-issue-117
Module
|
|
test-014-attrintf
Module
|
|
test-015-attribute-lister
Module
|
|
test-016-svg
Module
|
|
test-017-nesting
Module
|
|
test-018-comp-events
Module
|
|
test-019-js-create-populate
Module
|
|
test-020-vgform
Module
|
|
test-021-slots
Module
|
|
test-022-event-listener
Module
|
|
test-023-lifecycle-callbacks
Module
|
|
test-024-event-buffer-size
Module
|