diff --git a/Makefile b/Makefile index 6bb3e20..b8a75d6 100644 --- a/Makefile +++ b/Makefile @@ -68,6 +68,12 @@ vugu: clean cp ./vugu/index.html ./html/ cp $$(go env GOROOT)/misc/wasm/wasm_exec.js ./html/wasm_exec.js +.PHONY: vecty +vecty: clean + GOOS=js GOARCH=wasm go build -o ./html/test.wasm ./vecty/main.go + cp ./vecty/index.html ./html/index.html + cp $$(go env GOROOT)/misc/wasm/wasm_exec.js ./html/wasm_exec.js + test: clean GOOS=js GOARCH=wasm go test -c -o ./html/test.wasm ./test/ diff --git a/go.mod b/go.mod index 35c9531..117e9a3 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,11 @@ go 1.12 require ( github.com/NYTimes/gziphandler v1.1.1 github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 + github.com/gopherjs/vecty v0.0.0-20190701174234-2b6fc20f8913 // indirect github.com/hajimehoshi/ebiten v1.9.3 + github.com/microcosm-cc/bluemonday v1.0.2 // indirect + github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect + github.com/slimsag/blackfriday v2.0.0+incompatible // indirect github.com/vugu/vugu v0.0.0-20190518235128-5a84f26390d1 golang.org/x/image v0.0.0-20190618124811-92942e4437e2 ) diff --git a/go.sum b/go.sum index 050914e..937be79 100644 --- a/go.sum +++ b/go.sum @@ -19,6 +19,8 @@ github.com/gopherjs/gopherwasm v0.1.1/go.mod h1:kx4n9a+MzHH0BJJhvlsQ65hqLFXDO/m2 github.com/gopherjs/gopherwasm v1.0.0/go.mod h1:SkZ8z7CWBz5VXbhJel8TxCmAcsQqzgWGR/8nMhyhZSI= github.com/gopherjs/gopherwasm v1.1.0 h1:fA2uLoctU5+T3OhOn2vYP0DVT6pxc7xhTlBB1paATqQ= github.com/gopherjs/gopherwasm v1.1.0/go.mod h1:SkZ8z7CWBz5VXbhJel8TxCmAcsQqzgWGR/8nMhyhZSI= +github.com/gopherjs/vecty v0.0.0-20190701174234-2b6fc20f8913 h1:h5R2K5Wqn5av3i4xHkyVgI2qCSbpJHAqqAkKpMPh0eE= +github.com/gopherjs/vecty v0.0.0-20190701174234-2b6fc20f8913/go.mod h1:Yd9AOfl6lN1BWnVnvaSBwKiTCAcnlIGGvdsODOOZ9RY= github.com/hajimehoshi/bitmapfont v1.1.1 h1:H1wQ6QXA8kSp+plARsIMCTVb5iOZHq/OP3uyL5NzLuU= github.com/hajimehoshi/bitmapfont v1.1.1/go.mod h1:Hamfxgney7tDSmVOSDh2AWzoDH70OaC+P24zc02Gum4= github.com/hajimehoshi/ebiten v1.9.3 h1:YijWGMBwH2XA1ZytUQFy33UDHeCSS6d4JZKH1wq38O0= @@ -37,8 +39,14 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/microcosm-cc/bluemonday v1.0.2 h1:5lPfLTTAvAbtS0VqT+94yOtFnGfUWYyx0+iToC3Os3s= +github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= 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/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/slimsag/blackfriday v2.0.0+incompatible h1:3mjnT4p/+Ow8j8/T6H01S5pxXNPhVuOBzxmAbsszxi4= +github.com/slimsag/blackfriday v2.0.0+incompatible/go.mod h1:K2UwInbJ1ywJkRQ2IMfjP071c3KZu7FiOn2NW97ckKk= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -57,6 +65,7 @@ golang.org/x/image v0.0.0-20190618124811-92942e4437e2/go.mod h1:FeLwcggjj3mMvU+o golang.org/x/mobile v0.0.0-20180806140643-507816974b79/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190127143845-a42111704963 h1:2HSxAhImj2OpXsNjXSqfnv1xtqeCpDjwPB3o1DnQqKM= golang.org/x/mobile v0.0.0-20190127143845-a42111704963/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190328230028-74de082e2cca h1:hyA6yiAgbUwuWqtscNvWAI7U1CtlaD1KilQ6iudt1aI= golang.org/x/net v0.0.0-20190328230028-74de082e2cca/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= diff --git a/vecty/index.html b/vecty/index.html new file mode 100644 index 0000000..9ea5d74 --- /dev/null +++ b/vecty/index.html @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + diff --git a/vecty/main.go b/vecty/main.go new file mode 100644 index 0000000..4d0b478 --- /dev/null +++ b/vecty/main.go @@ -0,0 +1,78 @@ +package main + +import ( + "github.com/gopherjs/vecty" + "github.com/gopherjs/vecty/elem" + "github.com/gopherjs/vecty/event" + "github.com/microcosm-cc/bluemonday" + "github.com/slimsag/blackfriday" +) + +func main() { + vecty.SetTitle("Markdown Demo") + vecty.RenderBody(&PageView{ + Input: `# Markdown Example + +This is a live editor, try editing the Markdown on the right of the page. +`, + }) +} + +// PageView is our main page component. +type PageView struct { + vecty.Core + Input string +} + +// Render implements the vecty.Component interface. +func (p *PageView) Render() vecty.ComponentOrHTML { + return elem.Body( + // Display a textarea on the right-hand side of the page. + elem.Div( + vecty.Markup( + vecty.Style("float", "right"), + ), + elem.TextArea( + vecty.Markup( + vecty.Style("font-family", "monospace"), + vecty.Property("rows", 14), + vecty.Property("cols", 70), + + // When input is typed into the textarea, update the local + // component state and rerender. + event.Input(func(e *vecty.Event) { + p.Input = e.Target.Get("value").String() + vecty.Rerender(p) + }), + ), + vecty.Text(p.Input), // initial textarea text. + ), + ), + + // Render the markdown. + &Markdown{Input: p.Input}, + ) +} + +// Markdown is a simple component which renders the Input markdown as sanitized +// HTML into a div. +type Markdown struct { + vecty.Core + Input string `vecty:"prop"` +} + +// Render implements the vecty.Component interface. +func (m *Markdown) Render() vecty.ComponentOrHTML { + // Render the markdown input into HTML using Blackfriday. + unsafeHTML := blackfriday.Run([]byte(m.Input)) + + // Sanitize the HTML. + safeHTML := string(bluemonday.UGCPolicy().SanitizeBytes(unsafeHTML)) + + // Return the HTML, which we guarantee to be safe / sanitized. + return elem.Div( + vecty.Markup( + vecty.UnsafeHTML(safeHTML), + ), + ) +}