Inital Commit

master
Arsen Musayelyan 2 years ago
commit b666aa9bda

4
.gitignore vendored

@ -0,0 +1,4 @@
bin
**_vgen.go
.vscode
dist/

@ -0,0 +1,43 @@
defaultName = "wasmconv"
defaultTarget = "serve_dev"
def wasmconv_serve_dev():
shell.Exec("go run . -dev")
def wasmconv_dist():
distDir = "dist"
if file.Exists(distDir):
log.Warn("Found existing dist dir, replacing")
shell.Exec("rm -r " + distDir)
log.Info("Finding wasm_exec.js")
GOROOT = shell.Exec("go env GOROOT", output='return')
GOROOT = strings.TrimSpace(GOROOT)
WasmExecPath = GOROOT + "/misc/wasm/wasm_exec.js"
if not file.Exists(WasmExecPath):
log.Fatal("File wasm_exec.js not found")
log.Info("Found wasm_exec.js at " + WasmExecPath)
shell.Exec("mkdir " + distDir)
shell.Exec(fmt.Sprintf("cp -v %s %s/wasm_exec.js", WasmExecPath, distDir))
if shell.LookPath("vugugen") == -1:
log.Info("Command `vugugen` not found, installing")
shell.Exec("github.com/vugu/vugu/cmd/vugugen")
log.Info("Generating code and building wasm")
shell.Exec(fmt.Sprintf("""
go generate .
env GOOS=js GOARCH=wasm go build -o %s/main.wasm
""", distDir))
log.Info("Copying static assets")
shell.Exec("cp -rv assets/* " + distDir)
log.Info("Building server executables")
shell.Exec(fmt.Sprintf("""
env GOOS=linux GOARCH=amd64 go build -o %s/server-linux-x86_64
env GOOS=linux GOARCH=arm64 go build -o %s/server-linux-aarch64
""", distDir, distDir))
log.Info("Dist complete")

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020 vugu-examples
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

@ -0,0 +1,13 @@
# simple
Simple Vugu Example
You can get started with:
```sh
go get -u github.com/vugu/vgrun
vgrun -new-from-example=simple myexample
cd myexample
vgrun devserver.go
```
Then browse to the running server: http://localhost:8844/

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +1,56 @@
<div class="container has-text-centered">
<p class="title">
Wasm Base64 Converter
</p>
<div vg-if="c.TextToB64">
<textarea vg-content='c.PlainText' @keyup="c.ToB64(event)" placeholder="Plaintext" rows="4" cols="50"></textarea>
<div style="margin-bottom: 0.5rem;"></div>
<textarea vg-content='c.B64String' placeholder="Base64" rows="4" cols="50"></textarea>
</div>
<div vg-if="c.B64ToText">
<textarea vg-content='c.B64String' @keyup="c.ToString(event)" placeholder="Base64" rows="4" cols="50"></textarea>
<div style="margin-bottom: 0.5rem;"></div>
<textarea vg-content='c.PlainText' placeholder="Plaintext" rows="4" cols="50"></textarea>
</div>
<a class="button is-light" @click="c.Swap(event)" style="margin-top: 0.5rem;">
<span class="iconify" data-icon="heroicons-solid:refresh"></span>&nbsp;Swap
</a>
</div>
<script type="application/x-go">
import (
"encoding/base64"
)
type Base64 struct {
B64String string `vugu:"data"`
PlainText string `vugu:"data"`
TextToB64 bool `vugu:"data"`
B64ToText bool `vugu:"data"`
}
func (c *Base64) Init() {
c.TextToB64 = true
}
func (c *Base64) ToB64(event vugu.DOMEvent) {
plaintext := event.PropString("target", "value")
b64String := base64.StdEncoding.EncodeToString([]byte(plaintext))
c.PlainText = plaintext
c.B64String = b64String
}
func (c *Base64) ToString(event vugu.DOMEvent) {
b64String := event.PropString("target", "value")
plain, _ := base64.StdEncoding.DecodeString(b64String)
c.PlainText = string(plain)
c.B64String = b64String
}
func (c *Base64) Swap(event vugu.DOMEvent) {
c.TextToB64, c.B64ToText = !c.TextToB64, !c.B64ToText
}
</script>

