ref: 8bd61f88172581a0af0ea5f2293bff43f011eb1b
parent: 5acc68f9d3f5e32037b25853b899e62f9aac98c7
author: Philip Silva <philip.silva@protonmail.com>
date: Sun Mar 28 07:14:28 EDT 2021
Improved <pre> and <textarea> support - keep spaces - font height in low dpi
--- a/browser/browser.go
+++ b/browser/browser.go
@@ -139,15 +139,11 @@
edit := &duit.Edit{
Font: Style.Font(),
}
- formatted := ""
- lines := strings.Split(s, "\n")
- for _, line := range lines {
- formatted += strings.TrimSpace(line) + "\n"
- }
- edit.Append([]byte(formatted))
+ lines := len(strings.Split(s, "\n"))
+ edit.Append([]byte(s))
cv.UI = &Box{
Kids: duit.NewKids(edit),
- Height: n.Font().Height * (len(lines)+2),
+ Height: int(n.FontHeight()) * (lines+2),
}
return
}
@@ -430,7 +426,7 @@
if v := attr(*n.DomSubtree, "value"); v != "" {
t = v
- } else if c := strings.TrimSpace(n.ContentString()); c != "" {
+ } else if c := strings.TrimSpace(n.ContentString(false)); c != "" {
t = c
} else {
t = "Submit"
@@ -524,7 +520,7 @@
continue
}
lv := &duit.ListValue{
- Text: c.ContentString(),
+ Text: c.ContentString(false),
Value: c.Attr("value"),
Selected: c.HasAttr("selected"),
}
@@ -540,12 +536,8 @@
}
func NewTextArea(n *nodes.Node) *Element {
- t := n.ContentString()
- formatted := ""
- lines := strings.Split(t, "\n")
- for _, line := range lines {
- formatted += line + "\n"
- }
+ t := n.ContentString(true)
+ lines := len(strings.Split(t, "\n"))
edit := &duit.Edit{
Font: Style.Font(),
Keys: func(k rune, m draw.Mouse) (e duit.Event) {
@@ -553,10 +545,10 @@
return
},
}
- edit.Append([]byte(formatted))
+ edit.Append([]byte(t))
if n.Css("height") == "" {
- n.SetCss("height", fmt.Sprintf("%vpx", (n.Font().Height * (len(lines)+2))))
+ n.SetCss("height", fmt.Sprintf("%vpx", (int(n.FontHeight()) * (lines+2))))
}
el := NewElement(edit, n)
@@ -1068,7 +1060,7 @@
}
btn := &duit.Button{
- Text: n.ContentString(),
+ Text: n.ContentString(false),
Font: n.Font(),
}
@@ -1079,7 +1071,7 @@
return NewElement(NewImage(n), n)
case "pre":
return NewElement(
- NewCodeView(n.ContentString(), n.Map),
+ NewCodeView(n.ContentString(true), n.Map),
n,
)
case "li":
@@ -1086,7 +1078,7 @@
var innerContent duit.UI
if nodes.IsPureTextContent(*n) {
- t := n.ContentString()
+ t := n.ContentString(false)
if ul := n.Ancestor("ul"); ul != nil {
if ul.Css("list-style") != "none" && n.Css("list-style-type") != "none" {
@@ -1115,7 +1107,7 @@
} else if n.Type() == html.TextNode {
// Leaf text object
- if text := n.ContentString(); text != "" {
+ if text := n.ContentString(false); text != "" {
ui := NewLabel(text, n)
return NewElement(ui, n)
@@ -1144,11 +1136,11 @@
continue
}
if isWrapped(c) {
- ls := NewText(c.Content(), c)
+ ls := NewText(c.Content(false), c)
els = append(els, ls...)
} else if nodes.IsPureTextContent(*n) {
// Handle text wrapped in unwrappable tags like p, div, ...
- ls := NewText(c.Content(), c.Children[0])
+ ls := NewText(c.Content(false), c.Children[0])
if len(ls) == 0 {
continue
}
--- a/browser/website.go
+++ b/browser/website.go
@@ -185,7 +185,7 @@
nn := nodes.NewNodeTree(n, style.Map{}, make(map[*html.Node]style.Map), nil)
if nm != "" {
- data.Set(nm, nn.ContentString())
+ data.Set(nm, nn.ContentString(false))
}
}
--- a/domino/domino.go
+++ b/domino/domino.go
@@ -430,7 +430,7 @@
}
if isJS {
- fn(src, n.ContentString())
+ fn(src, n.ContentString(true))
}
}
for _, c := range n.Children {
--- a/nodes/nodes.go
+++ b/nodes/nodes.go
@@ -222,11 +222,14 @@
return true
}
-func (n Node) Content() []string {
+func (n Node) Content(pre bool) []string {
content := make([]string, 0, len(n.Children))
if n.Text != "" && n.Type() == html.TextNode && !n.Map.IsDisplayNone() {
- t := strings.TrimSpace(n.Text)
+ t := n.Text
+ if !pre {
+ t = strings.TrimSpace(t)
+ }
if t != "" {
content = append(content, t)
}
@@ -234,7 +237,7 @@
for _, c := range n.Children {
if !c.Map.IsDisplayNone() {
- content = append(content, c.Content()...)
+ content = append(content, c.Content(pre)...)
}
}
@@ -241,9 +244,14 @@
return content
}
-func (n Node) ContentString() (t string) {
- t = strings.Join(n.Content(), " ")
- t = strings.TrimSpace(t)
+func (n Node) ContentString(pre bool) (t string) {
+ ts := n.Content(pre)
+ if pre {
+ t = strings.Join(ts, "")
+ } else {
+ t = strings.Join(ts, " ")
+ t = strings.TrimSpace(t)
+ }
return
}
--- a/nodes/nodes_test.go
+++ b/nodes/nodes_test.go
@@ -39,11 +39,11 @@
doc, err := html.Parse(buf)
if err != nil { t.Fatalf(err.Error()) }
n := NewNodeTree(doc, style.Map{}, make(map[*html.Node]style.Map), nil)
- if s := n.ContentString(); s != "initial" {
+ if s := n.ContentString(false); s != "initial" {
t.Fatalf(s)
}
n.SetText("123")
- if s := n.ContentString(); s != "123" {
+ if s := n.ContentString(false); s != "123" {
t.Fatalf(s)
}
}
--- a/style/fonts_plan9.go
+++ b/style/fonts_plan9.go
@@ -7,6 +7,8 @@
"math"
)
+func initFontserver() {}
+
func matchClosestFontSize(desired float64, available []int) (closest int) {
for _, a := range available {
if closest == 0 || math.Abs(float64(a)-desired) < math.Abs(float64(closest)-desired) {
--- a/style/fonts_unix.go
+++ b/style/fonts_unix.go
@@ -5,7 +5,18 @@
import (
"fmt"
"math"
+ "os/exec"
+ "strings"
)
+
+func initFontserver() {
+ buf, err := exec.Command("fontsrv", "-p", ".").Output()
+ if err == nil {
+ availableFontNames = strings.Split(string(buf), "\n")
+ } else {
+ log.Printf("exec fontsrv: %v", err)
+ }
+}
func (cs Map) FontFilename() string {
pref := cs.preferedFontName([]string{"HelveticaNeue", "Helvetica"})
--- a/style/stylesheets.go
+++ b/style/stylesheets.go
@@ -10,7 +10,6 @@
"golang.org/x/image/colornames"
"golang.org/x/net/html"
"github.com/psilva261/opossum/logger"
- "os/exec"
"regexp"
"strconv"
"strings"
@@ -62,15 +61,6 @@
initFontserver()
}
-func initFontserver() {
- buf, err := exec.Command("fontsrv", "-p", ".").Output()
- if err == nil {
- availableFontNames = strings.Split(string(buf), "\n")
- } else {
- log.Printf("exec fontsrv: %v", err)
- }
-}
-
func Hrefs(doc *html.Node) (hrefs []string) {
hrefs = make([]string, 0, 3)
@@ -334,6 +324,11 @@
f *= FontBaseSize
}
return f
+}
+
+// FontHeight in lowDPI pixels.
+func (cs Map) FontHeight() float64 {
+ return float64(cs.Font().Height) / float64(dui.Scale(1))
}
func (cs Map) Color() draw.Color {