about summary refs log tree commit diff stats
path: root/src/html
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2021-12-14 17:31:00 +0100
committerbptato <nincsnevem662@gmail.com>2021-12-14 17:31:00 +0100
commit72e171f6bee469ecc0086357f83fe4dc678023f3 (patch)
tree4b02726798aa961c3562a0f44293dafcf28dd179 /src/html
parent8edf12e933f490a5adf268a101f320ace8120997 (diff)
downloadchawan-72e171f6bee469ecc0086357f83fe4dc678023f3.tar.gz
Add lists, function selector fixes
Diffstat (limited to 'src/html')
-rw-r--r--src/html/dom.nim96
-rw-r--r--src/html/parser.nim42
2 files changed, 102 insertions, 36 deletions
diff --git a/src/html/dom.nim b/src/html/dom.nim
index f2c98bd0..0c7d385a 100644
--- a/src/html/dom.nim
+++ b/src/html/dom.nim
@@ -1,5 +1,7 @@
 import uri
 import tables
+import options
+import strutils
 
 import css/values
 import types/enums
@@ -70,40 +72,46 @@ type
     cssapplied*: bool
     rendered*: bool
 
-  HTMLElement* = ref HTMLElementObj
-  HTMLElementObj = object of ElementObj
+  HTMLElement* = ref object of ElementObj
 
-  HTMLInputElement* = ref HTMLInputElementObj
-  HTMLInputElementObj = object of HTMLElementObj
+  HTMLInputElement* = ref object of HTMLElement
     itype*: InputType
     autofocus*: bool
     required*: bool
     value*: string
     size*: int
 
-  HTMLAnchorElement* = ref HTMLAnchorElementObj
-  HTMLAnchorElementObj = object of HTMLElementObj
+  HTMLAnchorElement* = ref object of HTMLElement
     href*: string
 
-  HTMLSelectElement* = ref HTMLSelectElementObj
-  HTMLSelectElementObj = object of HTMLElementObj
+  HTMLSelectElement* = ref object of HTMLElement
     name*: string
     value*: string
     valueSet*: bool
 
-  HTMLSpanElement* = ref HTMLSpanElementObj
-  HTMLSpanElementObj = object of HTMLElementObj
+  HTMLSpanElement* = ref object of HTMLElement
 
-  HTMLOptionElement* = ref HTMLOptionElementObj
-  HTMLOptionElementObj = object of HTMLElementObj
+  HTMLOptionElement* = ref object of HTMLElement
     value*: string
   
-  HTMLHeadingElement* = ref HTMLHeadingElementObj
-  HTMLHeadingElementObj = object of HTMLElementObj
+  HTMLHeadingElement* = ref object of HTMLElement
     rank*: uint16
 
-  HTMLBRElement* = ref HTMLBRElementObj
-  HTMLBRElementObj = object of HTMLElementObj
+  HTMLBRElement* = ref object of HTMLElement
+
+  HTMLMenuElement* = ref object of HTMLElement
+    ordinalcounter*: int
+
+  HTMLUListElement* = ref object of HTMLElement
+    ordinalcounter*: int
+
+  HTMLOListElement* = ref object of HTMLElement
+    start*: Option[int]
+    ordinalcounter*: int
+
+  HTMLLIElement* = ref object of HTMLElement
+    value*: Option[int]
+    ordinalvalue*: int
 
 func firstChild(node: Node): Node =
   if node.childNodes.len == 0:
@@ -191,6 +199,49 @@ func toInputType*(str: string): InputType =
   of "week": INPUT_WEEK
   else: INPUT_UNKNOWN
 
+func ancestor(node: Node, tagTypes: set[TagType]): Element =
+  var elem = node.parentElement
+  while elem != nil:
+    if elem.tagType in tagTypes:
+      return elem
+
+    elem = elem.parentElement
+  return nil
+
+func attr*(element: Element, s: string): string =
+  return element.attributes.getOrDefault(s, "")
+
+func attri*(element: Element, s: string): Option[int] =
+  let a = element.attr(s)
+  try:
+    return some(parseInt(a))
+  except ValueError:
+    return none(int)
+
+proc applyOrdinal*(elem: HTMLLIElement) =
+  let val = elem.attri("value")
+  if val.issome:
+    elem.ordinalvalue = val.get
+  else:
+    let owner = elem.ancestor({TAG_OL, TAG_UL, TAG_MENU})
+    if owner == nil:
+      elem.ordinalvalue = 1
+    else:
+      case owner.tagType
+      of TAG_OL:
+        let ol = HTMLOListElement(owner)
+        elem.ordinalvalue = ol.ordinalcounter
+        inc ol.ordinalcounter
+      of TAG_UL:
+        let ul = HTMLUListElement(owner)
+        elem.ordinalvalue = ul.ordinalcounter
+        inc ul.ordinalcounter
+      of TAG_MENU:
+        let menu = HTMLMenuElement(owner)
+        elem.ordinalvalue = menu.ordinalcounter
+        inc menu.ordinalcounter
+      else: discard
+
 func newText*(): Text =
   new(result)
   result.nodeType = TEXT_NODE
