shithub: mycel

Download patch

ref: 36ab9e8b4b71c5af9808b48abdbc114a70136dcb
parent: 3ddf47ad691b8fdae0aa930543107052a6ee2d6d
author: Philip Silva <philip.silva@protonmail.com>
date: Sun Feb 14 07:09:00 EST 2021

select

--- a/browser/browser.go
+++ b/browser/browser.go
@@ -116,7 +116,7 @@
 	edit.Append([]byte(formatted))
 	cv.UI = &duit.Box{
 		Kids:   duit.NewKids(edit),
-		Height: (int(n.FontSize()) + 4) * (len(lines)+2),
+		Height: n.Font().Height * (len(lines)+2),
 	}
 	return
 }
@@ -405,6 +405,42 @@
 	return NewElement(f, n)
 }
 
+func NewSelect(n *nodes.Node) *Element {
+	var l *duit.List
+	l = &duit.List{
+		Values: make([]*duit.ListValue, 0, len(n.Children)),
+		Font: n.Font(),
+		Changed: func(i int) (e duit.Event) {
+			v := l.Values[i]
+			vv := fmt.Sprintf("%v", v.Value)
+			if vv == "" {
+				vv = v.Text
+			}
+			setAttr(n.DomSubtree, "value", vv)
+			e.Consumed = true
+			return
+		},
+	}
+	for _, c := range n.Children {
+		if c.Data() != "option" {
+			continue
+		}
+		lv := &duit.ListValue{
+			Text: nodes.ContentFrom(*c),
+			Value: c.Attr("value"),
+			Selected: c.HasAttr("selected"),
+		}
+		l.Values = append(l.Values, lv)
+	}
+	if n.Css("width") == "" && n.Css("max-width") == "" {
+		n.SetCss("max-width", "200px")
+	}
+	if n.Css("height") == "" {
+		n.SetCss("height", fmt.Sprintf("%vpx", 4 * n.Font().Height))
+	}
+	return NewElement(NewScroll(l), n)
+}
+
 func NewTextArea(n *nodes.Node) *Element {
 	t := strings.TrimSpace(nodes.ContentFrom(*n))
 	formatted := ""
@@ -422,7 +458,7 @@
 	edit.Append([]byte(formatted))
 
 	if n.Css("height") == "" {
-		n.SetCss("height", fmt.Sprintf("%vpx", (int(n.FontSize()) + 4) * (len(lines)+2)))
+		n.SetCss("height", fmt.Sprintf("%vpx", (n.Font().Height * (len(lines)+2))))
 	}
 
 	el := NewElement(edit, n)
@@ -490,6 +526,15 @@
 	return el.UI.Mouse(dui, self, m, origM, orig)
 }
 
+func (el *Element) FirstFocus(dui *duit.DUI, self *duit.Kid) *image.Point {
+	// Provide custom implementation with nil check because of nil Elements.
+	// (TODO: remove)
+	if el == nil {
+		return &image.Point{}
+	}
+	return el.UI.FirstFocus(dui, self)
+}
+
 func (el *Element) click() (consumed bool) {
 	if el.Click != nil {
 		e := el.Click()
@@ -905,6 +950,8 @@
 			} else {
 				return nil
 			}
+		case "select":
+			return NewSelect(n)
 		case "textarea":
 			return NewTextArea(n)
 		case "button":
@@ -1080,6 +1127,8 @@
 	case *duit.Field:
 	case *duit.Edit:
 	case *duit.Button:
+	case *duit.List:
+	case *duit.Scroll:
 	case *CodeView:
 	default:
 		panic(fmt.Sprintf("unknown: %+v", v))
--- a/browser/experimental.go
+++ b/browser/experimental.go
@@ -87,39 +87,6 @@
 	}
 }
 
-func CleanTree(ui duit.UI) {
-	if ui == nil {
-		panic("nil root")
-	}
-	TraverseTree(ui, func(ui duit.UI) {
-		if ui == nil {
-			panic("null")
-		}
-		switch v := ui.(type) {
-		case nil:
-			panic("null")
-		case *duit.Scroll:
-			panic("like nil root")
-		case *duit.Box:
-			//realKids := make([])
-		case *Element:
-			if v == nil {
-				panic("null element")
-			}
-		case *duit.Grid:
-		case *duit.Image:
-		case *duit.Label:
-		case *Label:
-		case *duit.Button:
-		case *Image:
-		case *duit.Field:
-		case *CodeView:
-		default:
-			panic(fmt.Sprintf("unknown: %+v", v))
-		}
-	})
-}
-
 func processJS2(d *domino.Domino, scripts []string) (resHtm string, changed bool, err error) {
 	initialized := false
 	for _, script := range scripts {
--- a/browser/website.go
+++ b/browser/website.go
@@ -171,7 +171,7 @@
 	nm := attr(*n, "name")
 
 	switch n.Data {
-	case "input":
+	case "input", "select":
 		if attr(*n, "type") == "submit" && n != submitBtn {
 			return
 		}
--- a/nodes/nodes.go
+++ b/nodes/nodes.go
@@ -146,6 +146,15 @@
 	return ""
 }
 
+func (n *Node) HasAttr(k string) bool {
+	for _, a := range n.Attrs {
+		if a.Key == k {
+			return true
+		}
+	}
+	return false
+}
+
 // QueryRef relative to html > body
 func (n *Node) QueryRef() string {
 	nRef, ok := n.queryRef()