Documentation
¶
Index ¶
- Constants
- Variables
- func IsElement(el any) bool
- func IsNode(node any) bool
- func IsNonNodeElement(el any) bool
- func PreventDefaultRemove(tag Adder)
- func Render(ctx context.Context)
- func RenderComponent(ctx context.Context, comp Componenter)
- func StopPropagationRemove(tag Adder)
- type Adder
- type Attribute
- type AttributePluginer
- type Attributer
- type Attrs
- type Class
- type ClassBool
- type ClassList
- type ClassListOff
- type ClassOff
- type Component
- type ComponentMountable
- type Componenter
- type CtxKey
- type DOM
- type Diff
- type DiffType
- type Differ
- type ElementGroup
- type Event
- type EventBinding
- type EventHandler
- type File
- type HTML
- type MessageWS
- type Mounter
- type NodeGroup
- type Page
- func (p *Page) Close(ctx context.Context)
- func (p *Page) GetBrowserNodeByID(id string) *Tag
- func (p *Page) GetNodes() *NodeGroup
- func (p *Page) GetSessionID() string
- func (p *Page) IsConnected() bool
- func (p *Page) RenderWS(ctx context.Context) ([]Diff, error)
- func (p *Page) ServeHTTP(w http.ResponseWriter, r *http.Request)
- func (p *Page) ServeWS(ctx context.Context, sessID string, send chan<- MessageWS, ...) error
- func (p *Page) SetLogger(logger zerolog.Logger)
- type PageServer
- type PageSession
- type PageSessionStore
- type PipeAttributerHandler
- type PipeNodeHandler
- type PipeNodegroupHandler
- type PipeTagHandler
- type PipeTaggerHandler
- type Pipeline
- type PipelineProcessor
- func NewPipelineProcessor(key string) *PipelineProcessor
- func PipelineProcessorAttributePluginMount(page *Page) *PipelineProcessor
- func PipelineProcessorAttributePluginMountSSR(page *Page) *PipelineProcessor
- func PipelineProcessorConvertToString() *PipelineProcessor
- func PipelineProcessorEventBindingCache(cache *hashmap.HashMap) *PipelineProcessor
- func PipelineProcessorMount() *PipelineProcessor
- func PipelineProcessorRenderer(renderer *Renderer) *PipelineProcessor
- func PipelineProcessorStripHLiveAttrs() *PipelineProcessor
- func PipelineProcessorUnmount(page *Page) *PipelineProcessor
- type PreventDefaultAttribute
- type Renderer
- type StopPropagationAttribute
- type Style
- type Tag
- func (t *Tag) Add(element ...interface{})
- func (t *Tag) AddAttributes(attrs ...interface{})
- func (t *Tag) GetAttribute(name string) Attributer
- func (t *Tag) GetAttributeValue(name string) string
- func (t *Tag) GetAttributes() []Attributer
- func (t *Tag) GetName() string
- func (t *Tag) GetNodes() *NodeGroup
- func (t *Tag) IsNil() bool
- func (t *Tag) IsVoid() bool
- func (t *Tag) RemoveAttributes(names ...string)
- func (t *Tag) SetName(name string)
- func (t *Tag) SetVoid(void bool)
- type Tagger
- type Teardowner
- type UniqueAdder
- type UniqueTagger
- type Unmounter
Constants ¶
const ( PipelineProcessorKeyStripHLiveAttrs = "hlive_strip_hlive_attr" PipelineProcessorKeyRenderer = "hlive_renderer" PipelineProcessorKeyEventBindingCache = "hlive_eb" PipelineProcessorKeyAttributePluginMount = "hlive_attr_mount" PipelineProcessorKeyMount = "hlive_mount" PipelineProcessorKeyUnmount = "hlive_unmount" )
const ( AttrID = "data-hlive-id" AttrOn = "data-hlive-on" AttrUpload = "data-hlive-upload" )
HLive special attributes
const ( HTML5DocType HTML = "<!doctype html>" WebSocketDisconnectTimeoutDefault = time.Second * 5 PageSessionLimitDefault = 1000 PageSessionGarbageCollectionTick = time.Second )
Defaults
const PreventDefaultAttributeName = "data-hlive-pd"
const StopPropagationAttributeName = "data-hlive-sp"
Variables ¶
var ( ErrRenderElement = errors.New("attempted to render an unrecognised element") ErrAttrValueCount = errors.New("zero or one value allowed only") ErrInvalidNode = errors.New("variable is not a valid node") ErrInvalidElement = errors.New("variable is not a valid element") ErrInvalidAttribute = errors.New("variable is not a valid attribute") ErrRenderCtx = errors.New("render not found in context") ErrRenderCompCtx = errors.New("component render not found in context") )
Public errors
var ErrDOMInvalidated = errors.New("dom invalidated")
var PageJavaScript []byte
var PreventDefaultJavaScript []byte
var StopPropagationJavaScript []byte
Functions ¶
func IsElement ¶
IsElement returns true is the pass value is a valid Element.
An Element is anything that cna be rendered at HTML.
func IsNode ¶
IsNode returns true is the pass value is a valid Node.
A Node is a value that could be rendered as HTML by itself. An int for example can be converted to a string which is valid HTML. An attribute would not be valid and doesn't make sense to cast to a string.
func IsNonNodeElement ¶
func PreventDefaultRemove ¶
func PreventDefaultRemove(tag Adder)
func RenderComponent ¶
func RenderComponent(ctx context.Context, comp Componenter)
RenderComponent will trigger a WebSocket render for the current page from the passed Componenter down only
func StopPropagationRemove ¶
func StopPropagationRemove(tag Adder)
Types ¶
type Adder ¶
type Adder interface {
// Add elements to a Tagger
Add(elements ...interface{})
}
Adder interface for inputting elements to Tagger type values.
type Attribute ¶
Attribute represents an HTML attribute e.g. id="submitBtn"
func NewAttribute ¶
NewAttribute create a new Attribute
func (*Attribute) GetAttribute ¶
type AttributePluginer ¶
type AttributePluginer interface {
Attributer
// Initialize will only be called once per attribute name for diff render
Initialize(page *Page)
// InitializeSSR will only be called once per attribute name for server side render
InitializeSSR(page *Page)
}
type Attributer ¶
type Attributer interface {
GetAttribute() *Attribute
}
func PreventDefault ¶
func PreventDefault() Attributer
func StopPropagation ¶
func StopPropagation() Attributer
type Attrs ¶
type Attrs map[string]interface{}
Attrs is a helper for adding Attributes to nodes You can update an existing Attribute by adding new Attrs, it;s also possible to pass a string by reference. You can remove an Attribute by passing a nil value.
func (Attrs) GetAttributes ¶
func (a Attrs) GetAttributes() []Attributer
type ClassBool ¶
ClassBool a special Attribute for working with CSS classes on nodes using a bool to toggle them on and off. It supports turning them on and off and allowing overriding. Due to how Go maps work the order of the classes in the map is not preserved. All Classes are de-duped, overriding a Class by adding new ClassBool will result in the old Class getting updated. You don't have to use ClassBool to add a class attribute, but it's the recommended way to do it.
type Component ¶
Component is the default implementation of Componenter.
func C ¶
C is a shortcut for NewComponent.
NewComponent is a constructor for Component.
You can add zero or many Attributes and Tags
func NewComponent ¶
NewComponent is a constructor for Component.
You can add zero or many Attributes and Tags.
func (*Component) Add ¶
func (c *Component) Add(elements ...interface{})
Add an element to this Component.
This is an easy way to add anything.
func (*Component) GetEventBinding ¶
func (c *Component) GetEventBinding(id string) *EventBinding
GetEventBinding will return an EventBinding that exists directly on this element, it doesn't check its children. Returns nil is not found.
func (*Component) GetEventBindings ¶
func (c *Component) GetEventBindings() []*EventBinding
GetEventBindings returns all EventBindings for this component, not it's children.
func (*Component) IsAutoRender ¶
IsAutoRender indicates if this component should trigger "Auto Render"
func (*Component) RemoveEventBinding ¶
RemoveEventBinding removes an EventBinding that matches the passed ID.
No error if the passed id doesn't match an EventBinding. It doesn't check its children.
type ComponentMountable ¶
type ComponentMountable struct {
*Component
MountFunc func(ctx context.Context)
UnmountFunc func(ctx context.Context)
// contains filtered or unexported fields
}
func CM ¶
func CM(name string, elements ...interface{}) *ComponentMountable
CM is a shortcut for NewComponentMountable
func NewComponentMountable ¶
func NewComponentMountable(name string, elements ...interface{}) *ComponentMountable
func WM ¶
func WM(tag *Tag, elements ...interface{}) *ComponentMountable
WM is a shortcut for WrapMountable.
func WrapMountable ¶
func WrapMountable(tag *Tag, elements ...interface{}) *ComponentMountable
WrapMountable takes a Tag and creates a Component with it.
func (*ComponentMountable) AddTeardown ¶
func (c *ComponentMountable) AddTeardown(teardown func())
func (*ComponentMountable) Mount ¶
func (c *ComponentMountable) Mount(ctx context.Context)
func (*ComponentMountable) Teardown ¶
func (c *ComponentMountable) Teardown()
func (*ComponentMountable) Unmount ¶
func (c *ComponentMountable) Unmount(ctx context.Context)
type Componenter ¶
type Componenter interface {
UniqueTagger
// GetEventBinding returns a binding by its id
GetEventBinding(id string) *EventBinding
// GetEventBindings returns all event bindings for this tag
GetEventBindings() []*EventBinding
// RemoveEventBinding remove an event binding from this component
RemoveEventBinding(id string)
// IsAutoRender indicates if the page should rerender after an event binding on this tag is called
IsAutoRender() bool
}
Componenter builds on UniqueTagger and adds the ability to handle events.
type DOM ¶
type Diff ¶
type Diff struct {
// Root element, where to start the path search from, "doc" is a special case that means the browser document
Root string
// Position of each child
Path string
Type DiffType
Tag Tagger
Text *string
Attribute *Attribute
HTML *HTML
// Not used for render but for Lifecycle events
Old interface{}
}
Diff Diffs are from old to new
type ElementGroup ¶
type ElementGroup struct {
// contains filtered or unexported fields
}
ElementGroup is a Group of Elements
func E ¶
func E(elements ...any) *ElementGroup
E is shorthand for Elements.
Groups zero or more Element values.
Will panic if something that is not an Element is passed.
func Elements ¶
func Elements(elements ...any) *ElementGroup
Elements groups zero or more Element values.
Will panic if something that is not an Element is passed.
func (*ElementGroup) Add ¶
func (g *ElementGroup) Add(elements ...any)
func (*ElementGroup) Get ¶
func (g *ElementGroup) Get() []any
type Event ¶
type Event struct {
// The binding that was listening for this event
Binding *EventBinding
// If an input has a value set by the browsers on page load, different to the inputs value attribute this type of
// event is sent. This typically happens on page reload after data has been inputted to a field.
IsInitial bool
// The value of the field, if relevant
Value string
// Used when an event source could have multiple values
Values []string
// Selected is true, for the element interacted with, if a radio or checkbox is checked or a select option is selected.
// Most relevant for checkbox as it always has a value, this lets you know if they are currently checked or not.
Selected bool
// TODO: move to nillable value
// Key related values are only used on keyboard related events
Key string
CharCode int
KeyCode int
ShiftKey bool
AltKey bool
CtrlKey bool
// Used for file inputs and uploads
File *File
// Extra, for non-browser related data, for use by plugins
Extra map[string]string
}
type EventBinding ¶
type EventBinding struct {
// Unique ID for this binding
ID string
// Function to call when binding is triggered
Handler EventHandler
// Component we are bound to
Component Componenter
// Call this binding once then discard it
Once bool
// Name of the JavaScript event that will trigger this binding
Name string
}
func NewEventBinding ¶
func NewEventBinding() *EventBinding
func On ¶
func On(name string, handler EventHandler) *EventBinding
func OnOnce ¶
func OnOnce(name string, handler EventHandler) *EventBinding
type EventHandler ¶
type HTML ¶
type HTML string
HTML must always have a single root element, as we count it as 1 node in the tree but the browser will not if you have multiple root elements
type Mounter ¶
type Mounter interface {
UniqueTagger
// Mount is called after a component is mounted
Mount(ctx context.Context)
}
Mounter wants to be notified after it's mounted.
type NodeGroup ¶
type NodeGroup struct {
// contains filtered or unexported fields
}
NodeGroup is a Group of Nodes
func G ¶
G is shorthand for Group.
Group zero or more Nodes together.
Will panic if something that is not a node is passed.
type Page ¶
type Page struct {
// HTML renderer
Renderer *Renderer
// DOM differ
Differ *Differ
// Page rendering pipelines
PipelineDiff *Pipeline
// Page HTML rendering pipeline
PipelineSSR *Pipeline
// Virtual DOM
DOM DOM
// What we think is the browser done is now
DOMBrowser interface{}
//
// Hooks
//
// Before each event
HookBeforeEvent []func(ctx context.Context, e Event) (context.Context, Event)
// After each event
HookAfterEvent []func(ctx context.Context, e Event) (context.Context, Event)
// After each render
HookAfterRender []func(context.Context, []Diff, chan<- MessageWS)
HookClose []func(context.Context, *Page)
// Before we do the initial render and send to the browser
HookBeforeMount []func(context.Context, *Page)
// After we do the initial render and send to the browser
HookMount []func(context.Context, *Page)
// When we close the page
HookUnmount []func(context.Context, *Page)
// contains filtered or unexported fields
}
func (*Page) GetBrowserNodeByID ¶
func (*Page) GetSessionID ¶
func (*Page) IsConnected ¶
type PageServer ¶
type PageServer struct {
Sessions *PageSessionStore
Upgrader websocket.Upgrader
// contains filtered or unexported fields
}
func NewPageServer ¶
func NewPageServer(pf func() *Page) *PageServer
func NewPageServerWithSessionStore ¶
func NewPageServerWithSessionStore(pf func() *Page, sess *PageSessionStore) *PageServer
func (*PageServer) ServeHTTP ¶
func (s *PageServer) ServeHTTP(w http.ResponseWriter, r *http.Request)
type PageSession ¶
type PageSessionStore ¶
type PageSessionStore struct {
DisconnectTimeout time.Duration
SessionLimit int
GarbageCollectionTick time.Duration
// contains filtered or unexported fields
}
func NewPageSessionStore ¶
func NewPageSessionStore() *PageSessionStore
func (*PageSessionStore) Delete ¶
func (pss *PageSessionStore) Delete(id string)
func (*PageSessionStore) GarbageCollection ¶
func (pss *PageSessionStore) GarbageCollection()
func (*PageSessionStore) Get ¶
func (pss *PageSessionStore) Get(id string) *PageSession
func (*PageSessionStore) GetSessionCount ¶
func (pss *PageSessionStore) GetSessionCount() int
type PipeAttributerHandler ¶
type PipeAttributerHandler func(ctx context.Context, w io.Writer, tag Attributer) (Attributer, error)
type PipeNodeHandler ¶
type PipeNodegroupHandler ¶
type PipeTagHandler ¶
type PipeTaggerHandler ¶
type Pipeline ¶
type Pipeline struct {
// contains filtered or unexported fields
}
func NewPipeline ¶
func NewPipeline(pps ...*PipelineProcessor) *Pipeline
func (*Pipeline) Add ¶
func (p *Pipeline) Add(processors ...*PipelineProcessor)
func (*Pipeline) AddAfter ¶
func (p *Pipeline) AddAfter(processorKey string, processors ...*PipelineProcessor)
func (*Pipeline) AddBefore ¶
func (p *Pipeline) AddBefore(processorKey string, processors ...*PipelineProcessor)
type PipelineProcessor ¶
type PipelineProcessor struct {
// Will replace an existing processor with the same key. An empty string won't error.
Key string
Disabled bool
BeforeWalk PipeNodeHandler
OnSimpleNode PipeNodeHandler
BeforeTagger PipeTaggerHandler
BeforeAttribute PipeAttributerHandler
AfterAttribute PipeAttributerHandler
AfterTagger PipeTagHandler
AfterWalk PipeNodegroupHandler
}
func NewPipelineProcessor ¶
func NewPipelineProcessor(key string) *PipelineProcessor
func PipelineProcessorAttributePluginMount ¶
func PipelineProcessorAttributePluginMount(page *Page) *PipelineProcessor
func PipelineProcessorAttributePluginMountSSR ¶
func PipelineProcessorAttributePluginMountSSR(page *Page) *PipelineProcessor
func PipelineProcessorConvertToString ¶
func PipelineProcessorConvertToString() *PipelineProcessor
func PipelineProcessorEventBindingCache ¶
func PipelineProcessorEventBindingCache(cache *hashmap.HashMap) *PipelineProcessor
func PipelineProcessorMount ¶
func PipelineProcessorMount() *PipelineProcessor
func PipelineProcessorRenderer ¶
func PipelineProcessorRenderer(renderer *Renderer) *PipelineProcessor
func PipelineProcessorStripHLiveAttrs ¶
func PipelineProcessorStripHLiveAttrs() *PipelineProcessor
func PipelineProcessorUnmount ¶
func PipelineProcessorUnmount(page *Page) *PipelineProcessor
type PreventDefaultAttribute ¶
type PreventDefaultAttribute struct {
*Attribute
}
func (*PreventDefaultAttribute) Initialize ¶
func (a *PreventDefaultAttribute) Initialize(page *Page)
func (*PreventDefaultAttribute) InitializeSSR ¶
func (a *PreventDefaultAttribute) InitializeSSR(page *Page)
type Renderer ¶
type Renderer struct {
// contains filtered or unexported fields
}
func NewRenderer ¶
func NewRenderer() *Renderer
func (*Renderer) Attribute ¶
func (r *Renderer) Attribute(attrs []Attributer, w io.Writer) error
Attribute renders an Attribute to it's HTML string representation While it's possible to have attributes without values it simplifies things if we always have a value
type StopPropagationAttribute ¶
type StopPropagationAttribute struct {
*Attribute
}
func (*StopPropagationAttribute) Initialize ¶
func (a *StopPropagationAttribute) Initialize(page *Page)
func (*StopPropagationAttribute) InitializeSSR ¶
func (a *StopPropagationAttribute) InitializeSSR(page *Page)
type Style ¶
type Style map[string]interface{}
Style is a special Attribute that allows you to work with ClassBool styles on nodes. It allows you to override All Styles are de-duped, overriding a Style by adding new Style will result in the old Style getting updated. You don't have to use Style to add a style attribute, but it's the recommended way to do it.
type Tag ¶
type Tag struct {
// contains filtered or unexported fields
}
Tag is the default HTML tag implementation.
Use T or NewTag to create a value.
func (*Tag) AddAttributes ¶
func (t *Tag) AddAttributes(attrs ...interface{})
AddAttributes will add zero or more attributes types (Attributer, Attribute, Attrs, Style, ClassBool).
Adding an attribute with the same name will override an existing attribute.
func (*Tag) GetAttribute ¶
func (t *Tag) GetAttribute(name string) Attributer
GetAttribute returns an Attributer value by its name.
This includes attribute values related to Class, and Style. If an Attributer of the passed name has not been set `nil` it's returned.
func (*Tag) GetAttributeValue ¶
GetAttributeValue returns a value for a given Attributer name.
If an attribute has not yet been set, then an empty string is returned.
func (*Tag) GetAttributes ¶
func (t *Tag) GetAttributes() []Attributer
GetAttributes returns a list of Attributer values that this tag has.
Any Class, Style values are returned here as Attribute values.
func (*Tag) GetNodes ¶
GetNodes returns a NodeGroup with any child Nodes that have been added to this Node.
func (*Tag) RemoveAttributes ¶
type Tagger ¶
type Tagger interface {
// GetName returns a tag's name. For example <hr>'s name is hr.
GetName() string
// GetAttributes returns all attributes for this tag.
GetAttributes() []Attributer
// GetNodes returns this tags children nodes, to be rendered inside this tag.
GetNodes() *NodeGroup
// IsVoid indicates if this has a closing tag or not. Void tags don't have a closing tag.
IsVoid() bool
// IsNil returns true if pointer is nil.
//
// It's easy to create something like `var t *Tag` but forget to give it a value.
// This allows us to not have panics in that case.
IsNil() bool
}
Tagger represents a static HTML tag.
type Teardowner ¶
type Teardowner interface {
UniqueTagger
// AddTeardown adds a teardown function
AddTeardown(teardown func())
// Teardown call the set teardown function passed in SetTeardown
Teardown()
}
Teardowner wants to have manual control when it needs to be removed from a Page. If you have a Mounter or Unmounter that will be permanently removed from a Page they must call the passed function to clean up their references.
type UniqueAdder ¶
UniqueAdder is an Adder that can be uniquely identified in a DOM Tree.
type UniqueTagger ¶
UniqueTagger is a Tagger that can be uniquely identified in a DOM Tree.
type Unmounter ¶
type Unmounter interface {
UniqueTagger
// Unmount is called before a component is unmounted
Unmount(ctx context.Context)
}
Unmounter wants to be notified before it's unmounted.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
_example
|
|
|
animation
command
|
|
|
callback
command
|
|
|
click
command
|
|
|
clock
command
|
|
|
file_upload
command
|
|
|
hover
command
|
|
|
initial_sync
command
|
|
|
local_render
command
|
|
|
preempt
command
|
|
|
pubsub
command
|
|
|
session
command
|
|
|
todo
command
|
|
|
url_params
command
|
|
|
_tutorial
|
|
|
helloworld
command
|
|