@ -0,0 +1,55 @@
<div class="container has-text-centered">
<p class="title">
Wasm Base91 Converter
</p>
<div vg-if="c.TextToB91">
<textarea vg-content='c.PlainText' @keyup="c.ToB91(event)" placeholder="Plaintext" rows="4" cols="50"></textarea>
<div style="margin-bottom: 0.5rem;"></div>
<textarea vg-content='c.B91String' placeholder="Base91" rows="4" cols="50"></textarea>
</div>
<div vg-if="c.B91ToText">
<textarea vg-content='c.B91String' @keyup="c.ToString(event)" placeholder="Base91" rows="4" cols="50"></textarea>
<div style="margin-bottom: 0.5rem;"></div>
<textarea vg-content='c.PlainText' placeholder="Plaintext" rows="4" cols="50"></textarea>
</div>
<a class="button is-light" @click="c.Swap(event)" style="margin-top: 0.5rem;">
<span class="iconify" data-icon="heroicons-solid:refresh"></span>&nbsp;Swap
</a>
</div>
<script type="application/x-go">
import (
"ekyu.moe/base91"
)
type Base91 struct {
B91String string `vugu:"data"`
PlainText string `vugu:"data"`
TextToB91 bool `vugu:"data"`
B91ToText bool `vugu:"data"`
}
func (c *Base91) Init() {
c.TextToB91 = true
}
func (c *Base91) ToB91(event vugu.DOMEvent) {
plaintext := event.PropString("target", "value")
b91String := base91.EncodeToString([]byte(plaintext))
c.PlainText = plaintext
c.B91String = b91String
}
func (c *Base91) ToString(event vugu.DOMEvent) {
b91String := event.PropString("target", "value")
plain := base91.DecodeString(b91String)
c.PlainText = string(plain)
c.B91String = b91String
}
func (c *Base91) Swap(event vugu.DOMEvent) {
c.TextToB91, c.B91ToText = !c.TextToB91, !c.B91ToText
}
</script>

@ -0,0 +1,3 @@
package main
//go:generate vugugen -s

@ -0,0 +1,10 @@
module github.com/vugu-examples/simple
go 1.14
require (
ekyu.moe/base91 v0.2.3
github.com/vugu/vgrouter v0.0.0-20200725205318-eeb478c42e5d
github.com/vugu/vjson v0.0.0-20200505061711-f9cbed27d3d9
github.com/vugu/vugu v0.3.3
)

