Diff
diff --git a/docs/cstyle/index.html b/docs/cstyle/index.html
index cf20576..480af84 100644
--- a/docs/cstyle/index.html
+++ b/docs/cstyle/index.html
@@ -68 +68 @@ The utils.ChildrenHaveText function is called here instead of checking if the no
- 27 Handler func(element.Node, *CSS) element.Node
+ 27 Handler func(element.Node) element.Node
@@ -81,10 +81,10 @@ The utils.ChildrenHaveText function is called here instead of checking if the no
- 40 for _, v := range c.Transformers {
- 41 if v.Selector(&n) {
- 42 n = v.Handler(n, c)
- 43 }
- 44 }
- 45 for i := 0; i < len(n.Children); i++ {
- 46 v := n.Children[i]
- 47 tc := c.Transform(v)
- 48 n = *tc.Parent
- 49 n.Children[i] = tc
+ 40 fmt.Println("########")
+ 41 fmt.Println(n.TagName)
+ 42 // for i := 0; i < len(n.Children); i++ {
+ 43 // v := n.Children[i]
+ 44 // fmt.Println(v.TagName)
+ 45 // }
+ 46 for i := 0; i < len(n.Children); i++ {
+ 47 v := n.Children[i]
+ 48 fmt.Println(v.TagName)
+ 49 n.Children[i] = c.Transform(v)
@@ -92,15 +92,15 @@ The utils.ChildrenHaveText function is called here instead of checking if the no
- 51
- 52 return n
- 53}
- 54
- 55func (c *CSS) StyleSheet(path string) {
- 56 // Parse the CSS file
- 57 dat, err := os.ReadFile(path)
- 58 utils.Check(err)
- 59 styles := parser.ParseCSS(string(dat))
- 60
- 61 c.StyleSheets = append(c.StyleSheets, styles)
- 62}
- 63
- 64func (c *CSS) StyleTag(css string) {
- 65 styles := parser.ParseCSS(css)
+ 51 for _, v := range c.Transformers {
+ 52 if v.Selector(&n) {
+ 53 n = v.Handler(n)
+ 54 }
+ 55 }
+ 56
+ 57 return n
+ 58}
+ 59
+ 60func (c *CSS) StyleSheet(path string) {
+ 61 // Parse the CSS file
+ 62 dat, err := os.ReadFile(path)
+ 63 utils.Check(err)
+ 64 styles := parser.ParseCSS(string(dat))
+ 65
@@ -110,51 +110,51 @@ The utils.ChildrenHaveText function is called here instead of checking if the no
- 69var inheritedProps = []string{
- 70 "color",
- 71 "cursor",
- 72 "font",
- 73 "font-family",
- 74 "font-size",
- 75 "font-style",
- 76 "font-weight",
- 77 "letter-spacing",
- 78 "line-height",
- 79 // "text-align",
- 80 "text-indent",
- 81 "text-justify",
- 82 "text-shadow",
- 83 "text-transform",
- 84 "text-decoration",
- 85 "visibility",
- 86 "word-spacing",
- 87 "display",
- 88}
- 89
- 90func (c *CSS) GetStyles(n element.Node) map[string]string {
- 91 styles := map[string]string{}
- 92
- 93 if n.Parent != nil {
- 94 ps := c.GetStyles(*n.Parent)
- 95 for _, v := range inheritedProps {
- 96 if ps[v] != "" {
- 97 styles[v] = ps[v]
- 98 }
- 99 }
-100 }
-101 for k, v := range n.Style {
-102 styles[k] = v
-103 }
-104 hovered := false
-105 if slices.Contains(n.ClassList.Classes, ":hover") {
-106 hovered = true
-107 }
-108
-109 for _, styleSheet := range c.StyleSheets {
-110 for selector := range styleSheet {
-111 // fmt.Println(selector, n.Properties.Id)
-112 key := selector
-113 if strings.Contains(selector, ":hover") && hovered {
-114 selector = strings.Replace(selector, ":hover", "", -1)
-115 }
-116 if element.TestSelector(selector, &n) {
-117 for k, v := range styleSheet[key] {
-118 styles[k] = v
-119 }
+ 69func (c *CSS) StyleTag(css string) {
+ 70 styles := parser.ParseCSS(css)
+ 71 c.StyleSheets = append(c.StyleSheets, styles)
+ 72}
+ 73
+ 74var inheritedProps = []string{
+ 75 "color",
+ 76 "cursor",
+ 77 "font",
+ 78 "font-family",
+ 79 "font-size",
+ 80 "font-style",
+ 81 "font-weight",
+ 82 "letter-spacing",
+ 83 "line-height",
+ 84 // "text-align",
+ 85 "text-indent",
+ 86 "text-justify",
+ 87 "text-shadow",
+ 88 "text-transform",
+ 89 "text-decoration",
+ 90 "visibility",
+ 91 "word-spacing",
+ 92 "display",
+ 93}
+ 94
+ 95func (c *CSS) GetStyles(n element.Node) map[string]string {
+ 96 styles := map[string]string{}
+ 97
+ 98 if n.Parent != nil {
+ 99 ps := c.GetStyles(*n.Parent)
+100 for _, v := range inheritedProps {
+101 if ps[v] != "" {
+102 styles[v] = ps[v]
+103 }
+104 }
+105 }
+106 for k, v := range n.Style {
+107 styles[k] = v
+108 }
+109 hovered := false
+110 if slices.Contains(n.ClassList.Classes, ":hover") {
+111 hovered = true
+112 }
+113
+114 for _, styleSheet := range c.StyleSheets {
+115 for selector := range styleSheet {
+116 // fmt.Println(selector, n.Properties.Id)
+117 key := selector
+118 if strings.Contains(selector, ":hover") && hovered {
+119 selector = strings.Replace(selector, ":hover", "", -1)
@@ -162,54 +162,54 @@ The utils.ChildrenHaveText function is called here instead of checking if the no
-121
-122 }
-123 }
-124
-125 // This is different than node.Style
-126 // temp1 = <span style=​"color:​#a6e22e">​CSS​</span>​
-127 // temp1.style == CSSStyleDeclaration {0: 'color', accentColor: '', additiveSymbols: '', alignContent: '', alignItems: '', alignSelf: '', …}
-128 // temp1.getAttribute("style") == 'color:#a6e22e'
-129 inline := parser.ParseStyleAttribute(n.GetAttribute("style") + ";")
-130 styles = utils.Merge(styles, inline)
-131 // add hover and focus css events
-132
-133 if n.Parent != nil {
-134 if styles["z-index"] == "" && n.Parent.Style["z-index"] != "" {
-135 z, _ := strconv.Atoi(n.Parent.Style["z-index"])
-136 z += 1
-137 styles["z-index"] = strconv.Itoa(z)
-138 }
-139 }
-140
-141 return styles
-142}
-143
-144func (c *CSS) AddPlugin(plugin Plugin) {
-145 c.Plugins = append(c.Plugins, plugin)
-146}
-147
-148func (c *CSS) AddTransformer(transformer Transformer) {
-149 c.Transformers = append(c.Transformers, transformer)
-150}
-151
-152func CheckNode(n *element.Node, state *map[string]element.State) {
-153 s := *state
-154 self := s[n.Properties.Id]
-155
-156 fmt.Println(n.TagName, n.Properties.Id)
-157 fmt.Printf("ID: %v\n", n.Id)
-158 fmt.Printf("EM: %v\n", self.EM)
-159 fmt.Printf("Parent: %v\n", n.Parent.TagName)
-160 fmt.Printf("Classes: %v\n", n.ClassList.Classes)
-161 fmt.Printf("Text: %v\n", n.InnerText)
-162 fmt.Printf("X: %v, Y: %v, Z: %v\n", self.X, self.Y, self.Z)
-163 fmt.Printf("Width: %v, Height: %v\n", self.Width, self.Height)
-164 fmt.Printf("Styles: %v\n", n.Style)
-165 fmt.Printf("Background: %v\n", self.Background)
-166 fmt.Printf("Border: %v\n\n\n", self.Border)
-167}
-168
-169func (c *CSS) ComputeNodeStyle(n *element.Node, state *map[string]element.State) *element.Node {
-170
-171 // Head is not renderable
-172 if utils.IsParent(*n, "head") {
-173 return n
-174 }
+121 if element.TestSelector(selector, &n) {
+122 for k, v := range styleSheet[key] {
+123 styles[k] = v
+124 }
+125 }
+126
+127 }
+128 }
+129
+130 // This is different than node.Style
+131 // temp1 = <span style=​"color:​#a6e22e">​CSS​</span>​
+132 // temp1.style == CSSStyleDeclaration {0: 'color', accentColor: '', additiveSymbols: '', alignContent: '', alignItems: '', alignSelf: '', …}
+133 // temp1.getAttribute("style") == 'color:#a6e22e'
+134 inline := parser.ParseStyleAttribute(n.GetAttribute("style") + ";")
+135 styles = utils.Merge(styles, inline)
+136 // add hover and focus css events
+137
+138 if n.Parent != nil {
+139 if styles["z-index"] == "" && n.Parent.Style["z-index"] != "" {
+140 z, _ := strconv.Atoi(n.Parent.Style["z-index"])
+141 z += 1
+142 styles["z-index"] = strconv.Itoa(z)
+143 }
+144 }
+145
+146 return styles
+147}
+148
+149func (c *CSS) AddPlugin(plugin Plugin) {
+150 c.Plugins = append(c.Plugins, plugin)
+151}
+152
+153func (c *CSS) AddTransformer(transformer Transformer) {
+154 c.Transformers = append(c.Transformers, transformer)
+155}
+156
+157func CheckNode(n *element.Node, state *map[string]element.State) {
+158 s := *state
+159 self := s[n.Properties.Id]
+160
+161 fmt.Println(n.TagName, n.Properties.Id)
+162 fmt.Printf("ID: %v\n", n.Id)
+163 fmt.Printf("EM: %v\n", self.EM)
+164 fmt.Printf("Parent: %v\n", n.Parent.TagName)
+165 fmt.Printf("Classes: %v\n", n.ClassList.Classes)
+166 fmt.Printf("Text: %v\n", n.InnerText)
+167 fmt.Printf("X: %v, Y: %v, Z: %v\n", self.X, self.Y, self.Z)
+168 fmt.Printf("Width: %v, Height: %v\n", self.Width, self.Height)
+169 fmt.Printf("Styles: %v\n", self.Style)
+170 fmt.Printf("Background: %v\n", self.Background)
+171 fmt.Printf("Border: %v\n\n\n", self.Border)
+172}
+173
+174func (c *CSS) ComputeNodeStyle(n *element.Node, state *map[string]element.State) *element.Node {
@@ -217,11 +217,11 @@ The utils.ChildrenHaveText function is called here instead of checking if the no
-176 plugins := c.Plugins
-177
-178 s := *state
-179 self := s[n.Properties.Id]
-180 parent := s[n.Parent.Properties.Id]
-181
-182 self.Background = color.Parse(n.Style, "background")
-183 self.Border, _ = CompleteBorder(n.Style, self, parent)
-184
-185 fs, _ := utils.ConvertToPixels(n.Style["font-size"], parent.EM, parent.Width)
-186 self.EM = fs
+176 // Head is not renderable
+177 if utils.IsParent(*n, "head") {
+178 return n
+179 }
+180
+181 plugins := c.Plugins
+182
+183 s := *state
+184 self := s[n.Properties.Id]
+185 parent := s[n.Parent.Properties.Id]
+186 self.Style = c.GetStyles(*n)
@@ -229,16 +229,16 @@ The utils.ChildrenHaveText function is called here instead of checking if the no
-188 if n.Style["display"] == "none" {
-189 self.X = 0
-190 self.Y = 0
-191 self.Width = 0
-192 self.Height = 0
-193 return n
-194 }
-195
-196 if n.Style["width"] == "" && n.Style["display"] == "block" {
-197 n.Style["width"] = "100%"
-198 }
-199
-200 // Set Z index value to be sorted in window
-201 if n.Style["z-index"] != "" {
-202 z, _ := strconv.Atoi(n.Style["z-index"])
-203 self.Z = float32(z)
+188 self.Background = color.Parse(self.Style, "background")
+189 self.Border, _ = CompleteBorder(self.Style, self, parent)
+190
+191 fs, _ := utils.ConvertToPixels(self.Style["font-size"], parent.EM, parent.Width)
+192 self.EM = fs
+193
+194 if self.Style["display"] == "none" {
+195 self.X = 0
+196 self.Y = 0
+197 self.Width = 0
+198 self.Height = 0
+199 return n
+200 }
+201
+202 if self.Style["width"] == "" && self.Style["display"] == "block" {
+203 self.Style["width"] = "100%"
@@ -247,5 +247,5 @@ The utils.ChildrenHaveText function is called here instead of checking if the no
-206 if parent.Z > 0 {
-207 self.Z = parent.Z + 1
-208 }
-209
-210 (*state)[n.Properties.Id] = self
+206 // Set Z index value to be sorted in window
+207 if self.Style["z-index"] != "" {
+208 z, _ := strconv.Atoi(self.Style["z-index"])
+209 self.Z = float32(z)
+210 }
@@ -253,3 +253,3 @@ The utils.ChildrenHaveText function is called here instead of checking if the no
-212 wh := utils.GetWH(*n, state)
-213 width := wh.Width
-214 height := wh.Height
+212 if parent.Z > 0 {
+213 self.Z = parent.Z + 1
+214 }
@@ -257,5 +257,5 @@ The utils.ChildrenHaveText function is called here instead of checking if the no
-216 x, y := parent.X, parent.Y
-217 // !NOTE: Would like to consolidate all XY function into this function like WH
-218 offsetX, offsetY := utils.GetXY(n, state)
-219 x += offsetX
-220 y += offsetY
+216 (*state)[n.Properties.Id] = self
+217
+218 wh := utils.GetWH(*n, state)
+219 width := wh.Width
+220 height := wh.Height
@@ -263,7 +263,7 @@ The utils.ChildrenHaveText function is called here instead of checking if the no
-222 var top, left, right, bottom bool = false, false, false, false
-223
-224 m := utils.GetMP(*n, wh, state, "margin")
-225 p := utils.GetMP(*n, wh, state, "padding")
-226
-227 self.Margin = m
-228 self.Padding = p
+222 x, y := parent.X, parent.Y
+223 // !NOTE: Would like to consolidate all XY function into this function like WH
+224 offsetX, offsetY := utils.GetXY(n, state)
+225 x += offsetX
+226 y += offsetY
+227
+228 var top, left, right, bottom bool = false, false, false, false
@@ -271,109 +271,109 @@ The utils.ChildrenHaveText function is called here instead of checking if the no
-230 if n.Style["position"] == "absolute" {
-231 bas := utils.GetPositionOffsetNode(n)
-232 base := s[bas.Properties.Id]
-233 if n.Style["top"] != "" {
-234 v, _ := utils.ConvertToPixels(n.Style["top"], self.EM, parent.Width)
-235 y = v + base.Y
-236 top = true
-237 }
-238 if n.Style["left"] != "" {
-239 v, _ := utils.ConvertToPixels(n.Style["left"], self.EM, parent.Width)
-240 x = v + base.X
-241 left = true
-242 }
-243 if n.Style["right"] != "" {
-244 v, _ := utils.ConvertToPixels(n.Style["right"], self.EM, parent.Width)
-245 x = (base.Width - width) - v
-246 right = true
-247 }
-248 if n.Style["bottom"] != "" {
-249 v, _ := utils.ConvertToPixels(n.Style["bottom"], self.EM, parent.Width)
-250 y = (base.Height - height) - v
-251 bottom = true
-252 }
-253
-254 } else {
-255 for i, v := range n.Parent.Children {
-256 if v.Style["position"] != "absolute" {
-257 if v.Properties.Id == n.Properties.Id {
-258 if i-1 > 0 {
-259 sib := n.Parent.Children[i-1]
-260 sibling := s[sib.Properties.Id]
-261 if sib.Style["position"] != "absolute" {
-262 if n.Style["display"] == "inline" {
-263 if sib.Style["display"] == "inline" {
-264 y = sibling.Y
-265 } else {
-266 y = sibling.Y + sibling.Height
-267 }
-268 } else {
-269 y = sibling.Y + sibling.Height + (sibling.Border.Width * 2) + sibling.Margin.Bottom
-270 }
-271 }
-272
-273 }
-274 break
-275 } else if n.Style["display"] != "inline" {
-276 vState := s[v.Properties.Id]
-277 y += vState.Margin.Top + vState.Margin.Bottom + vState.Padding.Top + vState.Padding.Bottom + vState.Height + (self.Border.Width)
-278 }
-279 }
-280 }
-281 }
-282
-283 // Display modes need to be calculated here
-284
-285 relPos := !top && !left && !right && !bottom
-286
-287 if left || relPos {
-288 x += m.Left
-289 }
-290 if top || relPos {
-291 y += m.Top
-292 }
-293 if right {
-294 x -= m.Right
-295 }
-296 if bottom {
-297 y -= m.Bottom
-298 }
-299
-300 self.X = x
-301 self.Y = y
-302 self.Width = width
-303 self.Height = height
-304 (*state)[n.Properties.Id] = self
-305
-306 if !utils.ChildrenHaveText(n) && len(n.InnerText) > 0 {
-307 // Confirm text exists
-308 if len(strings.TrimSpace(n.InnerText)) > 0 {
-309 n.InnerText = strings.TrimSpace(n.InnerText)
-310 self = genTextNode(n, state)
-311 }
-312 }
-313
-314 (*state)[n.Properties.Id] = self
-315 (*state)[n.Parent.Properties.Id] = parent
-316
-317 // Call children here
-318
-319 var childYOffset float32
-320 for i := 0; i < len(n.Children); i++ {
-321 v := n.Children[i]
-322 v.Parent = n
-323 // This is were the tainting comes from
-324 n.Children[i] = *c.ComputeNodeStyle(&v, state)
-325
-326 cState := (*state)[n.Children[i].Properties.Id]
-327 if n.Style["height"] == "" {
-328 if v.Style["position"] != "absolute" && cState.Y+cState.Height > childYOffset {
-329 childYOffset = cState.Y + cState.Height
-330 self.Height = (cState.Y - self.Border.Width) - (self.Y) + cState.Height
-331 self.Height += cState.Margin.Top
-332 self.Height += cState.Margin.Bottom
-333 self.Height += cState.Padding.Top
-334 self.Height += cState.Padding.Bottom
-335 }
-336 }
-337 if cState.Width > self.Width {
-338 self.Width = cState.Width
+230 m := utils.GetMP(*n, wh, state, "margin")
+231 p := utils.GetMP(*n, wh, state, "padding")
+232
+233 self.Margin = m
+234 self.Padding = p
+235
+236 if self.Style["position"] == "absolute" {
+237 bas := utils.GetPositionOffsetNode(n, state)
+238 base := s[bas.Properties.Id]
+239 if self.Style["top"] != "" {
+240 v, _ := utils.ConvertToPixels(self.Style["top"], self.EM, parent.Width)
+241 y = v + base.Y
+242 top = true
+243 }
+244 if self.Style["left"] != "" {
+245 v, _ := utils.ConvertToPixels(self.Style["left"], self.EM, parent.Width)
+246 x = v + base.X
+247 left = true
+248 }
+249 if self.Style["right"] != "" {
+250 v, _ := utils.ConvertToPixels(self.Style["right"], self.EM, parent.Width)
+251 x = (base.Width - width) - v
+252 right = true
+253 }
+254 if self.Style["bottom"] != "" {
+255 v, _ := utils.ConvertToPixels(self.Style["bottom"], self.EM, parent.Width)
+256 y = (base.Height - height) - v
+257 bottom = true
+258 }
+259
+260 } else {
+261 for i, v := range n.Parent.Children {
+262 vState := s[v.Properties.Id]
+263 if vState.Style["position"] != "absolute" {
+264 if v.Properties.Id == n.Properties.Id {
+265 if i-1 > 0 {
+266 sib := n.Parent.Children[i-1]
+267 sibling := s[sib.Properties.Id]
+268 if sibling.Style["position"] != "absolute" {
+269 if self.Style["display"] == "inline" {
+270 if sibling.Style["display"] == "inline" {
+271 y = sibling.Y
+272 } else {
+273 y = sibling.Y + sibling.Height
+274 }
+275 } else {
+276 y = sibling.Y + sibling.Height + (sibling.Border.Width * 2) + sibling.Margin.Bottom
+277 }
+278 }
+279
+280 }
+281 break
+282 } else if self.Style["display"] != "inline" {
+283 vState := s[v.Properties.Id]
+284 y += vState.Margin.Top + vState.Margin.Bottom + vState.Padding.Top + vState.Padding.Bottom + vState.Height + (self.Border.Width)
+285 }
+286 }
+287 }
+288 }
+289
+290 // Display modes need to be calculated here
+291
+292 relPos := !top && !left && !right && !bottom
+293
+294 if left || relPos {
+295 x += m.Left
+296 }
+297 if top || relPos {
+298 y += m.Top
+299 }
+300 if right {
+301 x -= m.Right
+302 }
+303 if bottom {
+304 y -= m.Bottom
+305 }
+306
+307 self.X = x
+308 self.Y = y
+309 self.Width = width
+310 self.Height = height
+311 (*state)[n.Properties.Id] = self
+312
+313 if !utils.ChildrenHaveText(n) && len(n.InnerText) > 0 {
+314 // Confirm text exists
+315 // words := strings.Split(strings.TrimSpace(n.InnerText), " ")
+316 // if len(words) != 1 {
+317 // if self.Style["display"] == "inline" {
+318 // n.InnerText = words[0]
+319 // // for i := 1; i < len(words); i++ {
+320 // // el := *n
+321 // // el.InnerText = strings.Join(words[1:], " ")
+322 // // n.Parent.InsertAfter(el, *n)
+323 // // fmt.Println("injetc", el.Properties.Id)
+324 // // }
+325
+326 // } else {
+327 // // el := n.CreateElement("notaspan")
+328 // // el.InnerText = n.InnerText
+329 // // n.AppendChild(el)
+330 // // self.Style["font-size"] = parent.Style["font-size"]
+331 // // self.EM = parent.EM
+332 // // n.InnerText = ""
+333 // }
+334 // (*state)[n.Properties.Id] = self
+335 // }
+336 if len(strings.TrimSpace(n.InnerText)) > 0 {
+337 n.InnerText = strings.TrimSpace(n.InnerText)
+338 self = genTextNode(n, state)
@@ -383,29 +383,29 @@ The utils.ChildrenHaveText function is called here instead of checking if the no
-342 self.Height += self.Padding.Bottom
-343
-344 (*state)[n.Properties.Id] = self
-345
-346 // Sorting the array by the Level field
-347 sort.Slice(plugins, func(i, j int) bool {
-348 return plugins[i].Level < plugins[j].Level
-349 })
-350
-351 for _, v := range plugins {
-352 matches := true
-353 for name, value := range v.Styles {
-354 if n.Style[name] != value && !(value == "*") && n.Style[name] != "" {
-355 matches = false
-356 }
-357 }
-358 if matches {
-359 v.Handler(n, state)
-360 }
-361 }
-362
-363 // CheckNode(n, state)
-364
-365 return n
-366}
-367
-368func CompleteBorder(cssProperties map[string]string, self, parent element.State) (element.Border, error) {
-369 // Split the shorthand into components
-370 borderComponents := strings.Fields(cssProperties["border"])
+342 (*state)[n.Properties.Id] = self
+343 (*state)[n.Parent.Properties.Id] = parent
+344
+345 // Call children here
+346
+347 var childYOffset float32
+348 for i := 0; i < len(n.Children); i++ {
+349 v := n.Children[i]
+350 v.Parent = n
+351 // This is were the tainting comes from
+352 n.Children[i] = *c.ComputeNodeStyle(&v, state)
+353
+354 cState := (*state)[n.Children[i].Properties.Id]
+355 if self.Style["height"] == "" {
+356 if cState.Style["position"] != "absolute" && cState.Y+cState.Height > childYOffset {
+357 childYOffset = cState.Y + cState.Height
+358 self.Height = (cState.Y - self.Border.Width) - (self.Y) + cState.Height
+359 self.Height += cState.Margin.Top
+360 self.Height += cState.Margin.Bottom
+361 self.Height += cState.Padding.Top
+362 self.Height += cState.Padding.Bottom
+363 }
+364 }
+365 if cState.Width > self.Width {
+366 self.Width = cState.Width
+367 }
+368 }
+369
+370 self.Height += self.Padding.Bottom
@@ -413,18 +413,18 @@ The utils.ChildrenHaveText function is called here instead of checking if the no
-372 // Ensure there are at least 1 component (width or style or color)
-373 if len(borderComponents) >= 1 {
-374 width := "0px" // Default width
-375 style := "solid"
-376 borderColor := "#000000" // Default color
-377
-378 // Extract style and color if available
-379 if len(borderComponents) >= 1 {
-380 width = borderComponents[0]
-381 }
-382
-383 // Extract style and color if available
-384 if len(borderComponents) >= 2 {
-385 style = borderComponents[1]
-386 }
-387 if len(borderComponents) >= 3 {
-388 borderColor = borderComponents[2]
-389 }
+372 (*state)[n.Properties.Id] = self
+373
+374 // Sorting the array by the Level field
+375 sort.Slice(plugins, func(i, j int) bool {
+376 return plugins[i].Level < plugins[j].Level
+377 })
+378
+379 for _, v := range plugins {
+380 matches := true
+381 for name, value := range v.Styles {
+382 if self.Style[name] != value && !(value == "*") && self.Style[name] != "" {
+383 matches = false
+384 }
+385 }
+386 if matches {
+387 v.Handler(n, state)
+388 }
+389 }
@@ -432,23 +432,23 @@ The utils.ChildrenHaveText function is called here instead of checking if the no
-391 parsedColor, _ := color.Color(borderColor)
-392
-393 w, _ := utils.ConvertToPixels(width, self.EM, parent.Width)
-394
-395 return element.Border{
-396 Width: w,
-397 Style: style,
-398 Color: parsedColor,
-399 Radius: cssProperties["border-radius"],
-400 }, nil
-401 }
-402
-403 return element.Border{}, fmt.Errorf("invalid border shorthand format")
-404}
-405
-406func genTextNode(n *element.Node, state *map[string]element.State) element.State {
-407 s := *state
-408 self := s[n.Properties.Id]
-409 parent := s[n.Parent.Properties.Id]
-410
-411 text := element.Text{}
-412
-413 bold, italic := false, false
+391 // n.InnerHTML = utils.InnerHTML(*n)
+392 // tag, closing := utils.NodeToHTML(*n)
+393 // n.OuterHTML = tag + n.InnerHTML + closing
+394
+395 // CheckNode(n, state)
+396
+397 return n
+398}
+399
+400func CompleteBorder(cssProperties map[string]string, self, parent element.State) (element.Border, error) {
+401 // Split the shorthand into components
+402 borderComponents := strings.Fields(cssProperties["border"])
+403
+404 // Ensure there are at least 1 component (width or style or color)
+405 if len(borderComponents) >= 1 {
+406 width := "0px" // Default width
+407 style := "solid"
+408 borderColor := "#000000" // Default color
+409
+410 // Extract style and color if available
+411 if len(borderComponents) >= 1 {
+412 width = borderComponents[0]
+413 }
@@ -456,7 +456,7 @@ The utils.ChildrenHaveText function is called here instead of checking if the no
-415 if n.Style["font-weight"] == "bold" {
-416 bold = true
-417 }
-418
-419 if n.Style["font-style"] == "italic" {
-420 italic = true
-421 }
+415 // Extract style and color if available
+416 if len(borderComponents) >= 2 {
+417 style = borderComponents[1]
+418 }
+419 if len(borderComponents) >= 3 {
+420 borderColor = borderComponents[2]
+421 }
@@ -464,10 +464,10 @@ The utils.ChildrenHaveText function is called here instead of checking if the no
-423 if text.Font == nil {
-424 f, _ := font.LoadFont(n.Style["font-family"], int(self.EM), bold, italic)
-425 text.Font = f
-426 }
-427
-428 letterSpacing, _ := utils.ConvertToPixels(n.Style["letter-spacing"], self.EM, parent.Width)
-429 wordSpacing, _ := utils.ConvertToPixels(n.Style["word-spacing"], self.EM, parent.Width)
-430 lineHeight, _ := utils.ConvertToPixels(n.Style["line-height"], self.EM, parent.Width)
-431 if lineHeight == 0 {
-432 lineHeight = self.EM + 3
+423 parsedColor, _ := color.Color(borderColor)
+424
+425 w, _ := utils.ConvertToPixels(width, self.EM, parent.Width)
+426
+427 return element.Border{
+428 Width: w,
+429 Style: style,
+430 Color: parsedColor,
+431 Radius: cssProperties["border-radius"],
+432 }, nil
@@ -476,24 +476,24 @@ The utils.ChildrenHaveText function is called here instead of checking if the no
-435 text.LineHeight = int(lineHeight)
-436 text.WordSpacing = int(wordSpacing)
-437 text.LetterSpacing = int(letterSpacing)
-438 wb := " "
-439
-440 if n.Style["word-wrap"] == "break-word" {
-441 wb = ""
-442 }
-443
-444 if n.Style["text-wrap"] == "wrap" || n.Style["text-wrap"] == "balance" {
-445 wb = ""
-446 }
-447
-448 var dt float32
-449
-450 if n.Style["text-decoration-thickness"] == "auto" || n.Style["text-decoration-thickness"] == "" {
-451 dt = self.EM / 7
-452 } else {
-453 dt, _ = utils.ConvertToPixels(n.Style["text-decoration-thickness"], self.EM, parent.Width)
-454 }
-455
-456 col := color.Parse(n.Style, "font")
-457
-458 self.Color = col
+435 return element.Border{}, fmt.Errorf("invalid border shorthand format")
+436}
+437
+438func genTextNode(n *element.Node, state *map[string]element.State) element.State {
+439 s := *state
+440 self := s[n.Properties.Id]
+441 parent := s[n.Parent.Properties.Id]
+442
+443 text := element.Text{}
+444
+445 bold, italic := false, false
+446
+447 if self.Style["font-weight"] == "bold" {
+448 bold = true
+449 }
+450
+451 if self.Style["font-style"] == "italic" {
+452 italic = true
+453 }
+454
+455 if text.Font == nil {
+456 f, _ := font.LoadFont(self.Style["font-family"], int(self.EM), bold, italic)
+457 text.Font = f
+458 }
@@ -501,21 +501,21 @@ The utils.ChildrenHaveText function is called here instead of checking if the no
-460 text.Color = col
-461 text.DecorationColor = color.Parse(n.Style, "decoration")
-462 text.Align = n.Style["text-align"]
-463 text.WordBreak = wb
-464 text.WordSpacing = int(wordSpacing)
-465 text.LetterSpacing = int(letterSpacing)
-466 text.WhiteSpace = n.Style["white-space"]
-467 text.DecorationThickness = int(dt)
-468 text.Overlined = n.Style["text-decoration"] == "overline"
-469 text.Underlined = n.Style["text-decoration"] == "underline"
-470 text.LineThrough = n.Style["text-decoration"] == "linethrough"
-471 text.EM = int(self.EM)
-472 text.Width = int(parent.Width)
-473 text.Text = n.InnerText
-474
-475 if n.Style["word-spacing"] == "" {
-476 text.WordSpacing = font.MeasureSpace(&text)
-477 }
-478
-479 img, width := font.Render(&text)
-480 self.Texture = img
+460 letterSpacing, _ := utils.ConvertToPixels(self.Style["letter-spacing"], self.EM, parent.Width)
+461 wordSpacing, _ := utils.ConvertToPixels(self.Style["word-spacing"], self.EM, parent.Width)
+462 lineHeight, _ := utils.ConvertToPixels(self.Style["line-height"], self.EM, parent.Width)
+463 if lineHeight == 0 {
+464 lineHeight = self.EM + 3
+465 }
+466
+467 text.LineHeight = int(lineHeight)
+468 text.WordSpacing = int(wordSpacing)
+469 text.LetterSpacing = int(letterSpacing)
+470 wb := " "
+471
+472 if self.Style["word-wrap"] == "break-word" {
+473 wb = ""
+474 }
+475
+476 if self.Style["text-wrap"] == "wrap" || self.Style["text-wrap"] == "balance" {
+477 wb = ""
+478 }
+479
+480 var dt float32
@@ -523,7 +523,7 @@ The utils.ChildrenHaveText function is called here instead of checking if the no
-482 if n.Style["height"] == "" {
-483 self.Height = float32(text.LineHeight)
-484 }
-485
-486 if n.Style["width"] == "" {
-487 self.Width = float32(width)
-488 }
+482 if self.Style["text-decoration-thickness"] == "auto" || self.Style["text-decoration-thickness"] == "" {
+483 dt = self.EM / 7
+484 } else {
+485 dt, _ = utils.ConvertToPixels(self.Style["text-decoration-thickness"], self.EM, parent.Width)
+486 }
+487
+488 col := color.Parse(self.Style, "font")
@@ -531,2 +531,34 @@ The utils.ChildrenHaveText function is called here instead of checking if the no
-490 return self
-491}
+490 self.Color = col
+491
+492 text.Color = col
+493 text.DecorationColor = color.Parse(self.Style, "decoration")
+494 text.Align = self.Style["text-align"]
+495 text.WordBreak = wb
+496 text.WordSpacing = int(wordSpacing)
+497 text.LetterSpacing = int(letterSpacing)
+498 text.WhiteSpace = self.Style["white-space"]
+499 text.DecorationThickness = int(dt)
+500 text.Overlined = self.Style["text-decoration"] == "overline"
+501 text.Underlined = self.Style["text-decoration"] == "underline"
+502 text.LineThrough = self.Style["text-decoration"] == "linethrough"
+503 text.EM = int(self.EM)
+504 text.Width = int(parent.Width)
+505 text.Text = n.InnerText
+506
+507 if self.Style["word-spacing"] == "" {
+508 text.WordSpacing = font.MeasureSpace(&text)
+509 }
+510
+511 img, width := font.Render(&text)
+512 self.Texture = img
+513
+514 if self.Style["height"] == "" {
+515 self.Height = float32(text.LineHeight)
+516 }
+517
+518 if self.Style["width"] == "" {
+519 self.Width = float32(width)
+520 }
+521
+522 return self
+523}