ref: 5acc68f9d3f5e32037b25853b899e62f9aac98c7
parent: 61a338e19d2e61337515130f2c635e5b6428a687
author: Philip Silva <philip.silva@protonmail.com>
date: Sat Mar 27 17:33:48 EDT 2021
Support picture tag - try to pick smallest image/image fitting to screen scale - prevent too large images on some websites leading to too wide text
--- a/browser/browser.go
+++ b/browser/browser.go
@@ -18,6 +18,7 @@
"github.com/psilva261/opossum/nodes"
"github.com/psilva261/opossum/style"
"os"
+ "strconv"
"strings"
"github.com/mjl-/duit"
@@ -189,7 +190,9 @@
return nil, fmt.Errorf("display nil")}
- if n.Data() == "svg" {+ if n.Data() == "picture" {+ src = newPicture(n)
+ } else if n.Data() == "svg" {xml, err := n.Serialized()
if err != nil { return nil, fmt.Errorf("serialize: %w", err)@@ -240,6 +243,43 @@
), nil
}
+func newPicture(n *nodes.Node) string {+ smallestImg := ""
+ smallestW := 0
+ scale := 1
+
+ if dui != nil {+ scale = int(dui.Scale(1))
+ }
+
+ for _, source := range n.FindAll("source") {+ for _, s := range strings.Split(source.Attr("srcset"), ",") {+ s = strings.TrimSpace(s)
+ tmp := strings.Split(s, " ")
+ src := ""
+ s := ""
+ src = tmp[0]
+ if len(tmp) == 2 {+ s = tmp[1]
+ }
+ if s == "" || s == fmt.Sprintf("%vx", scale) {+ return src
+ }
+ s = strings.TrimSuffix(s, "w")
+ w, err := strconv.Atoi(s)
+ if err != nil {+ continue
+ }
+ if smallestImg == "" || smallestW > w {+ smallestImg = src
+ smallestW = w
+ }
+ }
+ }
+
+ return smallestImg
+}
+
type Element struct {duit.UI
n *nodes.Node
@@ -1035,7 +1075,7 @@
return NewElement(btn, n)
case "table":
return NewTable(n).Element(r+1, b, n)
- case "img", "svg":
+ case "picture", "img", "svg":
return NewElement(NewImage(n), n)
case "pre":
return NewElement(
--- a/browser/browser_test.go
+++ b/browser/browser_test.go
@@ -410,3 +410,22 @@
}
}
+func TestNewPicture(t *testing.T) {+ htm := `
+ <picture itemprop="contentUrl">
+ <source srcset="https://example.com/2040 2040w,https://example.com/1880 1880w,https://example.com/1400 1400w" media="(-webkit-min-device-pixel-ratio: 1.25), (min-resolution: 120dpi)">
+ <source srcset="https://example.com/1020 1020w,https://example.com/940 940w,https://example.com/700 700w">
+ <img src="https://example.com/465" height="5000" width="7000" loading="lazy">
+ </picture>
+ `
+ nt, _, err := digestHtm(htm)
+ if err != nil {+ t.Fatalf("digest: %v", err)+ }
+
+ p := nt.Find("picture")+ src := newPicture(p)
+ if src != "https://example.com/700" {+ t.Error()
+ }
+}
--- a/nodes/nodes.go
+++ b/nodes/nodes.go
@@ -122,6 +122,18 @@
return
}
+func (n *Node) FindAll(tag string) (cs []*Node) {+ for _, cc := range n.Children {+ if cc.Data() == tag {+ cs = append(cs, cc)
+ } else {+ cs = append(cs, cc.FindAll(tag)...)
+ }
+ }
+
+ return
+}
+
func (n *Node) Attr(k string) string { for _, a := range n.Attrs { if a.Key == k {--
⑨