ref: bfe62e5957b0791af5a2f0684314b32cc0ee5383
parent: fac398b8c20c0701b84bd6ccbbed67cbfcb6db95
author: Philip Silva <[email protected]>
date: Sun Dec 13 06:30:12 EST 2020
Back button
--- a/README.md
+++ b/README.md
@@ -40,4 +40,4 @@
- load images on the fly
- implement more parts of HTML5 and CSS
- create a widget for div/span
-- clean up code, support webfs, snarf, file downloads
\ No newline at end of file
+- clean up code, support webfs, snarf, file downloads
--- a/browser/browser.go
+++ b/browser/browser.go
@@ -164,8 +164,8 @@
if imgUrl, err = browser.LinkedUrl(src); err != nil {
return nil, err
}
- if data, _, err = browser.Get(*imgUrl); err != nil {
- return nil, fmt.Errorf("get %v: %w", *imgUrl, err)
+ if data, _, err = browser.Get(imgUrl); err != nil {
+ return nil, fmt.Errorf("get %v: %w", imgUrl, err)
}
}
@@ -182,7 +182,7 @@
if w != 0 || h != 0 {
image, _, err := image.Decode(bytes.NewReader(data))
if err != nil {
- return nil, fmt.Errorf("decode %v: %w", *imgUrl, err)
+ return nil, fmt.Errorf("decode %v: %w", imgUrl, err)
}
// check err
@@ -387,8 +387,6 @@
if 5 <= x && x <= (maxX-5) && 5 <= y && y <= (maxY-5) {
//log.Printf("Mouse %v (m ~ %v); Kid.R.Dx/Dy=%v/%v\n", el.UI, m.Point, self.R.Dx(), self.R.Dy())
if el.IsLink {
- //fmt.Printf("do hover\n")
- // dui.Display.SetCursor(nil) // set to system cursor
yolo := [2 * 16]uint8{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 90, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}
dui.Display.SetCursor(&draw.Cursor{
Set: yolo,
@@ -400,8 +398,6 @@
}
} else {
if el.IsLink {
- // this never hhappens :/
- //fmt.Printf("unhover\n")
dui.Display.SetCursor(nil)
} else {
dui.Display.SetCursor(nil)
@@ -480,7 +476,7 @@
if m := attr(*form, "method"); m != "" {
method = strings.ToUpper(m)
}
- uri := b.URL
+ uri := b.URL()
log.Printf("form = %+v", form)
if action := attr(*form, "action"); action != "" {
uri, err = b.LinkedUrl(action)
@@ -499,10 +495,10 @@
}
uri.RawQuery = q.Encode()
log.Printf("uri raw query=%v", uri.RawQuery)
- buf, contentType, err = b.get(*uri, true)
+ buf, contentType, err = b.get(uri, true)
log.Printf("uri=%v", uri.String())
} else {
- buf, contentType, err = b.PostForm(*uri, formData(*form))
+ buf, contentType, err = b.PostForm(uri, formData(*form))
}
if err == nil {
if contentType.IsHTML() {
@@ -1128,10 +1124,36 @@
}
}
+type History struct {
+ urls []*url.URL
+}
+
+func (h History) URL() *url.URL {
+ return h.urls[len(h.urls)-1]
+}
+
+func (h *History) Push(u *url.URL) {
+ h.urls = append(h.urls, u)
+}
+
+func (h *History) Back() {
+ if len(h.urls) > 1 {
+ h.urls = h.urls[:len(h.urls)-1]
+ }
+}
+
+func (h *History) String() string {
+ addrs := make([]string, len(h.urls))
+ for i, u := range h.urls {
+ addrs[i] = u.String()
+ }
+ return strings.Join(addrs, ", ")
+}
+
type Browser struct {
+ History
dui *duit.DUI
html string
- URL *url.URL
Website *Website
StatusBar *duit.Label
LocationField *duit.Field
@@ -1158,7 +1180,6 @@
b.LocationField = &duit.Field{
Text: initUrl,
Font: Style.Font(),
- Changed: b.SetUrl,
}
u, err := url.Parse(initUrl)
@@ -1165,9 +1186,9 @@
if err != nil {
log.Fatalf("parse: %v", err)
}
- b.URL = u
+ b.History.Push(u)
- buf, _, err := b.Get(*u)
+ buf, _, err := b.Get(u)
if err != nil {
log.Fatalf("get: %v", err)
}
@@ -1178,27 +1199,26 @@
dui = _dui
b.layoutWebsite()
- b.SetUrl(initUrl)
return
}
func (b *Browser) LinkedUrl(addr string) (a *url.URL, err error) {
- log.Printf("LinkedUrl: addr=%v, b.URL=%v", addr, b.URL)
+ log.Printf("LinkedUrl: addr=%v, b.URL=%v", addr, b.URL())
if strings.HasPrefix(addr, "//") {
- addr = b.URL.Scheme + ":" + addr
+ addr = b.URL().Scheme + ":" + addr
} else if strings.HasPrefix(addr, "/") {
- addr = b.URL.Scheme + "://" + b.URL.Host + addr
+ addr = b.URL().Scheme + "://" + b.URL().Host + addr
} else if !strings.HasPrefix(addr, "http") {
- if strings.HasSuffix(b.URL.Path, "/") {
+ if strings.HasSuffix(b.URL().Path, "/") {
log.Printf("A")
- addr = "/" + b.URL.Path + "/" + addr
+ addr = "/" + b.URL().Path + "/" + addr
} else {
log.Printf("B")
- m := strings.LastIndex(b.URL.Path, "/")
+ m := strings.LastIndex(b.URL().Path, "/")
if m > 0 {
log.Printf("B.>")
- folder := b.URL.Path[0:m]
+ folder := b.URL().Path[0:m]
addr = "/" + folder + "/" + addr
} else {
log.Printf("B.<=")
@@ -1206,19 +1226,29 @@
}
}
addr = strings.ReplaceAll(addr, "//", "/")
- addr = b.URL.Scheme + "://" + b.URL.Host + addr
+ addr = b.URL().Scheme + "://" + b.URL().Host + addr
}
return url.Parse(addr)
}
+func (b *Browser) Back() (e duit.Event) {
+ if len(b.History.urls) > 0 {
+ b.History.Back()
+ b.LocationField.Text = b.History.URL().String()
+ b.LoadUrl()
+ }
+ e.Consumed = true
+ return
+}
+
func (b *Browser) SetAndLoadUrl(addr string) func() duit.Event {
a := addr
return func() duit.Event {
log.Printf("SetAndLoadUrl::callback: addr=%v", addr)
- log.Printf(" b.URL=%v", b.URL)
+ log.Printf(" b.URL=%v", b.URL())
url, err := b.LinkedUrl(addr)
if err == nil {
- b.SetUrl(url.String())
+ b.LocationField.Text = url.String()
b.LoadUrl()
} else {
log.Printf("parse url %v: %v", a, err)
@@ -1230,22 +1260,6 @@
}
}
-func (b *Browser) SetUrl(addr string) (e duit.Event) {
- log.Printf("SetUrl(%v)", addr)
- var err error
- if !strings.HasPrefix(addr, "http") {
- addr = "https://" + addr
- }
- b.URL, err = url.Parse(addr)
- if err != nil {
- log.Printf("could not parse url: %v", err)
- }
- log.Printf(" b.Url=%v", b.URL)
- return duit.Event{
- Consumed: true,
- }
-}
-
func (b *Browser) showBodyMessage(msg string) {
b.Website.UI = &duit.Label{
Text: msg,
@@ -1257,18 +1271,22 @@
}
func (b *Browser) LoadUrl() (e duit.Event) {
- if b.URL == nil {
- e.Consumed = true
- return
+ addr := b.LocationField.Text
+ if !strings.HasPrefix(addr, "http") {
+ addr = "https://" + addr
}
- addr := b.URL.String()
log.Printf("Getting %v...", addr)
- buf, contentType, err := b.get(*b.URL, true)
+ url, err := url.Parse(addr)
if err != nil {
+ log.Errorf("load url: error parsing %v", addr)
+ return
+ }
+ buf, contentType, err := b.get(url, true)
+ if err != nil {
log.Errorf("error loading %v: %v", addr, err)
err = errors.Unwrap(err)
if strings.Contains(err.Error(), "HTTP response to HTTPS client") {
- b.SetUrl(strings.Replace(b.URL.String(), "https://", "http://", 1))
+ b.LocationField.Text = strings.Replace(url.String(), "https://", "http://", 1)
return b.LoadUrl()
}
b.showBodyMessage(err.Error())
@@ -1306,7 +1324,7 @@
log.Printf("Rendering done")
}
-func (b *Browser) Get(uri url.URL) (buf []byte, contentType opossum.ContentType, err error) {
+func (b *Browser) Get(uri *url.URL) (buf []byte, contentType opossum.ContentType, err error) {
c, ok := cache[uri.String()]
if ok {
log.Printf("use %v from cache", uri)
@@ -1332,7 +1350,7 @@
dui.Render()
}
-func (b *Browser) get(uri url.URL, isNewOrigin bool) (buf []byte, contentType opossum.ContentType, err error) {
+func (b *Browser) get(uri *url.URL, isNewOrigin bool) (buf []byte, contentType opossum.ContentType, err error) {
msg := fmt.Sprintf("Get %v", uri.String())
log.Printf(msg)
b.statusBarMsg(msg, true)
@@ -1349,10 +1367,6 @@
return nil, opossum.ContentType{}, fmt.Errorf("error loading %v: %w", uri, err)
}
defer resp.Body.Close()
- if isNewOrigin {
- b.URL = resp.Request.URL
- b.LocationField.Text = b.URL.String()
- }
buf, err = ioutil.ReadAll(resp.Body)
if err != nil {
return nil, opossum.ContentType{}, fmt.Errorf("error reading")
@@ -1362,10 +1376,15 @@
if err == nil && (contentType.IsHTML() || contentType.IsCSS() || contentType.IsPlain()) {
buf = contentType.Utf8(buf)
}
+ if isNewOrigin {
+ b.History.Push(resp.Request.URL)
+ log.Printf("b.History is now %s", b.History.String())
+ b.LocationField.Text = b.URL().String()
+ }
return
}
-func (b *Browser) PostForm(uri url.URL, data url.Values) (buf []byte, contentType opossum.ContentType, err error) {
+func (b *Browser) PostForm(uri *url.URL, data url.Values) (buf []byte, contentType opossum.ContentType, err error) {
b.Website.UI = &duit.Label{Text: "Posting..."}
dui.MarkLayout(dui.Top.UI)
dui.MarkDraw(dui.Top.UI)
@@ -1381,7 +1400,7 @@
return nil, opossum.ContentType{}, fmt.Errorf("error loading %v: %w", uri, err)
}
defer resp.Body.Close()
- b.URL = resp.Request.URL
+ b.History.Push(resp.Request.URL)
buf, err = ioutil.ReadAll(resp.Body)
if err != nil {
return nil, opossum.ContentType{}, fmt.Errorf("error reading")
@@ -1446,7 +1465,7 @@
continue
}
log.Printf("Download %v", url)
- buf, contentType, err := b.Get(*url)
+ buf, contentType, err := b.Get(url)
if err != nil {
log.Printf("error downloading %v", url)
continue
@@ -1462,9 +1481,6 @@
if *ExperimentalJsInsecure {
log.Printf("3rd pass")
- if b.URL == nil {
- b.SetUrl("opossum://go")
- }
nt := nodes.NewNodeTree(doc, style.Map{}, nodeMap, nil)
jsSrcs := domino.Srcs(nt)
downloads := make(map[string]string)
@@ -1475,7 +1491,7 @@
continue
}
log.Printf("Download %v", url)
- buf, _ /*contentType*/, err := b.Get(*url)
+ buf, _, err := b.Get(url)
if err != nil {
log.Printf("error downloading %v", url)
continue
--- a/browser/browser_test.go
+++ b/browser/browser_test.go
@@ -45,7 +45,7 @@
if err != nil {
panic(err.Error())
}
- b.URL = origin
+ b.History.Push(origin)
res, err := b.LinkedUrl(i.href)
if err != nil {
panic(err.Error())
--- a/cmd/browse/main.go
+++ b/cmd/browse/main.go
@@ -55,11 +55,16 @@
dui.Top.UI = &duit.Box{
Kids: duit.NewKids(
&duit.Grid{
- Columns: 2,
- Padding: duit.NSpace(2, duit.SpaceXY(5, 3)),
- Halign: []duit.Halign{duit.HalignLeft, duit.HalignRight},
- Valign: []duit.Valign{duit.ValignMiddle, duit.ValignMiddle},
+ Columns: 3,
+ Padding: duit.NSpace(3, duit.SpaceXY(5, 3)),
+ Halign: []duit.Halign{duit.HalignLeft, duit.HalignLeft, duit.HalignRight},
+ Valign: []duit.Valign{duit.ValignMiddle, duit.ValignMiddle, duit.ValignMiddle},
Kids: duit.NewKids(
+ &duit.Button{
+ Text: "Back",
+ Font: browser.Style.Font(),
+ Click: b.Back,
+ },
&duit.Button{
Text: "Load",
Font: browser.Style.Font(),
--- a/opossum.go
+++ b/opossum.go
@@ -20,7 +20,7 @@
// LinkedUrl relative to current page
LinkedUrl(string) (*url.URL, error)
- Get(url.URL) ([]byte, ContentType, error)
+ Get(*url.URL) ([]byte, ContentType, error)
}
type ContentType struct {
--- a/package.rc
+++ b/package.rc
@@ -8,6 +8,7 @@
cd ../..
mv cmd/browse/opossum-plan9-amd64.bin .
mv opossum-plan9-amd64.bin ./opossum-plan9-amd64/
+cp README.md ./opossum-plan9-amd64/
cp normalize.css ./opossum-plan9-amd64/
dircp domino-lib ./opossum-plan9-amd64/domino-lib
tar czf opossum-plan9-amd64.tgz opossum-plan9-amd64
--- a/style/experimental.go
+++ b/style/experimental.go
@@ -90,7 +90,7 @@
log.Printf("bg img interpet url: %v", err)
return nil
}
- buf, contentType, err := fetcher.Get(*uri)
+ buf, contentType, err := fetcher.Get(uri)
if err != nil {
log.Printf("bg img get %v (%v): %v", uri, contentType, err)
return nil