-
Notifications
You must be signed in to change notification settings - Fork 1
/
element.go
163 lines (142 loc) · 4.69 KB
/
element.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
package jaws
import (
"bytes"
"fmt"
"html/template"
"io"
"github.com/linkdata/jaws/jid"
"github.com/linkdata/jaws/what"
)
// An Element is an instance of a *Request, an UI object and a Jid.
type Element struct {
ui UI // (read-only) the UI object
jid jid.Jid // (read-only) JaWS ID, unique to this Element within it's Request
*Request // (read-only) the Request the Element belongs to
// internals
updating bool // about to have Update() called
wsQueue []wsMsg // changes queued
handlers []EventHandler // custom event handlers registered, if any
}
func (e *Element) String() string {
return fmt.Sprintf("Element{%T, id=%q, Tags: %v}", e.ui, e.jid, e.Request.TagsOf(e))
}
// Tag adds the given tags to the Element.
func (e *Element) Tag(tags ...interface{}) {
e.Request.Tag(e, tags...)
}
// HasTag returns true if this Element has the given tag.
func (e *Element) HasTag(tag interface{}) bool {
return e.Request.HasTag(e, tag)
}
// Jid returns the JaWS ID for this Element, unique within it's Request.
func (e *Element) Jid() jid.Jid {
return e.jid
}
// Ui returns the UI object.
func (e *Element) Ui() UI {
return e.ui
}
// Render calls Request.JawsRender() for this Element.
func (e *Element) Render(w io.Writer, params []interface{}) {
e.Request.JawsRender(e, w, params)
}
func (e *Element) queue(wht what.What, data string) {
if len(e.wsQueue) < maxWsQueueLengthPerElement {
e.wsQueue = append(e.wsQueue, wsMsg{
Data: data,
Jid: e.jid,
What: wht,
})
} else {
e.Request.cancelFn(ErrWebsocketQueueOverflow)
}
}
// SetAttr queues sending a new attribute value
// to the browser for the Element with the given JaWS ID in this Request.
//
// Call this only during JawsRender() or JawsUpdate() processing.
func (e *Element) SetAttr(attr, val string) {
e.queue(what.SAttr, attr+"\n"+val)
}
// RemoveAttr queues sending a request to remove an attribute
// to the browser for the Element with the given JaWS ID in this Request.
//
// Call this only during JawsRender() or JawsUpdate() processing.
func (e *Element) RemoveAttr(attr string) {
e.queue(what.RAttr, attr)
}
// SetClass a queues sending a class
// to the browser for the Element with the given JaWS ID in this Request.
//
// Call this only during JawsRender() or JawsUpdate() processing.
func (e *Element) SetClass(cls string) {
e.queue(what.SClass, cls)
}
// RemoveClass queues sending a request to remove a class
// to the browser for the Element with the given JaWS ID in this Request.
//
// Call this only during JawsRender() or JawsUpdate() processing.
func (e *Element) RemoveClass(cls string) {
e.queue(what.RClass, cls)
}
// SetInner queues sending a new inner HTML content
// to the browser for the Element.
//
// Call this only during JawsRender() or JawsUpdate() processing.
func (e *Element) SetInner(innerHtml template.HTML) {
e.queue(what.Inner, string(innerHtml))
}
// SetValue queues sending a new current input value in textual form
// to the browser for the Element with the given JaWS ID in this Request.
//
// Call this only during JawsRender() or JawsUpdate() processing.
func (e *Element) SetValue(val string) {
e.queue(what.Value, val)
}
// Replace replaces the elements entire HTML DOM node with new HTML code.
// If the HTML code doesn't seem to contain correct HTML ID, it panics.
//
// Call this only during JawsRender() or JawsUpdate() processing.
func (e *Element) Replace(htmlCode template.HTML) {
var b []byte
b = append(b, "id="...)
b = e.Jid().AppendQuote(b)
if !bytes.Contains([]byte(htmlCode), b) {
panic(fmt.Errorf("jaws: Element.Replace(): expected HTML " + string(b)))
}
e.queue(what.Replace, string(htmlCode))
}
// Append appends a new HTML element as a child to the current one.
//
// Call this only during JawsRender() or JawsUpdate() processing.
func (e *Element) Append(htmlCode template.HTML) {
e.queue(what.Append, string(htmlCode))
}
// Order reorders the HTML elements.
//
// Call this only during JawsRender() or JawsUpdate() processing.
func (e *Element) Order(jidList []jid.Jid) {
if len(jidList) > 0 {
var b []byte
for i, jid := range jidList {
if i > 0 {
b = append(b, ' ')
}
b = jid.Append(b)
}
e.queue(what.Order, string(b))
}
}
// Delete requests that this Element is removed from the Request and it's HTML element from the browser.
//
// Call this only during JawsRender() or JawsUpdate() processing.
func (e *Element) Delete() {
e.queue(what.Delete, "")
}
// Remove requests that the HTML child with the given HTML ID of this Element
// is removed from the Request and it's HTML element from the browser.
//
// Call this only during JawsRender() or JawsUpdate() processing.
func (e *Element) Remove(htmlId string) {
e.queue(what.Remove, htmlId)
}