Documentation ¶
Overview ¶
This file is responsible for implementing the bulk of the so-called "virtual DOM". In order to keep matching efficient, the VNode struct pretty much follows the implementation of the standard library HTML Node struct exactly.
Index ¶
- func AddEventListener(el js.Value, eventStr string, eFunc func(e *DOMEvent))
- func EscapeString(s string) string
- func GetByQuerySelector(parent js.Value, selector string) js.Value
- func GetElID(nodeTag string) string
- func GetFirstElemWithClass(parent js.Value, class string) js.Value
- func InitWrapper(c Component)
- func RemoveAttribute(el js.Value, key string)
- func RenderHTML(w io.Writer, n *VNode) error
- func ReplaceElement(el js.Value, newEl string)
- func SetAttribute(el js.Value, key, val string)
- func SetInnerHTML(el js.Value, content string)
- func UnescapeString(s string) string
- func UpdateWrapper(c Component)
- type BaseComponent
- type Component
- type ComputedFunc
- type ConditionalRender
- type DOMEvent
- type DOMOperation
- type DOMUpdate
- type DataDep
- type Document
- type Emitter
- type Listener
- type LiveArray
- type LiveBool
- type LiveData
- type LiveInt
- type LiveString
- type LiveStruct
- type LiveStructImpl
- type Mounter
- type Subject
- type Updater
- type VNAttrListener
- type VNCalculatorListener
- type VNConditionalListener
- type VNContentListener
- type VNIteratorListener
- type VNPropListener
- type VNode
- func Comment(commentMsg string) VNode
- func DynamicText(dynamicData interface{}) *VNode
- func Element(tag string, attrs map[string]interface{}, children []*VNode) *VNode
- func RenderFor(iterator LiveArray, r func(index int, val interface{}) *VNode) *VNode
- func RenderIf(condition interface{}, r *VNode) *VNode
- func RenderWrapper(c Component, updateQueue chan DOMUpdate) *VNode
- func StaticText(content string) *VNode
- func (node *VNode) BindEvent(event string, callback func(e *DOMEvent)) *VNode
- func (node *VNode) GetDOMSelector() string
- func (node *VNode) GetOrCreateListener(lID string) Listener
- func (vnode *VNode) Key(keyVal interface{}) *VNode
- func (vnode *VNode) RenderElse(r *VNode) *VNode
- func (vnode *VNode) RenderElseIf(condition interface{}, r *VNode) *VNode
- type VNodeListener
- type VNodeType
- type ZephyrApp
- type ZephyrAttr
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AddEventListener ¶
func EscapeString ¶
EscapeString escapes special characters like "<" to become "<". It escapes only five such characters: <, >, &, ' and ". UnescapeString(EscapeString(s)) == s always holds, but the converse isn't always true.
func InitWrapper ¶
func InitWrapper(c Component)
func RemoveAttribute ¶
func RenderHTML ¶
Renders HTML string from VNode tree. This file is extended directly from the net/http package; its documentation is below. TODO: namespaces
Render renders the parse tree n to the given writer.
Rendering is done on a 'best effort' basis: calling Parse on the output of Render will always result in something similar to the original tree, but it is not necessarily an exact clone unless the original tree was 'well-formed'. 'Well-formed' is not easily specified; the HTML5 specification is complicated.
Calling Parse on arbitrary input typically results in a 'well-formed' parse tree. However, it is possible for Parse to yield a 'badly-formed' parse tree. For example, in a 'well-formed' parse tree, no <a> element is a child of another <a> element: parsing "<a><a>" results in two sibling elements. Similarly, in a 'well-formed' parse tree, no <a> element is a child of a <table> element: parsing "<p><table><a>" results in a <p> with two sibling children; the <a> is reparented to the <table>'s parent. However, calling Parse on "<a><table><a>" does not return an error, but the result has an <a> element with an <a> child, and is therefore not 'well-formed'.
Programmatically constructed trees are typically also 'well-formed', but it is possible to construct a tree that looks innocuous but, when rendered and re-parsed, results in a different tree. A simple example is that a solitary text node would become a tree containing <html>, <head> and <body> elements. Another example is that the programmatic equivalent of "a<head>b</head>c" becomes "<html><head><head/><body>abc</body></html>".
func ReplaceElement ¶
func SetAttribute ¶
func SetInnerHTML ¶
func UnescapeString ¶
UnescapeString unescapes entities like "<" to become "<". It unescapes a larger range of entities than EscapeString escapes. For example, "á" unescapes to "á", as does "á" and "&xE1;". UnescapeString(EscapeString(s)) == s always holds, but the converse isn't always true.
func UpdateWrapper ¶
func UpdateWrapper(c Component)
Types ¶
type BaseComponent ¶
type BaseComponent struct { // Node is a reference to the components // root vNode Node *VNode // contains filtered or unexported fields }
func (*BaseComponent) BindProp ¶
func (c *BaseComponent) BindProp(propName string) interface{}
func (*BaseComponent) Component ¶
func (parent *BaseComponent) Component(c Component) *VNode
ChildComponent calls the render func of a child component
func (*BaseComponent) ComponentWithProps ¶
func (parent *BaseComponent) ComponentWithProps(c Component, props map[string]interface{}) *VNode
ChildComponent calls the render func of a child component
type Component ¶
type Component interface { // Public API Init() Render() *VNode // contains filtered or unexported methods }
type ComputedFunc ¶
type ComputedFunc func() interface{}
This probably will only allow one return value, is there a use case where this doesnt work??
type ConditionalRender ¶
type ConditionalRender struct { Condition interface{} Render *VNode }
type DOMEvent ¶
func (*DOMEvent) PreventDefault ¶
func (e *DOMEvent) PreventDefault()
func (*DOMEvent) StopPropagation ¶
func (e *DOMEvent) StopPropagation()
type DOMOperation ¶
type DOMOperation int
const ( InitialRender DOMOperation = iota Insert Delete UpdateAttr UpdateAttrs SetAttrs RemoveAttr UpdateContent UpdateConditional Replace OverwriteInnerHTML AddEventListeners InsertBefore InsertAfter SwapChildren )
type DOMUpdate ¶
type DOMUpdate struct { ElementID string Data interface{} Operation DOMOperation }
type DataDep ¶
DataDep is the struct that acts as the struct implementation of the Subject.
type Document ¶
func GetDocument ¶
func GetDocument() Document
type Listener ¶
type Listener interface { Update() Identifier() string }
Listener lets implementations call an Update() function, which triggers a DOM update in the reactive data types
type LiveArray ¶
type LiveArray func() *DataDep
LiveArr is the LiveData implementation for the `string` type.
func NewLiveArray ¶
func NewLiveArray(data interface{}) LiveArray
NewLiveString returns a "live" string (reactive type LiveString)
type LiveBool ¶
type LiveBool func() *DataDep
LiveBool is the LiveData implementation for the `string` type.
func NewLiveBool ¶
NewLiveString returns a "live" string (reactive type LiveString)
type LiveData ¶
type LiveData interface { // Set must be implemented on all data types. // Type checking occurs in implementations. Set(interface{}) // Value returns the value stored inside // the reactive data; requires type assert Value(l Listener) interface{} // contains filtered or unexported methods }
LiveData is the interface for using reactive data in components. Implementations are functions that return their resp. types.
type LiveInt ¶
type LiveInt func() *DataDep
LiveInt is the LiveData implementation for the `string` type.
func NewLiveInt ¶
NewLiveString returns a "live" string (reactive type LiveString)
type LiveString ¶
type LiveString func() *DataDep
LiveString is the LiveData implementation for the `string` type.
func NewLiveString ¶
func NewLiveString(data string) LiveString
NewLiveString returns a "live" string (reactive type LiveString)
func (LiveString) Set ¶
func (str LiveString) Set(newData interface{})
Set implements LiveData.Set(interface{}), and is used to set and notify listeners.
func (LiveString) Value ¶
func (str LiveString) Value(l Listener) interface{}
type LiveStruct ¶
type LiveStruct interface { Notify() Register(l Listener) }
type LiveStructImpl ¶
func (LiveStructImpl) Notify ¶
func (s LiveStructImpl) Notify()
func (*LiveStructImpl) Register ¶
func (s *LiveStructImpl) Register(l Listener)
type Subject ¶
type Subject interface { Register(l Listener) Notify() }
Subject lets implementations register listeners and notify their listeners. May want to add removal in the future.
type VNAttrListener ¶
type VNAttrListener struct {
// contains filtered or unexported fields
}
func (VNAttrListener) Identifier ¶
func (l VNAttrListener) Identifier() string
func (VNAttrListener) Update ¶
func (l VNAttrListener) Update()
type VNCalculatorListener ¶
type VNCalculatorListener struct {
// contains filtered or unexported fields
}
func (VNCalculatorListener) Identifier ¶
func (l VNCalculatorListener) Identifier() string
func (VNCalculatorListener) Update ¶
func (l VNCalculatorListener) Update()
type VNConditionalListener ¶
type VNConditionalListener struct {
// contains filtered or unexported fields
}
func (VNConditionalListener) Identifier ¶
func (l VNConditionalListener) Identifier() string
func (VNConditionalListener) Update ¶
func (l VNConditionalListener) Update()
type VNContentListener ¶
type VNContentListener struct {
// contains filtered or unexported fields
}
func (VNContentListener) Identifier ¶
func (l VNContentListener) Identifier() string
func (VNContentListener) Update ¶
func (l VNContentListener) Update()
type VNIteratorListener ¶
type VNIteratorListener struct {
// contains filtered or unexported fields
}
func (VNIteratorListener) Identifier ¶
func (l VNIteratorListener) Identifier() string
func (VNIteratorListener) Update ¶
func (l VNIteratorListener) Update()
type VNPropListener ¶
type VNPropListener struct {
// contains filtered or unexported fields
}
func (VNPropListener) Identifier ¶
func (l VNPropListener) Identifier() string
func (VNPropListener) Update ¶
func (l VNPropListener) Update()
type VNode ¶
type VNode struct { // NodeType is the virtual nodes DOM node type NodeType VNodeType // Tag is the HTML tag - only used for ElementNodes Tag string // DOM_ID is the auto-generated ID that is used to update the node DOM_ID string // Content Content interface{} // Attrs stores the attributes for the ZNode Attrs map[string]interface{} // ParsedAttrs is a map[string]string of ready-to-render // attributes. ParsedAttrs map[string]string RenderChan chan DOMUpdate // Other node refs Parent, FirstChild, LastChild, PrevSibling, NextSibling *VNode // Flags Static bool Component bool // Special fields - may want to interface it up ConditionalRenders []ConditionalRender CurrentCondition int ConditionUpdated bool Keys []interface{} IterRender func(int, interface{}) *VNode // contains filtered or unexported fields }
VNode struct is a simple intermediary between the stdlib html.Node and a Zephyr Component instance. There are also a few extra fields for optimizing patching. Its all on the heap :( I feel like this is bad, but I don't know how else to have ref variables inited in the func. FP maybe? Will investigate.
func RenderWrapper ¶
func StaticText ¶
func (*VNode) GetDOMSelector ¶
func (*VNode) GetOrCreateListener ¶
func (*VNode) RenderElse ¶
func (*VNode) RenderElseIf ¶
type VNodeListener ¶
type VNodeListener struct {
// contains filtered or unexported fields
}
func (VNodeListener) Identifier ¶
func (l VNodeListener) Identifier() string
func (VNodeListener) Update ¶
func (l VNodeListener) Update()
type VNodeType ¶
type VNodeType int
const ( ErrorNode VNodeType = iota TextNode DocumentNode ElementNode CommentNode DoctypeNode // RawNode nodes are not returned by the parser, but can be part of the // Node tree passed to func Render to insert raw HTML (without escaping). // If so, this package makes no guarantee that the rendered HTML is secure // (from e.g. Cross Site Scripting attacks) or well-formed. RawNode // The following are types that don't follow the Go HTML package. They are // used for conditional and iterative rendering ConditionalNode IterativeNode )
(follows html package exactly)
type ZephyrApp ¶
type ZephyrApp struct { // Anchor is a JS Value representing an HTMLElement // object. Anchor js.Value AnchorSelector string // UpdateQueue is a channel that receives a DOMUpdate, // which holds the id of the DOM element, the op, and data UpdateQueue chan DOMUpdate // DOMNodes is a map that stores each element by its // js.Value, which can be retrieved from the DOMElements // map DOMNodes map[string]*VNode // DOMElements holds each element on the pages js.Value // by its id. I think this is faster than calling getElementById // in JS DOMElements map[string]js.Value // ComponentInstance is the instance of the root component RootComponent Component RootNode *VNode // contains filtered or unexported fields }
func CreateApp ¶
CreateApp creates and returns an instance of a ZephyrApp, after doing app-wide initialization (plugins and other stuff maybe)
func (*ZephyrApp) Mount ¶
Mount will mount the ZephyrApp to the given document found by the querySelector. It will also begin the rendering and patching process
func (*ZephyrApp) RenderLoop ¶
func (z *ZephyrApp) RenderLoop()
type ZephyrAttr ¶
type ZephyrAttr struct {
// Namespace is currently unused
Namespace, Key string
// Value should be a regular Go
// data type.
Value interface{}
}
ZephyrAttrs represents the HTML attributes for a VNode in a key/value map. e.g. <input type="text" /> -> "type": "text"