-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmodule.go
97 lines (80 loc) · 2.05 KB
/
module.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
//go:build js && wasm
package client
import (
"errors"
"fmt"
"io"
"net/http"
"net/url"
"os"
"gopkg.in/yaml.v3"
"honnef.co/go/js/dom/v2"
)
// Module bridges the gap between WASM modules and looking glass.
type Module struct {
name string
root dom.Element
}
// NewModule returns a module.
func NewModule() (*Module, error) {
name := os.Args[0]
root := dom.GetWindow().Document().QuerySelector("#" + name + ".module")
if root == nil {
return nil, fmt.Errorf("module %q not found", name)
}
return &Module{
name: name,
root: root,
}, nil
}
// Name returns the module name.
func (m *Module) Name() string {
return m.name
}
// ParseConfig parse the config for the module into v.
func (m *Module) ParseConfig(v any) error {
if len(os.Args) <= 1 {
return nil
}
return yaml.Unmarshal([]byte(os.Args[1]), v)
}
// Asset returns the path in the configured asset directory.
func (m *Module) Asset(path string) ([]byte, error) {
assetPath := os.Getenv("ASSETS_URL")
u, err := url.Parse(assetPath)
if err != nil {
return nil, fmt.Errorf("parsing assest path %q: %w", assetPath, err)
}
u = u.JoinPath(path)
//nolint:noctx // There is not context here anyway.
resp, err := http.DefaultClient.Get(u.String())
if err != nil {
return nil, fmt.Errorf("getting asset: %w", err)
}
defer func() {
_, _ = io.Copy(io.Discard, resp.Body)
_ = resp.Body.Close()
}()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("unexpected status code: %d", resp.StatusCode)
}
return io.ReadAll(resp.Body)
}
// LoadCSS loads the given styles into the module.
func (m *Module) LoadCSS(styles ...string) error {
for _, style := range styles {
styleElem := dom.GetWindow().Document().CreateElement("style")
styleElem.SetID(m.name)
styleElem.SetTextContent(style)
headElem := dom.GetWindow().Document().QuerySelector("head")
if headElem == nil {
return errors.New("head element not found")
}
headElem.AppendChild(styleElem)
}
return nil
}
// Element returns the modules root DOM element.
func (m *Module) Element() dom.Element {
return m.root
}