-
Notifications
You must be signed in to change notification settings - Fork 327
/
element.go
109 lines (96 loc) · 3.41 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
// Copyright (C) 2017 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package dom
import (
"fmt"
"math"
"github.com/gopherjs/gopherjs/js"
)
// Element is represents a DOM element type.
type Element struct {
node
text Text
Width int `js:"width"`
Height int `js:"height"`
OffsetLeft int `js:"offsetLeft"`
OffsetTop int `js:"offsetTop"`
WidthV interface{} `js:"width"`
HeightV interface{} `js:"height"`
Style *CSSStyleDeclaration `js:"style"`
}
func el(o *js.Object) *Element { return &Element{node: node{o}} }
func newEl(name string) *Element { return Doc().createElement(name) }
// ElementProvider is the interface implemented by types that are represented
// by a DOM element.
type ElementProvider interface {
// Element returns the DOM element that represents the type.
Element() *Element
}
// Append adds v to the end of element's children.
// If v is a node then it is simply appended, otherwise the value will be
// converted to a string and appended as a text node.
func (e *Element) Append(v interface{}) Node {
var n Node
switch v := v.(type) {
case Node:
n = v
case ElementProvider:
n = v.Element()
default:
t := Doc().createTextNode(fmt.Sprintf("%v", v))
if e.text.Object == nil {
e.text = t
}
n = t
}
e.AppendNode(n)
return n
}
// Text returns the child text node for the element, creating it if it
// doesn't already exist.
func (e *Element) Text() Text {
if e.text.Object == nil {
e.Append("") // assigns to e.text
}
return e.text
}
// VisibleRect returns the visible region of the element in the viewport.
func (e *Element) VisibleRect() *Rect {
rect := e.Call("getBoundingClientRect")
l := math.Max(-rect.Get("left").Float(), 0)
t := math.Max(-rect.Get("top").Float(), 0)
r := l + math.Min(rect.Get("right").Float(), float64(Win.InnerWidth))
b := t + math.Min(rect.Get("bottom").Float(), float64(Win.InnerHeight))
return NewRect(l, t, r, b)
}
// OnClick registers a click handler for the element.
func (e *Element) OnClick(cb func(MouseEvent)) Unsubscribe {
e.Call("addEventListener", "click", cb)
return func() { e.Call("removeEventListener", "click", cb) }
}
// OnMouseMove registers a mouse-move handler for the element.
func (e *Element) OnMouseMove(cb func(MouseEvent)) Unsubscribe {
e.Call("addEventListener", "mousemove", cb)
return func() { e.Call("removeEventListener", "mousemove", cb) }
}
// OnMouseDown registers a mouse-down handler for the element.
func (e *Element) OnMouseDown(cb func(MouseEvent)) Unsubscribe {
e.Call("addEventListener", "mousedown", cb)
return func() { e.Call("removeEventListener", "mousedown", cb) }
}
// OnMouseUp registers a mouse-up handler for the element.
func (e *Element) OnMouseUp(cb func(MouseEvent)) Unsubscribe {
e.Call("addEventListener", "mouseup", cb)
return func() { e.Call("removeEventListener", "mouseup", cb) }
}