@ -0,0 +1,47 @@
ekyu.moe/base91 v0.2.3 h1:1jCZrrpWjDSMMjjU9LANfQV+n7EHeW0OQ0MO9fpDRHg=
ekyu.moe/base91 v0.2.3/go.mod h1:/qmmaFUj5d0p9xcpj8beZDj33yXrc54eGU+hO/V5vuo=
github.com/cheekybits/is v0.0.0-20150225183255-68e9c0620927/go.mod h1:h/aW8ynjgkuj+NQRlZcDbAbM1ORAbXjXX77sX7T289U=
github.com/chromedp/cdproto v0.0.0-20191009033829-c22f49c9ff0a/go.mod h1:PfAWWKJqjlGFYJEidUM6aVIWPr0EpobeyVWEEmplX7g=
github.com/chromedp/chromedp v0.5.1/go.mod h1:3NMfuKTrKNr8PWEvHzdzZ57PK4jm9zW1C5nKiaWdxcM=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo=
github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM=
github.com/knq/sysutil v0.0.0-20191005231841-15668db23d08/go.mod h1:dFWs1zEqDjFtnBXsd1vPOZaLsESovai349994nHx3e0=
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
github.com/matryer/try v0.0.0-20161228173917-9ac251b645a2/go.mod h1:0KeJpeMD6o+O4hW7qJOT7vyQPKrWmj26uf5wMc/IiIs=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/tdewolff/minify/v2 v2.7.3/go.mod h1:BkDSm8aMMT0ALGmpt7j3Ra7nLUgZL0qhyrAHXwxcy5w=
github.com/tdewolff/parse/v2 v2.4.2/go.mod h1:WzaJpRSbwq++EIQHYIRTpbYKNA3gn9it1Ik++q4zyho=
github.com/tdewolff/test v1.0.6/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE=
github.com/vugu/html v0.0.0-20190914200101-c62dc20b8289 h1:w3hfLuU5tKlcf+hhfmx6UZ5IC1h5M69dL9/6uugfLj8=
github.com/vugu/html v0.0.0-20190914200101-c62dc20b8289/go.mod h1:Y3pLGz8dZUSrB9SARXqFmtW8RNs4HIGAr0+JaWL31Vg=
github.com/vugu/vgrouter v0.0.0-20200725205318-eeb478c42e5d h1:9XOp5CHgCF2xXd7YzcB3Mo2d5jfL+NNVPOnBEc0LGMU=
github.com/vugu/vgrouter v0.0.0-20200725205318-eeb478c42e5d/go.mod h1:C+Uj+375LwtFuL5dNIMLNv/miLesGINzR04oWTyDb40=
github.com/vugu/vjson v0.0.0-20191111004939-722507e863cb/go.mod h1:z7mAqSUjRDMQ09NIO18jG2llXMHLnUHlZ3/8MEMyBPA=
github.com/vugu/vjson v0.0.0-20200505061711-f9cbed27d3d9 h1:0cwYt2uGUAwxOYF6zAkVvCKWt8zOV3JhQqjvwKb6jf0=
github.com/vugu/vjson v0.0.0-20200505061711-f9cbed27d3d9/go.mod h1:z7mAqSUjRDMQ09NIO18jG2llXMHLnUHlZ3/8MEMyBPA=
github.com/vugu/vugu v0.3.0/go.mod h1:RFwOrlJHEkdZvrFcde4d6c0/7SqlRA8E4l2yz1Rs8xM=
github.com/vugu/vugu v0.3.3 h1:s0NxpMfekcg1k7bQ+MgL2J5y7ZhuBTz7gaQrCR4mBS4=
github.com/vugu/vugu v0.3.3/go.mod h1:EuAxLy3HZ+y4vAnohT/peY7IzG3RSdu/QSdyBfdfMgo=
github.com/vugu/xxhash v0.0.0-20191111030615-ed24d0179019 h1:8NGiD5gWbVGObr+lnqcbM2rcOQBO6mr+m19BIblCdho=
github.com/vugu/xxhash v0.0.0-20191111030615-ed24d0179019/go.mod h1:PrBK6+LJXwb+3EnJTHo43Uh4FhjFFwvN4jKk4Zc5zZ8=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/net v0.0.0-20190912160710-24e19bdeb0f2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/sys v0.0.0-20181031143558-9b800f95dbbc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

@ -0,0 +1,55 @@
<div class="container has-text-centered">
<p class="title">
Wasm Hex Converter
</p>
<div vg-if="c.TextToHex">
<textarea vg-content='c.PlainText' @keyup="c.ToHex(event)" placeholder="Plaintext" rows="4" cols="50"></textarea>
<div style="margin-bottom: 0.5rem;"></div>
<textarea vg-content='c.HexString' placeholder="Hex" rows="4" cols="50"></textarea>
</div>
<div vg-if="c.HexToText">
<textarea vg-content='c.HexString' @keyup="c.ToString(event)" placeholder="Hex" rows="4" cols="50"></textarea>
<div style="margin-bottom: 0.5rem;"></div>
<textarea vg-content='c.PlainText' placeholder="Plaintext" rows="4" cols="50"></textarea>
</div>
<a class="button is-light" @click="c.Swap(event)" style="margin-top: 0.5rem;">
<span class="iconify" data-icon="heroicons-solid:refresh"></span>&nbsp;Swap
</a>
</div>
<script type="application/x-go">
import (
"encoding/hex"
)
type Hex struct {
HexString string `vugu:"data"`
PlainText string `vugu:"data"`
TextToHex bool `vugu:"data"`
HexToText bool `vugu:"data"`
}
func (c *Hex) Init() {
c.TextToHex = true
}
func (c *Hex) ToHex(event vugu.DOMEvent) {
plaintext := event.PropString("target", "value")
hexString := hex.EncodeToString([]byte(plaintext))
c.PlainText = plaintext
c.HexString = hexString
}
func (c *Hex) ToString(event vugu.DOMEvent) {
hexString := event.PropString("target", "value")
plain, _ := hex.DecodeString(hexString)
c.PlainText = string(plain)
c.HexString = hexString
}
func (c *Hex) Swap(event vugu.DOMEvent) {
c.TextToHex, c.HexToText = !c.TextToHex, !c.HexToText
}
</script>

