Diff
diff --git a/events/main.go b/events/main.go
index 93b9872..6cf5010 100644
--- a/events/main.go
+++ b/events/main.go
@@ -7,0 +8,2 @@ import (
+ "sort"
+ "strconv"
@@ -8,0 +11,3 @@ import (
+ "unicode"
+
+ "slices"
@@ -21,5 +26,7 @@ type Monitor struct {
- State *map[string]element.State
- Adapter *adapter.Adapter
- History *map[string]element.EventList
- CSS *cstyle.CSS
- Focus Focus
+ Document *element.Node
+ State *map[string]element.State
+ EventList *element.EventList
+ Adapter *adapter.Adapter
+ History *map[string]element.EventList
+ CSS *cstyle.CSS
+ Focus Focus
@@ -36 +43,16 @@ type Focus struct {
-func (m *Monitor) RunEvents(n *element.Node) {
+func (m *Monitor) RunEvents(n *element.Node, rd []element.State) bool {
+ eventRan := false
+ for _, evt := range *m.History {
+ if len(evt.List) > 0 {
+ for _, v := range evt.List {
+ if len(evt.Event.Target.Properties.EventListeners[v]) > 0 {
+ for _, handler := range evt.Event.Target.Properties.EventListeners[v] {
+ handler(evt.Event)
+ eventRan = true
+ }
+ }
+ }
+ }
+ }
+ return eventRan
+}
@@ -37,0 +60,3 @@ func (m *Monitor) RunEvents(n *element.Node) {
+func (m *Monitor) GetEvents(data *EventData) {
+ m.Focus.LastClickWasFocused = false
+ m.CalcEvents(m.Document, data)
@@ -42,2 +67,43 @@ func (m *Monitor) RunEvents(n *element.Node) {
-func (m *Monitor) GetEvents(data *EventData) {
- s := *m.State
+func (m *Monitor) CalcEvents(n *element.Node, data *EventData) {
+ if data.Click {
+ m.Focus.SoftFocused = nil
+ }
+ // loop through state to build events, then use multithreading to complete
+ // map
+ for _, v := range n.Children {
+ m.CalcEvents(v, data)
+ }
+
+ // events := map[string]Event{}
+ // for k, v := range *m.State {
+ // event[k] =
+ // }
+
+ if n.TabIndex > -1 {
+ if m.Focus.Nodes != nil {
+ selectedIndex := -1
+ for i, v := range m.Focus.Nodes {
+ if v.Properties.Id == n.Properties.Id {
+ selectedIndex = i
+ }
+ }
+ if selectedIndex == -1 {
+ if n.TabIndex == 9999999 {
+ // Add the last digits of the properties.id to make the elements sort in order
+ numStr := strings.TrimFunc(n.Properties.Id, func(r rune) bool {
+ return !unicode.IsDigit(r) // Remove non-digit characters
+ })
+ prid, _ := strconv.Atoi(numStr)
+ n.TabIndex += prid
+ }
+ m.Focus.Nodes = append([]*element.Node{n}, m.Focus.Nodes...)
+ }
+ } else {
+ m.Focus = Focus{}
+ m.Focus.Selected = -1
+ m.Focus.Nodes = append(m.Focus.Nodes, n)
+ }
+ }
+ sort.Slice(m.Focus.Nodes, func(i, j int) bool {
+ return m.Focus.Nodes[i].TabIndex < m.Focus.Nodes[j].TabIndex // Ascending order by TabIndex
+ })
@@ -45 +111,3 @@ func (m *Monitor) GetEvents(data *EventData) {
- eventMap := map[string][]element.Event{}
+ mHistory := *m.History
+ eventList := []string{}
+ evt := mHistory[n.Properties.Id].Event
@@ -47,3 +115,13 @@ func (m *Monitor) GetEvents(data *EventData) {
- for k, self := range s {
- if data.Click {
- m.Focus.SoftFocused = nil
+ s := *m.State
+ self := s[n.Properties.Id]
+
+ if evt.Target == nil {
+ if len(data.Position) < 2 {
+ data.Position = []int{0, 0}
+ }
+ evt = element.Event{
+ X: data.Position[0],
+ Y: data.Position[1],
+ MouseUp: true,
+ MouseLeave: true,
+ Target: n,
@@ -50,0 +129,5 @@ func (m *Monitor) GetEvents(data *EventData) {
+ (*m.History)[n.Properties.Id] = element.EventList{
+ Event: evt,
+ List: []string{},
+ }
+ }
@@ -52 +135 @@ func (m *Monitor) GetEvents(data *EventData) {
- var isMouseOver, isFocused bool
+ var isMouseOver, isFocused bool
@@ -53,0 +137,14 @@ func (m *Monitor) GetEvents(data *EventData) {
+ if m.Focus.SoftFocused != nil {
+ isFocused = m.Focus.SoftFocused.Properties.Id == n.Properties.Id
+ } else {
+ isFocused = false
+ }
+
+ insideX := (self.X < float32(data.Position[0]) && self.X+self.Width > float32(data.Position[0]))
+ insideY := (self.Y < float32(data.Position[1]) && self.Y+self.Height > float32(data.Position[1]))
+ inside := (insideX && insideY)
+
+ arrowScroll := 0
+
+ if isFocused {
+ // This allows for arrow scrolling when off the element and typing
@@ -55,3 +152,18 @@ func (m *Monitor) GetEvents(data *EventData) {
- isFocused = m.Focus.SoftFocused.Properties.Id == k
- } else {
- isFocused = false
+ if data.Key == 265 {
+ // up
+ arrowScroll += 20
+ } else if data.Key == 264 {
+ // Down
+ arrowScroll -= 20
+ }
+ }
+ // Get the keycode of the pressed key
+ if data.Key != 0 {
+ if n.ContentEditable {
+ // Sync the innertext and value but idk
+ n.Value = n.InnerText
+ ProcessKeyEvent(n, int(data.Key))
+
+ n.InnerText = n.Value
+ eventList = append(eventList, "keypress")
+ }
@@ -60 +172,17 @@ func (m *Monitor) GetEvents(data *EventData) {
- evt := element.Event{}
+ if data.Key == 258 && data.KeyState && !m.Focus.LastClickWasFocused {
+ // Tab
+ mfsLen := len(m.Focus.Nodes)
+ if mfsLen > 0 {
+ store := m.Focus.Selected
+ m.Focus.Selected += 1
+ if m.Focus.Selected >= mfsLen {
+ m.Focus.Selected = 0
+ }
+ if store != m.Focus.Selected {
+ if store > -1 {
+ m.Focus.Nodes[store].Blur()
+ }
+ m.Focus.Nodes[m.Focus.Selected].Focus()
+ m.Focus.LastClickWasFocused = true
+ }
+ }
@@ -62,2 +189,0 @@ func (m *Monitor) GetEvents(data *EventData) {
- if eventMap[k] == nil {
- eventMap[k] = []element.Event{}
@@ -64,0 +191 @@ func (m *Monitor) GetEvents(data *EventData) {
+ }
@@ -66,16 +193,12 @@ func (m *Monitor) GetEvents(data *EventData) {
- insideX := (self.X < float32(data.Position[0]) && self.X+self.Width > float32(data.Position[0]))
- insideY := (self.Y < float32(data.Position[1]) && self.Y+self.Height > float32(data.Position[1]))
- inside := (insideX && insideY)
-
- arrowScroll := 0
-
- if isFocused {
- // This allows for arrow scrolling when off the element and typing
- if m.Focus.SoftFocused != nil {
- if data.Key == 265 {
- // up
- arrowScroll += 20
- } else if data.Key == 264 {
- // Down
- arrowScroll -= 20
- }
+ if inside || isFocused {
+ // Mouse is over element
+ isMouseOver = true
+ if !slices.Contains(n.ClassList.Classes, ":hover") {
+ n.ClassList.Add(":hover")
+ }
+
+ if data.Click && !evt.MouseDown {
+ evt.MouseDown = true
+ evt.MouseUp = false
+ if n.OnMouseDown != nil {
+ n.OnMouseDown(evt)
@@ -83,9 +206,9 @@ func (m *Monitor) GetEvents(data *EventData) {
- // Get the keycode of the pressed key
- if data.Key != 0 {
- if self.ContentEditable {
- // Sync the innertext and value but idk
- // !ISSUE: This may not work
- ProcessKeyEvent(self, int(data.Key))
-
- evt.Value = self.Value
- }
+ eventList = append(eventList, "mousedown")
+ }
+
+ if !data.Click && !evt.MouseUp {
+ evt.MouseUp = true
+ evt.MouseDown = false
+ evt.Click = false
+ if n.OnMouseUp != nil {
+ n.OnMouseUp(evt)
@@ -92,0 +216,2 @@ func (m *Monitor) GetEvents(data *EventData) {
+ eventList = append(eventList, "mouseup")
+ }
@@ -94,12 +219,14 @@ func (m *Monitor) GetEvents(data *EventData) {
- if data.Key == 258 && data.KeyState && !m.Focus.LastClickWasFocused {
- // Tab
- mfsLen := len(m.Focus.Nodes)
- if mfsLen > 0 {
- store := m.Focus.Selected
- m.Focus.Selected += 1
- if m.Focus.Selected >= mfsLen {
- m.Focus.Selected = 0
- }
- if store != m.Focus.Selected {
- if store > -1 {
- m.Focus.Nodes[store].Blur()
+ if data.Click && !evt.Click {
+ evt.Click = true
+
+ if n.TabIndex > -1 {
+ if m.Focus.Selected > -1 {
+ if m.Focus.Nodes[m.Focus.Selected].Properties.Id != n.Properties.Id {
+ m.Focus.Nodes[m.Focus.Selected].Blur()
+ for i, v := range m.Focus.Nodes {
+ if v.Properties.Id == n.Properties.Id {
+ m.Focus.Selected = i
+ n.Focus()
+ m.Focus.LastClickWasFocused = true
+ break
+ }
@@ -107 +234 @@ func (m *Monitor) GetEvents(data *EventData) {
- m.Focus.Nodes[m.Focus.Selected].Focus()
+ } else {
@@ -109,0 +237,30 @@ func (m *Monitor) GetEvents(data *EventData) {
+ } else {
+ selectedIndex := -1
+ for i, v := range m.Focus.Nodes {
+ if v.Properties.Id == n.Properties.Id {
+ selectedIndex = i
+ }
+ }
+ if selectedIndex == -1 {
+ if n.TabIndex == 9999999 {
+ // Add the last digits of the properties.id to make the elements sort in order
+ numStr := strings.TrimFunc(n.Properties.Id, func(r rune) bool {
+ return !unicode.IsDigit(r) // Remove non-digit characters
+ })
+ prid, _ := strconv.Atoi(numStr)
+ n.TabIndex += prid
+ }
+ m.Focus.Nodes = append([]*element.Node{n}, m.Focus.Nodes...)
+ sort.Slice(m.Focus.Nodes, func(i, j int) bool {
+ return m.Focus.Nodes[i].TabIndex < m.Focus.Nodes[j].TabIndex // Ascending order by TabIndex
+ })
+ for i, v := range m.Focus.Nodes {
+ if v.Properties.Id == n.Properties.Id {
+ selectedIndex = i
+ }
+ }
+ }
+
+ m.Focus.Selected = selectedIndex
+ n.Focus()
+ m.Focus.LastClickWasFocused = true
@@ -111,0 +269,12 @@ func (m *Monitor) GetEvents(data *EventData) {
+ } else if m.Focus.Selected > -1 {
+ if m.Focus.Nodes[m.Focus.Selected].Properties.Id != n.Properties.Id && !m.Focus.LastClickWasFocused {
+ m.Focus.Nodes[m.Focus.Selected].Blur()
+ m.Focus.Selected = -1
+ }
+ }
+ if n.OnClick != nil {
+ n.OnClick(evt)
+ }
+ // Regardless set soft focus to trigger events to the selected element: when non is set default body???
+ if m.Focus.SoftFocused == nil {
+ m.Focus.SoftFocused = n
@@ -112,0 +282 @@ func (m *Monitor) GetEvents(data *EventData) {
+ eventList = append(eventList, "click")
@@ -115,6 +285,4 @@ func (m *Monitor) GetEvents(data *EventData) {
- if inside || isFocused {
- // Mouse is over element
- isMouseOver = true
-
- if evt.AddClasses == nil {
- evt.AddClasses = []string{}
+ if data.Context {
+ evt.ContextMenu = true
+ if n.OnContextMenu != nil {
+ n.OnContextMenu(evt)
@@ -121,0 +290,2 @@ func (m *Monitor) GetEvents(data *EventData) {
+ eventList = append(eventList, "contextmenu")
+ }
@@ -123 +293,5 @@ func (m *Monitor) GetEvents(data *EventData) {
- evt.AddClasses = append(evt.AddClasses, ":hover")
+ // el.ScrollY = 0
+ if (data.Scroll != 0 && (inside)) || arrowScroll != 0 {
+ // !TODO: for now just emit a event, will have to add el.scrollX
+ data.Scroll += arrowScroll
+ styledEl, _ := m.CSS.GetStyles(n)
@@ -125,4 +299,2 @@ func (m *Monitor) GetEvents(data *EventData) {
- if data.Click && !evt.MouseDown {
- evt.MouseDown = true
- evt.MouseUp = false
- }
+ // !TODO: Add scrolling for dragging over the scroll bar
+ // + the dragging part will be hard as events has no context of the scrollbars
@@ -130,5 +302,5 @@ func (m *Monitor) GetEvents(data *EventData) {
- if !data.Click && !evt.MouseUp {
- evt.MouseUp = true
- evt.MouseDown = false
- evt.Click = false
- }
+ if hasAutoOrScroll(styledEl) {
+ n.ScrollTop = int(n.ScrollTop + (-data.Scroll))
+ if n.ScrollTop > n.ScrollHeight {
+ n.ScrollTop = n.ScrollHeight
+ }
@@ -136,60 +308,3 @@ func (m *Monitor) GetEvents(data *EventData) {
- if data.Click && !evt.Click {
- evt.Click = true
-
- // if n.TabIndex > -1 {
- // if m.Focus.Selected > -1 {
- // if m.Focus.Nodes[m.Focus.Selected].Properties.Id != k {
- // m.Focus.Nodes[m.Focus.Selected].Blur()
- // for i, v := range m.Focus.Nodes {
- // if v.Properties.Id == k {
- // m.Focus.Selected = i
- // m.Focus.LastClickWasFocused = true
- // break
- // }
- // }
- // } else {
- // m.Focus.LastClickWasFocused = true
- // }
- // } else {
- // selectedIndex := -1
- // for i, v := range m.Focus.Nodes {
- // if v.Properties.Id == k {
- // selectedIndex = i
- // }
- // }
- // if selectedIndex == -1 {
- // if n.TabIndex == 9999999 {
- // // Add the last digits of the properties.id to make the elements sort in order
- // numStr := strings.TrimFunc(k, func(r rune) bool {
- // return !unicode.IsDigit(r) // Remove non-digit characters
- // })
- // prid, _ := strconv.Atoi(numStr)
- // n.TabIndex += prid
- // }
- // m.Focus.Nodes = append([]*element.Node{n}, m.Focus.Nodes...)
- // sort.Slice(m.Focus.Nodes, func(i, j int) bool {
- // return m.Focus.Nodes[i].TabIndex < m.Focus.Nodes[j].TabIndex // Ascending order by TabIndex
- // })
- // for i, v := range m.Focus.Nodes {
- // if v.Properties.Id == k {
- // selectedIndex = i
- // }
- // }
- // }
-
- // m.Focus.Selected = selectedIndex
- // m.Focus.LastClickWasFocused = true
- // }
-
- // } else if m.Focus.Selected > -1 {
- // if m.Focus.Nodes[m.Focus.Selected].Properties.Id != k && !m.Focus.LastClickWasFocused {
- // m.Focus.Nodes[m.Focus.Selected].Blur()
- // m.Focus.Selected = -1
- // }
- // }
-
- // Regardless set soft focus to trigger events to the selected element: when non is set default body???
- // if m.Focus.SoftFocused == nil {
- // m.Focus.SoftFocused = n
- // }
- }
+ if n.ScrollTop <= 0 {
+ n.ScrollTop = 0
+ }
@@ -197,3 +312,3 @@ func (m *Monitor) GetEvents(data *EventData) {
- if data.Context {
- evt.ContextMenu = true
- }
+ if n.OnScroll != nil {
+ n.OnScroll(evt)
+ }
@@ -201,39 +316,2 @@ func (m *Monitor) GetEvents(data *EventData) {
- // el.ScrollY = 0
- // if (data.Scroll != 0 && (inside)) || arrowScroll != 0 {
- // // !TODO: for now just emit a event, will have to add el.scrollX
- // data.Scroll += arrowScroll
- // styledEl, _ := m.CSS.GetStyles(n)
-
- // // !TODO: Add scrolling for dragging over the scroll bar
- // // + the dragging part will be hard as events has no context of the scrollbars
-
- // if hasAutoOrScroll(styledEl) {
- // n.ScrollTop = int(n.ScrollTop + (-data.Scroll))
- // if n.ScrollTop > n.ScrollHeight {
- // n.ScrollTop = n.ScrollHeight
- // }
-
- // if n.ScrollTop <= 0 {
- // n.ScrollTop = 0
- // }
-
- // if n.OnScroll != nil {
- // n.OnScroll(evt)
- // }
-
- // data.Scroll = 0
- // eventList = append(eventList, "scroll")
- // }
-
- // }
-
- if !evt.MouseEnter {
- evt.MouseEnter = true
- evt.MouseOver = true
- evt.MouseLeave = false
-
- // Let the adapter know the cursor has changed
- // m.Adapter.DispatchEvent(element.Event{
- // Name: "cursor",
- // Data: self.Cursor,
- // })
+ data.Scroll = 0
+ eventList = append(eventList, "scroll")
@@ -242,3 +320 @@ func (m *Monitor) GetEvents(data *EventData) {
- if evt.X != int(data.Position[0]) && evt.Y != int(data.Position[1]) {
- evt.X = int(data.Position[0])
- evt.Y = int(data.Position[1])
+ }
@@ -245,0 +322,6 @@ func (m *Monitor) GetEvents(data *EventData) {
+ if !evt.MouseEnter {
+ evt.MouseEnter = true
+ evt.MouseOver = true
+ evt.MouseLeave = false
+ if n.OnMouseEnter != nil {
+ n.OnMouseEnter(evt)
@@ -247,4 +329,2 @@ func (m *Monitor) GetEvents(data *EventData) {
- } else {
- isMouseOver = false
- if evt.RemoveClasses == nil {
- evt.RemoveClasses = []string{}
+ if n.OnMouseOver != nil {
+ n.OnMouseEnter(evt)
@@ -251,0 +332,9 @@ func (m *Monitor) GetEvents(data *EventData) {
+ eventList = append(eventList, "mouseenter")
+ eventList = append(eventList, "mouseover")
+
+ // Let the adapter know the cursor has changed
+ m.Adapter.DispatchEvent(element.Event{
+ Name: "cursor",
+ Data: self.Cursor,
+ })
+ }
@@ -253 +342,7 @@ func (m *Monitor) GetEvents(data *EventData) {
- evt.RemoveClasses = append(evt.RemoveClasses, ":hover")
+ if evt.X != int(data.Position[0]) && evt.Y != int(data.Position[1]) {
+ evt.X = int(data.Position[0])
+ evt.Y = int(data.Position[1])
+ if n.OnMouseMove != nil {
+ n.OnMouseMove(evt)
+ }
+ eventList = append(eventList, "mousemove")
@@ -254,0 +350,6 @@ func (m *Monitor) GetEvents(data *EventData) {
+ } else {
+ isMouseOver = false
+ if slices.Contains(n.ClassList.Classes, ":hover") {
+ n.ClassList.Remove(":hover")
+ }
+ }
@@ -256,5 +357,9 @@ func (m *Monitor) GetEvents(data *EventData) {
- if !isMouseOver && !evt.MouseLeave {
- evt.MouseEnter = false
- evt.MouseOver = false
- evt.MouseLeave = true
- // n.Properties.Hover = false
+ // fmt.Println(isMouseOver)
+
+ if !isMouseOver && !evt.MouseLeave {
+ evt.MouseEnter = false
+ evt.MouseOver = false
+ evt.MouseLeave = true
+ n.Properties.Hover = false
+ if n.OnMouseLeave != nil {
+ n.OnMouseLeave(evt)
@@ -261,0 +367,2 @@ func (m *Monitor) GetEvents(data *EventData) {
+ eventList = append(eventList, "mouseleave")
+ }
@@ -263 +370,2 @@ func (m *Monitor) GetEvents(data *EventData) {
- eventMap[k] = append(eventMap[k], evt)
+ if len(n.Properties.Events) > 0 {
+ eventList = append(eventList, n.Properties.Events...)
@@ -266 +374,4 @@ func (m *Monitor) GetEvents(data *EventData) {
- fmt.Println(eventMap["ROOT"])
+ (*m.History)[n.Properties.Id] = element.EventList{
+ Event: evt,
+ List: eventList,
+ }
@@ -270 +381 @@ func (m *Monitor) GetEvents(data *EventData) {
-func ProcessKeyEvent(self element.State, key int) {
+func ProcessKeyEvent(n *element.Node, key int) {
@@ -271,0 +383 @@ func ProcessKeyEvent(self element.State, key int) {
+ fmt.Println(key)
@@ -275,3 +387,3 @@ func ProcessKeyEvent(self element.State, key int) {
- if len(self.Value) > 0 {
- self.Value = self.Value[:len(self.Value)-1]
- // n.InnerText = n.InnerText[:len(n.InnerText)-1]
+ if len(n.Value) > 0 {
+ n.Value = n.Value[:len(n.Value)-1]
+ n.InnerText = n.InnerText[:len(n.InnerText)-1]
@@ -281,8 +393,7 @@ func ProcessKeyEvent(self element.State, key int) {
- // !TODO: ctrl a
- // // Select All: set the entire text as selected
- // if key == 17 || key == 345 {
- // n.Properties.Selected = []float32{0, float32(len(n.Value))}
- // } else {
- // // Otherwise, append 'A' to the text
- // n.Value += "A"
- // }
+ // Select All: set the entire text as selected
+ if key == 17 || key == 345 {
+ n.Properties.Selected = []float32{0, float32(len(n.Value))}
+ } else {
+ // Otherwise, append 'A' to the text
+ n.Value += "A"
+ }
@@ -292,6 +403,6 @@ func ProcessKeyEvent(self element.State, key int) {
- // if key == 17 || key == 345 {
- // fmt.Println("Copy:", n.Value)
- // } else {
- // // Otherwise, append 'C' to the text
- // n.Value += "C"
- // }
+ if key == 17 || key == 345 {
+ fmt.Println("Copy:", n.Value)
+ } else {
+ // Otherwise, append 'C' to the text
+ n.Value += "C"
+ }
@@ -301,6 +412,6 @@ func ProcessKeyEvent(self element.State, key int) {
- // if key == 17 || key == 345 {
- // n.Value = "Pasted"
- // } else {
- // // Otherwise, append 'V' to the text
- // n.Value += "V"
- // }
+ if key == 17 || key == 345 {
+ n.Value = "Pasted"
+ } else {
+ // Otherwise, append 'V' to the text
+ n.Value += "V"
+ }
@@ -310 +421 @@ func ProcessKeyEvent(self element.State, key int) {
- self.Value += string(rune(key))
+ n.Value += string(rune(key))