Diff
diff --git a/docs/document/index.html b/docs/document/index.html
index 7c58c00..b9f7103 100644
--- a/docs/document/index.html
+++ b/docs/document/index.html
@@ -34,0 +35,10 @@
+# CreateElement?(go)
+# parse?(go)
+
+
+# localizePath?(go)
+# encapsulateText?(go)
+# matchFactory?(go)
+# removeWhitespace?(go)
+
+# check?(go)
@@ -38,29 +48,29 @@
- 4 "gui/cstyle"
- 5 "gui/element"
- 6 "gui/events"
- 7 "gui/window"
- 8
- 9 "gui/cstyle/plugins/block"
- 10 "gui/cstyle/plugins/flex"
- 11 "gui/cstyle/plugins/inline"
- 12
- 13 rl "github.com/gen2brain/raylib-go/raylib"
- 14 "golang.org/x/net/html"
- 15)
- 16
- 17type Window struct {
- 18 StyleSheets []string
- 19 StyleTags []string
- 20 DOM *html.Node
- 21 Title string
- 22}
- 23
- 24type Document struct {
- 25 CSS cstyle.CSS
- 26}
- 27
- 28func (doc Document) Open(index string, script func(*element.Node)) {
- 29 d := parse(index)
- 30
- 31 wm := window.NewWindowManager()
- 32 wm.FPS = true
+ 4 "bufio"
+ 5 "gui/cstyle"
+ 6 "gui/element"
+ 7 "gui/events"
+ 8 "gui/window"
+ 9 "net/url"
+ 10 "os"
+ 11 "path/filepath"
+ 12 "regexp"
+ 13 "strings"
+ 14
+ 15 "gui/cstyle/plugins/block"
+ 16 "gui/cstyle/plugins/flex"
+ 17 "gui/cstyle/plugins/inline"
+ 18
+ 19 rl "github.com/gen2brain/raylib-go/raylib"
+ 20 "golang.org/x/net/html"
+ 21)
+ 22
+ 23type Window struct {
+ 24 StyleSheets []string
+ 25 StyleTags []string
+ 26 DOM *html.Node
+ 27 Title string
+ 28}
+ 29
+ 30type Document struct {
+ 31 CSS cstyle.CSS
+ 32}
@@ -68,34 +78,34 @@
- 34 // Initialization
- 35 var screenWidth int32 = 800
- 36 var screenHeight int32 = 450
- 37
- 38 // Open the window
- 39 wm.OpenWindow(screenWidth, screenHeight)
- 40 defer wm.CloseWindow()
- 41
- 42 doc.CSS = cstyle.CSS{
- 43 Width: 800,
- 44 Height: 450,
- 45 }
- 46 doc.CSS.StyleSheet("./master.css")
- 47 // css.AddPlugin(position.Init())
- 48 doc.CSS.AddPlugin(inline.Init())
- 49 doc.CSS.AddPlugin(block.Init())
- 50 doc.CSS.AddPlugin(flex.Init())
- 51
- 52 for _, v := range d.StyleSheets {
- 53 doc.CSS.StyleSheet(v)
- 54 }
- 55
- 56 for _, v := range d.StyleTags {
- 57 doc.CSS.StyleTag(v)
- 58 }
- 59
- 60 nodes := doc.CSS.CreateDocument(d.DOM)
- 61 root := &nodes
- 62
- 63 script(root)
- 64
- 65 // fmt.Println(nodes.Style)
- 66
- 67 evts := map[string]element.EventList{}
+ 34func (doc Document) Open(index string, script func(*element.Node)) {
+ 35 d := parse(index)
+ 36
+ 37 wm := window.NewWindowManager()
+ 38 wm.FPS = true
+ 39
+ 40 // Initialization
+ 41 var screenWidth int32 = 800
+ 42 var screenHeight int32 = 450
+ 43
+ 44 // Open the window
+ 45 wm.OpenWindow(screenWidth, screenHeight)
+ 46 defer wm.CloseWindow()
+ 47
+ 48 doc.CSS = cstyle.CSS{
+ 49 Width: 800,
+ 50 Height: 450,
+ 51 }
+ 52 doc.CSS.StyleSheet("./master.css")
+ 53 // css.AddPlugin(position.Init())
+ 54 doc.CSS.AddPlugin(inline.Init())
+ 55 doc.CSS.AddPlugin(block.Init())
+ 56 doc.CSS.AddPlugin(flex.Init())
+ 57
+ 58 for _, v := range d.StyleSheets {
+ 59 doc.CSS.StyleSheet(v)
+ 60 }
+ 61
+ 62 for _, v := range d.StyleTags {
+ 63 doc.CSS.StyleTag(v)
+ 64 }
+ 65
+ 66 nodes := doc.CSS.CreateDocument(d.DOM)
+ 67 root := &nodes
@@ -103 +113 @@
- 69 eventStore := &evts
+ 69 script(root)
@@ -105,3 +115,3 @@
- 71 // Main game loop
- 72 for !wm.WindowShouldClose() {
- 73 rl.BeginDrawing()
+ 71 // fmt.Println(nodes.Style)
+ 72
+ 73 evts := map[string]element.EventList{}
@@ -109,9 +119,9 @@
- 75 // Check if the window size has changed
- 76 newWidth := int32(rl.GetScreenWidth())
- 77 newHeight := int32(rl.GetScreenHeight())
- 78
- 79 if newWidth != screenWidth || newHeight != screenHeight {
- 80 rl.ClearBackground(rl.RayWhite)
- 81 // Window has been resized, handle the event
- 82 screenWidth = newWidth
- 83 screenHeight = newHeight
+ 75 eventStore := &evts
+ 76
+ 77 // Main game loop
+ 78 for !wm.WindowShouldClose() {
+ 79 rl.BeginDrawing()
+ 80
+ 81 // Check if the window size has changed
+ 82 newWidth := int32(rl.GetScreenWidth())
+ 83 newHeight := int32(rl.GetScreenHeight())
@@ -119,13 +129,13 @@
- 85 doc.CSS.Width = float32(screenWidth)
- 86 doc.CSS.Height = float32(screenHeight)
- 87
- 88 nodes = doc.CSS.CreateDocument(d.DOM)
- 89 root = &nodes
- 90 script(root)
- 91 }
- 92
- 93 eventStore = events.GetEvents(root, eventStore)
- 94 doc.CSS.ComputeNodeStyle(root)
- 95 rd := doc.CSS.Render(*root)
- 96 wm.LoadTextures(rd)
- 97 wm.Draw(rd)
+ 85 if newWidth != screenWidth || newHeight != screenHeight {
+ 86 rl.ClearBackground(rl.RayWhite)
+ 87 // Window has been resized, handle the event
+ 88 screenWidth = newWidth
+ 89 screenHeight = newHeight
+ 90
+ 91 doc.CSS.Width = float32(screenWidth)
+ 92 doc.CSS.Height = float32(screenHeight)
+ 93
+ 94 nodes = doc.CSS.CreateDocument(d.DOM)
+ 95 root = &nodes
+ 96 script(root)
+ 97 }
@@ -133,5 +143,172 @@
- 99 events.RunEvents(eventStore)
-100
-101 rl.EndDrawing()
-102 }
-103}
+ 99 eventStore = events.GetEvents(root, eventStore)
+100 doc.CSS.ComputeNodeStyle(root)
+101 rd := doc.CSS.Render(*root)
+102 wm.LoadTextures(rd)
+103 wm.Draw(rd)
+104
+105 events.RunEvents(eventStore)
+106
+107 rl.EndDrawing()
+108 }
+109}
+110
+111// func (doc Document) CreateElement(t string) element.Node {
+112// n := element.Node{TagName: t, Properties: element.Properties{Node: &html.Node{}}}
+113// cstyle.InitNode(&n, doc.CSS)
+114// return n
+115// }
+116
+117func parse(path string) Window {
+118 file, err := os.Open(path)
+119 check(err)
+120 defer file.Close()
+121
+122 scanner := bufio.NewScanner(file)
+123 var htmlContent string
+124
+125 for scanner.Scan() {
+126 htmlContent += scanner.Text() + "\n"
+127 }
+128
+129 check(scanner.Err())
+130 // println(encapsulateText(htmlContent))
+131 doc, err := html.Parse(strings.NewReader(encapsulateText(htmlContent)))
+132 check(err)
+133
+134 // Extract stylesheet link tags and style tags
+135 stylesheets := extractStylesheets(doc, filepath.Dir(path))
+136 styleTags := extractStyleTags(doc)
+137
+138 d := Window{
+139 StyleSheets: stylesheets,
+140 StyleTags: styleTags,
+141 DOM: doc,
+142 }
+143
+144 return d
+145}
+146
+147func extractStylesheets(n *html.Node, baseDir string) []string {
+148 var stylesheets []string
+149
+150 var dfs func(*html.Node)
+151 dfs = func(node *html.Node) {
+152 if node.Type == html.ElementNode && node.Data == "link" {
+153 var href string
+154 isStylesheet := false
+155
+156 for _, attr := range node.Attr {
+157 if attr.Key == "rel" && attr.Val == "stylesheet" {
+158 isStylesheet = true
+159 } else if attr.Key == "href" {
+160 href = attr.Val
+161 }
+162 }
+163
+164 if isStylesheet {
+165 resolvedHref := localizePath(baseDir, href)
+166 stylesheets = append(stylesheets, resolvedHref)
+167 }
+168 }
+169
+170 for c := node.FirstChild; c != nil; c = c.NextSibling {
+171 dfs(c)
+172 }
+173 }
+174
+175 dfs(n)
+176 return stylesheets
+177}
+178
+179func extractStyleTags(n *html.Node) []string {
+180 var styleTags []string
+181
+182 var dfs func(*html.Node)
+183 dfs = func(node *html.Node) {
+184 if node.Type == html.ElementNode && node.Data == "style" {
+185 var styleContent strings.Builder
+186 for c := node.FirstChild; c != nil; c = c.NextSibling {
+187 if c.Type == html.TextNode {
+188 styleContent.WriteString(c.Data)
+189 }
+190 }
+191 styleTags = append(styleTags, styleContent.String())
+192 }
+193
+194 for c := node.FirstChild; c != nil; c = c.NextSibling {
+195 dfs(c)
+196 }
+197 }
+198
+199 dfs(n)
+200 return styleTags
+201}
+202
+203func localizePath(rootPath, filePath string) string {
+204 // Check if the file path has a scheme, indicating it's a URL
+205 u, err := url.Parse(filePath)
+206 if err == nil && u.Scheme != "" {
+207 return filePath
+208 }
+209
+210 // Join the root path and the file path to create an absolute path
+211 absPath := filepath.Join(rootPath, filePath)
+212
+213 // If the absolute path is the same as the original path, return it
+214 if absPath == filePath {
+215 return filePath
+216 }
+217
+218 return "./" + absPath
+219}
+220
+221func encapsulateText(htmlString string) string {
+222 htmlString = removeHTMLComments(htmlString)
+223 openOpen := regexp.MustCompile(`(<\w+[^>]*>)([^<]+)(<\w+[^>]*>)`)
+224 closeOpen := regexp.MustCompile(`(</\w+[^>]*>)([^<]+)(<\w+[^>]*>)`)
+225 closeClose := regexp.MustCompile(`(</\w+[^>]*>)([^<]+)(</\w+[^>]*>)`)
+226 a := matchFactory(openOpen)
+227 t := openOpen.ReplaceAllStringFunc(htmlString, a)
+228 b := matchFactory(closeOpen)
+229 u := closeOpen.ReplaceAllStringFunc(t, b)
+230 c := matchFactory(closeClose)
+231 v := closeClose.ReplaceAllStringFunc(u, c)
+232 return v
+233}
+234
+235func matchFactory(re *regexp.Regexp) func(string) string {
+236 return func(match string) string {
+237 submatches := re.FindStringSubmatch(match)
+238 if len(submatches) != 4 {
+239 return match
+240 }
+241
+242 // Process submatches
+243 if len(removeWhitespace(submatches[2])) > 0 {
+244 return submatches[1] + "<notaspan>" + submatches[2] + "</notaspan>" + submatches[3]
+245 } else {
+246 return match
+247 }
+248 }
+249}
+250func removeWhitespace(htmlString string) string {
+251 // Remove extra white space
+252 reSpaces := regexp.MustCompile(`\s+`)
+253 htmlString = reSpaces.ReplaceAllString(htmlString, " ")
+254
+255 // Trim leading and trailing white space
+256 htmlString = strings.TrimSpace(htmlString)
+257
+258 return htmlString
+259}
+260
+261func removeHTMLComments(htmlString string) string {
+262 re := regexp.MustCompile(`<!--(.*?)-->`)
+263 return re.ReplaceAllString(htmlString, "")
+264}
+265
+266func check(e error) {
+267 if e != nil {
+268 panic(e)
+269 }
+270}