@ -0,0 +1,19 @@
<div class="container has-text-centered">
<p class="title">
WasmConv
</p>
<p class="subtitle is-marginless">
This website uses WebAssembly to convert to and from various encodings.
</p>
<p class="subtitle is-marginless">
I wrote this to learn how WebAssembly is implemented and how it functions.
</p>
</div>
<script type="application/x-go">
import (
"runtime"
"time"
)
</script>

@ -0,0 +1,45 @@
// +build wasm
package main
import (
"fmt"
"flag"
"github.com/vugu/vugu"
"github.com/vugu/vugu/domrender"
)
func main() {
mountPoint := flag.String("mount-point", "#vugu_mount_point", "The query selector for the mount point for the root component, if it is not a full HTML component")
flag.Parse()
fmt.Printf("Entering main(), -mount-point=%q\n", *mountPoint)
defer fmt.Printf("Exiting main()\n")
renderer, err := domrender.New(*mountPoint)
if err != nil {
panic(err)
}
defer renderer.Release()
buildEnv, err := vugu.NewBuildEnv(renderer.EventEnv())
if err != nil {
panic(err)
}
rootBuilder := vuguSetup(buildEnv, renderer.EventEnv())
for ok := true; ok; ok = renderer.EventWait() {
buildResults := buildEnv.RunBuild(rootBuilder)
err = renderer.Render(buildResults)
if err != nil {
panic(err)
}
}
}

@ -0,0 +1,96 @@
<html>
<div>
<!-- Start Navbar -->
<nav class="navbar is-dark">
<a @click="c.ShowNav=!c.ShowNav" role="button" class="navbar-burger" aria-label="menu" aria-expanded="false">
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
</a>
<div class="container">
<div id="navMenu" :class='"navbar-menu "+func() string {if c.ShowNav {return "is-active"} else {return ""}}()'>
<div class="navbar-start">
<a @click='c.Navigate("/", nil)' class="navbar-item">
Home
</a>
<div :class='"navbar-item has-dropdown "+func() string {if c.ShowEncodingDropdown {return "is-active"} else {return ""}}()'>
<a class="navbar-link" @click="c.ShowEncodingDropdown=!c.ShowEncodingDropdown">
Encodings
</a>
<div class="navbar-dropdown">
<a @click='c.HideDropdowns(); c.Navigate("/hex", nil)' class="navbar-item">
Hex
</a>
<a @click='c.HideDropdowns(); c.Navigate("/base64", nil)' class="navbar-item">
Base64
</a>
<a @click='c.HideDropdowns(); c.Navigate("/base91", nil)' class="navbar-item">
Base91
</a>
</div>
</div>
</div>
</div>
</div>
</nav>
<!-- End Navbar -->
<!-- Start Body -->
<section class="hero is-dark is-fullheight-with-navbar">
<div class="hero-body">
<!-- Start Render Page-specific Body -->
<vg-comp expr="c.Body"></vg-comp>
<!-- End Render Page-specific Body -->
</div>
</section>
<!-- End Body -->
<!-- Start Footer -->
<section class="hero is-small is-dark">
<div class="hero-body">
<div class="container">
<div class="columns">
<div class="column has-text-left">
Copyright &copy; <span vg-content='time.Now().Format("2006")'></span> Arsen Musayelyan
</div>
<div class="column has-text-centered ">
<p vg-content="runtime.Version()"></p>
</div>
<div class="column has-text-right">
This website was written in
<a class="has-text-primary" href="https://golang.org/">Go</a>
using
<a class="has-text-primary" href="https://webassembly.org/">WebAssembly</a>
and
<a class="has-text-primary" href="https://vugu.org">Vugu</a>
</div>
</div>
</div>
</div>
</section>
<!-- End Footer -->
</div>
<script type="application/x-go">
import (
"runtime"
"time"
"github.com/vugu/vgrouter"
)
type Root struct {
vgrouter.NavigatorRef
Body vugu.Builder
ShowNav bool `vugu:"data"`
ShowEncodingDropdown bool `vugu:"data"`
}
func (c *Root) HideDropdowns() {
c.ShowEncodingDropdown = false
}
</script>

