shithub: mycel

Download patch

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 {