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 {