@ -0,0 +1,47 @@
// +build !wasm
package main
import (
"flag"
"log"
"net/http"
"os"
"path/filepath"
"github.com/vugu/vugu/devutil"
)
func main() {
dev := flag.Bool("dev", false, "Enable development features")
dir := flag.String("dir", ".", "Project directory")
httpl := flag.String("addr", ":8844", "Listen for HTTP on this host:port")
flag.Parse()
wd, _ := filepath.Abs(*dir)
os.Chdir(wd)
mux := devutil.NewMux()
mux.Match(devutil.NoFileExt, devutil.DefaultIndex.Replace(
`<!-- styles -->`,
`<link rel="stylesheet" href="/css/bulma.min.css">`,
).Replace(
`<!-- scripts -->`,
`<script src="/js/iconify.min.js"></script>`,
).Replace(
`<title>Vugu App</title>`,
`<title>WasmConv</title>`,
))
mux.Default(devutil.NewFileServer().SetDir("."))
if *dev {
wc := devutil.NewWasmCompiler().SetDir(".")
mux.Exact("/main.wasm", devutil.NewMainWasmHandler(wc))
mux.Exact("/wasm_exec.js", devutil.NewWasmExecJSHandler(wc))
log.Printf("Starting HTTP Server at %q", *httpl)
log.Fatal(http.ListenAndServe(*httpl, mux))
} else {
log.Printf("Starting HTTP Server at %q", *httpl)
log.Fatal(http.ListenAndServe(*httpl, mux))
}
}

@ -0,0 +1,63 @@
package main
import (
"github.com/vugu/vgrouter"
"github.com/vugu/vugu"
)
func vuguSetup(buildEnv *vugu.BuildEnv, eventEnv vugu.EventEnv) vugu.Builder {
// CREATE A NEW ROUTER INSTANCE
router := vgrouter.New(eventEnv)
// MAKE OUR WIRE FUNCTION POPULATE ANYTHING THAT WANTS A "NAVIGATOR".
buildEnv.SetWireFunc(func(b vugu.Builder) {
if c, ok := b.(vgrouter.NavigatorSetter); ok {
c.NavigatorSet(router)
}
})
// CREATE THE ROOT COMPONENT
root := &Root{}
buildEnv.WireComponent(root) // WIRE IT
// ADD ROUTES FOR EACH PAGE. NOTE THAT THESE ARE "EXACT" ROUTES.
// YOU CAN ALSO ADD ROUTES THAT MATCH ANYTHING WITH THE SPECIFIED PREFIX.
router.MustAddRouteExact("/",
vgrouter.RouteHandlerFunc(func(rm *vgrouter.RouteMatch) {
root.Body = &Home{} // A COMPONENT WITH PAGE CONTENTS
}))
router.MustAddRouteExact("/hex",
vgrouter.RouteHandlerFunc(func(rm *vgrouter.RouteMatch) {
root.Body = &Hex{} // A COMPONENT WITH PAGE CONTENTS
}))
router.MustAddRouteExact("/base64",
vgrouter.RouteHandlerFunc(func(rm *vgrouter.RouteMatch) {
root.Body = &Base64{} // A COMPONENT WITH PAGE CONTENTS
}))
router.MustAddRouteExact("/base91",
vgrouter.RouteHandlerFunc(func(rm *vgrouter.RouteMatch) {
root.Body = &Base91{} // A COMPONENT WITH PAGE CONTENTS
}))
router.SetNotFound(vgrouter.RouteHandlerFunc(
func(rm *vgrouter.RouteMatch) {
root.Body = &Home{} // A PAGE FOR THE NOT-FOUND CASE
}))
// TELL THE ROUTER TO LISTEN FOR THE BROWSER CHANGING URLS
err := router.ListenForPopState()
if err != nil {
panic(err)
}
// GRAB THE CURRENT BROWSER URL AND PROCESS IT AS A ROUTE
err = router.Pull()
if err != nil {
panic(err)
}
return root
}