@@ -215,6 +266,16 @@ func newHtmlElement*(tagType: TagType): HTMLElement =
     result = new(HTMLBRElement)
   of TAG_SPAN:
     result = new(HTMLSpanElement)
+  of TAG_OL:
+    result = new(HTMLOListElement)
+  of TAG_UL:
+    result = new(HTMLUListElement)
+    HTMLUListElement(result).ordinalcounter = 1
+  of TAG_MENU:
+    result = new(HTMLMenuElement)
+    HTMLMenuElement(result).ordinalcounter = 1
+  of TAG_LI:
+    result = new(HTMLLIElement)
   else:
     result = new(HTMLElement)
 
@@ -235,6 +296,3 @@ func newAttr*(parent: Element, key: string, value: string): Attr =
   result.ownerElement = parent
   result.name = key
   result.value = value
-
-func attr*(element: Element, s: string): string =
-  return element.attributes.getOrDefault(s, "")
diff --git a/src/html/parser.nim b/src/html/parser.nim
index a3a6885d..70b749a6 100644
--- a/src/html/parser.nim
+++ b/src/html/parser.nim
@@ -3,6 +3,7 @@ import unicode
 import strutils
 import tables
 import json
+import options
 
 import types/enums
 import types/tagtypes
@@ -250,6 +251,11 @@ proc processDocumentStartElement(state: var HTMLParseState, element: Element, ta
     HTMLAnchorElement(element).href = element.attr("href")
   of TAG_OPTION:
     HTMLOptionElement(element).value = element.attr("href")
+  of TAG_OL:
+    HTMLOListElement(element).start = element.attri("start") 
+    HTMLOListElement(element).ordinalcounter = HTMLOListElement(element).start.get(1)
+  of TAG_LI:
+    HTMLLIElement(element).value = element.attri("value")
   of TAG_HTML:
     add = false
   of TAG_HEAD:
@@ -261,29 +267,27 @@ proc processDocumentStartElement(state: var HTMLParseState, element: Element, ta
     add = false
   of TAG_PRE:
     state.skip_lf = true
+  of TAG_H1:
+    HTMLHeadingElement(element).rank = 1
+  of TAG_H2:
+    HTMLHeadingElement(element).rank = 2
+  of TAG_H3:
+    HTMLHeadingElement(element).rank = 3
+  of TAG_H4:
+    HTMLHeadingElement(element).rank = 4
+  of TAG_H5:
+    HTMLHeadingElement(element).rank = 5
+  of TAG_H6:
+    HTMLHeadingElement(element).rank = 6
   else: discard
 
   if not state.in_body and not (element.tagType in HeadTagTypes):
     processDocumentBody(state)
 
   if state.elementNode.nodeType == ELEMENT_NODE:
-    case element.tagType
-    of SelfClosingTagTypes:
+    if element.tagType in SelfClosingTagTypes:
       if state.elementNode.tagType == element.tagType:
         processDocumentEndNode(state)
-    of TAG_H1:
-      HTMLHeadingElement(element).rank = 1
-    of TAG_H2:
-      HTMLHeadingElement(element).rank = 2
-    of TAG_H3:
-      HTMLHeadingElement(element).rank = 3
-    of TAG_H4:
-      HTMLHeadingElement(element).rank = 4
-    of TAG_H5:
-      HTMLHeadingElement(element).rank = 5
-    of TAG_H6:
-      HTMLHeadingElement(element).rank = 6
-    else: discard
 
     if state.elementNode.tagType == TAG_P and element.tagType in PClosingTagTypes:
       processDocumentEndNode(state)
@@ -292,8 +296,12 @@ proc processDocumentStartElement(state: var HTMLParseState, element: Element, ta
     processDocumentAddNode(state, element)
     state.elementNode = element
 
-  if element.tagType in VoidTagTypes:
-    processDocumentEndNode(state)
+    case element.tagType
+    of VoidTagTypes:
+      processDocumentEndNode(state)
+    of TAG_LI:
+      HTMLLIElement(element).applyOrdinal() #needs to know parent
+    else: discard
 
 proc processDocumentEndElement(state: var HTMLParseState, tag: DOMParsedTag) =
   if tag.tagid in VoidTagTypes: