about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2021-08-11 22:26:30 +0200
committerbptato <nincsnevem662@gmail.com>2021-08-11 22:26:30 +0200
commit2f32d6ed51e14d6871c7be4fd1f8ccdc0455a0bb (patch)
treebcc405a077944852780551d5700d284958e49ce1 /src
parent6cea57b35e4e749de531faf6502237c1cf7ed022 (diff)
downloadchawan-2f32d6ed51e14d6871c7be4fd1f8ccdc0455a0bb.tar.gz
Get rid of some old code, work on css property handling
Diffstat (limited to 'src')
-rw-r--r--src/css/style.nim74
-rw-r--r--src/html/dom.nim97
-rw-r--r--src/html/parser.nim2
-rw-r--r--src/html/renderer.nim4
-rw-r--r--src/io/buffer.nim34
-rw-r--r--src/utils/twtstr.nim31
6 files changed, 73 insertions, 169 deletions
diff --git a/src/css/style.nim b/src/css/style.nim
index cdf774eb..3ef38bea 100644
--- a/src/css/style.nim
+++ b/src/css/style.nim
@@ -40,6 +40,8 @@ type
     position*: CSSPosition
     content*: seq[Rune]
 
+  CSSValues* = array[low(CSSRuleType)..high(CSSRuleType), CSSComputedValue]
+
   CSSColor* = tuple[r: uint8, g: uint8, b: uint8, a: uint8]
   
   CSSComputedValue* = object of RootObj
@@ -282,14 +284,32 @@ func getSpecifiedValue*(d: CSSDeclaration): CSSSpecifiedValue =
   of "content":
     return CSSSpecifiedValue(t: RULE_CONTENT, v: VALUE_CONTENT, content: cssString(d))
 
-func getComputedValue*(rule: CSSSpecifiedValue): CSSComputedValue =
+func getInitialColor*(t: CSSRuleType): CSSColor =
+  case t
+  of RULE_COLOR:
+    return (r: 255u8, g: 255u8, b: 255u8, a: 255u8)
+  else:
+    return (r: 0u8, g: 0u8, b: 0u8, a: 255u8)
+
+func getComputedValue*(rule: CSSSpecifiedValue, parent: CSSValues): CSSComputedValue =
   let inherit = rule.hasGlobalValue and (rule.globalValue == VALUE_INHERIT)
-  let initial = rule.hasGlobalValue and (rule.globalValue == VALUE_INHERIT)
-  let unset = rule.hasGlobalValue and (rule.globalValue == VALUE_INHERIT)
-  let revert = rule.hasGlobalValue and (rule.globalValue == VALUE_INHERIT)
+  let initial = rule.hasGlobalValue and (rule.globalValue == VALUE_INITIAL)
+  let unset = rule.hasGlobalValue and (rule.globalValue == VALUE_UNSET)
+  let revert = rule.hasGlobalValue and (rule.globalValue == VALUE_REVERT)
   case rule.v
   of VALUE_COLOR:
-    return CSSComputedValue(t: rule.t, v: VALUE_COLOR, color: rule.color)
+    var val = rule.color
+    if inherit: #TODO and inherited(rule.t):
+      val = parent[rule.t].color
+    if initial:
+      val = getInitialColor(rule.t)
+    if unset:
+      val = getInitialColor(rule.t)
+      #TODO if inherited
+    if revert:
+      #TODO
+      discard
+    return CSSComputedValue(t: rule.t, v: VALUE_COLOR, color: val)
   of VALUE_LENGTH:
     return CSSComputedValue(t: rule.t, v: VALUE_LENGTH, length: rule.length)
   of VALUE_DISPLAY:
@@ -300,37 +320,15 @@ func getComputedValue*(rule: CSSSpecifiedValue): CSSComputedValue =
     return CSSComputedValue(t: rule.t, v: VALUE_CONTENT, content: rule.content)
   of VALUE_NONE: return CSSComputedValue(t: rule.t, v: VALUE_NONE)
 
-func getValue*(vals: seq[CSSComputedValue], rule: CSSRuleType): CSSComputedValue =
-  for val in vals:
-    if val.t == rule:
-      result = val
+func getComputedValue*(d: CSSDeclaration, parent: CSSValues): CSSComputedValue =
+  return getComputedValue(getSpecifiedValue(d), parent)
 
-func getComputedValue*(d: CSSDeclaration): CSSComputedValue =
-  return getComputedValue(getSpecifiedValue(d))
-
-proc applyProperty*(props: CSS2Properties, d: CSSDeclaration) =
-  case $d.name
-  of "color":
-    props.color = cssColor(d)
-  of "margin":
-    let l = cssLength(d)
-    props.margintop = l
-    props.marginbottom = l
-    props.marginleft = l
-    props.marginright = l
-  of "margin-top":
-    props.margintop = cssLength(d)
-  of "margin-left":
-    props.marginleft = cssLength(d)
-  of "margin-right":
-    props.marginright = cssLength(d)
-  of "margin-bottom":
-    props.marginbottom = cssLength(d)
-  of "font-style":
-    props.fontStyle = cssFontStyle(d)
-  of "display":
-    props.display = cssDisplay(d)
-  of "content":
-    props.content = cssString(d)
-  else:
-    printc(d) #TODO
+func getInitialProperties*(): array[low(CSSRuleType)..high(CSSRuleType), CSSComputedValue] =
+  for i in low(result)..high(result):
+    let t = CSSRuleType(i)
+    let v = getValueType(t)
+    case v
+    of VALUE_COLOR:
+      result[i] = CSSComputedValue(t: t, v: v, color: getInitialColor(t))
+    else:
+      result[i] = CSSComputedValue(t: t, v: v)
diff --git a/src/html/dom.nim b/src/html/dom.nim
index cb2f363f..82301146 100644
--- a/src/html/dom.nim
+++ b/src/html/dom.nim
@@ -33,8 +33,6 @@ type
     parentElement*: Element
     ownerDocument*: Document
 
-    rawtext*: string
-    fmttext*: seq[string]
     x*: int
     y*: int
     ex*: int
@@ -86,8 +84,7 @@ type
     id*: string
     classList*: seq[string]
     attributes*: Table[string, Attr]
-    style*: CSS2Properties
-    cssvalues*: seq[CSSComputedValue]
+    cssvalues*: array[low(CSSRuleType)..high(CSSRuleType), CSSComputedValue]
 
   HTMLElement* = ref HTMLElementObj
   HTMLElementObj = object of ElementObj
@@ -155,15 +152,6 @@ func nodeAttr*(node: Node): HtmlElement =
   of ELEMENT_NODE: return HtmlElement(node)
   else: assert(false)
 
-func getStyle*(node: Node): CSS2Properties =
-  case node.nodeType
-  of TEXT_NODE: return node.parentElement.style
-  of ELEMENT_NODE: return Element(node).style
-  else: assert(false)
-
-func displayed*(node: Node): bool =
-  return node.rawtext.len > 0 and node.getStyle().display != DISPLAY_NONE
-
 func isTextNode*(node: Node): bool =
   return node.nodeType == TEXT_NODE
 
@@ -179,12 +167,6 @@ func isCData*(node: Node): bool =
 func isDocument*(node: Node): bool =
   return node.nodeType == DOCUMENT_NODE
 
-func getFmtLen*(htmlNode: Node): int =
-  return htmlNode.fmttext.join().runeLen()
-
-func getRawLen*(htmlNode: Node): int =
-  return htmlNode.rawtext.runeLen()
-
 func firstNode*(htmlNode: Node): bool =
   return htmlNode.parentElement != nil and htmlNode.parentElement.childNodes[0] == htmlNode
 
@@ -225,72 +207,12 @@ func toInputSize*(str: string): int =
       return 20
   return str.parseInt()
 
-func getFmtInput(inputElement: HtmlInputElement): seq[string] =
-  case inputElement.itype
-  of INPUT_TEXT, INPUT_SEARCH:
-    let valueFit = fitValueToSize(inputElement.value, inputElement.size)
-    return valueFit.ansiStyle(styleUnderscore).ansiReset().buttonFmt()
-  of INPUT_SUBMIT:
-    return inputElement.value.buttonFmt()
-  else: discard
-
-func getRawInput(inputElement: HtmlInputElement): string =
-  case inputElement.itype
-  of INPUT_TEXT, INPUT_SEARCH:
-    return inputElement.value.fitValueToSize(inputElement.size).buttonRaw()
-  of INPUT_SUBMIT:
-    return inputElement.value.buttonRaw()
-  else: discard
-
 #TODO
 func ancestor*(htmlNode: Node, tagType: TagType): HtmlElement =
   result = HtmlElement(htmlNode.parentElement)
   while result != nil and result.tagType != tagType:
     result = HtmlElement(result.parentElement)
 
-proc getRawText*(htmlNode: Node): string =
-  if htmlNode.isElemNode():
-    case HtmlElement(htmlNode).tagType
-    of TAG_INPUT: return HtmlInputElement(htmlNode).getRawInput()
-    else: return ""
-  elif htmlNode.isTextNode():
-    let chardata = CharacterData(htmlNode)
-    if htmlNode.parentElement != nil and htmlNode.parentElement.tagType != TAG_PRE:
-      result = chardata.data.remove("\n")
-    else:
-      result = unicode.strip(chardata.data)
-    if htmlNode.parentElement != nil and htmlNode.parentElement.tagType == TAG_OPTION:
-      result = result.buttonRaw()
-  else:
-    assert(false)
-
-func getFmtText*(node: Node): seq[string] =
-  if node.isElemNode():
-    case HtmlElement(node).tagType
-    of TAG_INPUT: return HtmlInputElement(node).getFmtInput()
-    else: return @[]
-  elif node.isTextNode():
-    let chardata = CharacterData(node)
-    result &= chardata.data
-    if node.parentElement != nil:
-      let style = node.getStyle()
-      if style.hasColor():
-        result = result.ansiFgColor(style.termColor())
-
-      if node.parentElement.tagType == TAG_OPTION:
-        result = result.ansiFgColor(fgRed).ansiReset()
-
-      if style.bold:
-        result = result.ansiStyle(styleBright).ansiReset()
-      if style.fontStyle == FONTSTYLE_ITALIC or style.fontStyle == FONTSTYLE_OBLIQUE:
-        result = result.ansiStyle(styleItalic).ansiReset()
-      if style.underscore:
-        result = result.ansiStyle(styleUnderscore).ansiReset()
-    else:
-      assert(false, node.rawtext)
-  else:
-    assert(false)
-
 func newText*(): Text =
   new(result)
   result.nodeType = TEXT_NODE
@@ -320,7 +242,7 @@ func newHtmlElement*(tagType: TagType): HTMLElement =
 
   result.nodeType = ELEMENT_NODE
   result.tagType = tagType
-  result.style = CSS2Properties()
+  result.cssvalues = getInitialProperties()
 
 func newDocument*(): Document =
   new(result)
@@ -455,6 +377,15 @@ func calcRules(elem: Element, rules: CSSStylesheet): seq[CSSSimpleBlock] =
   tosort.sort((x, y) => cmp(x.s,y.s))
   return tosort.map((x) => x.b)
 
+proc applyProperty(elem: Element, decl: CSSDeclaration) =
+  var parentprops: array[low(CSSRuleType)..high(CSSRuleType), CSSComputedValue]
+  if elem.parentElement != nil:
+    parentprops = elem.parentElement.cssvalues
+  else:
+    parentprops = getInitialProperties()
+  let cval = getComputedValue(decl, parentprops)
+  elem.cssvalues[cval.t] = cval
+
 proc applyRules*(document: Document, rules: CSSStylesheet): seq[tuple[e:Element,d:CSSDeclaration]] =
   var stack: seq[Element]
 
@@ -470,8 +401,7 @@ proc applyRules*(document: Document, rules: CSSStylesheet): seq[tuple[e:Element,
           if decl.important:
             result.add((elem, decl))
           else:
-            elem.style.applyProperty(decl)
-            elem.cssvalues.add(getComputedValue(decl))
+            elem.applyProperty(decl)
 
     for child in elem.children:
       stack.add(child)
@@ -480,6 +410,5 @@ proc applyRules*(document: Document, rules: CSSStylesheet): seq[tuple[e:Element,
 proc applyDefaultStylesheet*(document: Document) =
   let important = document.applyRules(stylesheet)
   for rule in important:
-    rule.e.style.applyProperty(rule.d)
-    rule.e.cssvalues.add(getComputedValue(rule.d))
+    rule.e.applyProperty(rule.d)
 
diff --git a/src/html/parser.nim b/src/html/parser.nim
index 44b31d4a..6868ec52 100644
--- a/src/html/parser.nim
+++ b/src/html/parser.nim
@@ -370,7 +370,6 @@ proc processDocumentPart(state: var HTMLParseState, buf: string) =
               state.commentNode = comment
               processDocumentAddNode(state, comment)
               if state.textNode != nil:
-                state.textNode.rawtext = state.textNode.getRawText()
                 state.textNode = nil
           else:
             #TODO for doctype
@@ -381,7 +380,6 @@ proc processDocumentPart(state: var HTMLParseState, buf: string) =
 
         if not state.in_comment:
           if state.textNode != nil:
-            state.textNode.rawtext = state.textNode.getRawText()
             state.textNode = nil
           p = at
           var tag = parse_tag(buf, at)
diff --git a/src/html/renderer.nim b/src/html/renderer.nim
index 6b63cf29..1f4deadd 100644
--- a/src/html/renderer.nim
+++ b/src/html/renderer.nim
@@ -41,7 +41,7 @@ func boxesForText*(text: seq[Rune], width: int, height: int, lx: int, x: int, y:
     result[^1].innerEdge.y2 = sy + 1
 
 proc generateBox(elem: Element, x: int, y: int, w: int, h: int, fromx: int = x): CSSBox =
-  let display = elem.cssvalues.getValue(RULE_DISPLAY)
+  let display = elem.cssvalues[RULE_DISPLAY]
   if display.t == RULE_DISPLAY:
     if display.display == DISPLAY_NONE:
       return nil
@@ -51,7 +51,7 @@ proc generateBox(elem: Element, x: int, y: int, w: int, h: int, fromx: int = x):
 
   var anonBoxes = false
   for child in elem.children:
-    let rule = child.cssvalues.getValue(RULE_DISPLAY)
+    let rule = child.cssvalues[RULE_DISPLAY]
     if rule.t == RULE_DISPLAY and rule.display == DISPLAY_BLOCK:
       anonBoxes = true
       break
diff --git a/src/io/buffer.nim b/src/io/buffer.nim
index 637fc87b..65bece1f 100644
--- a/src/io/buffer.nim
+++ b/src/io/buffer.nim
@@ -213,13 +213,7 @@ func cursorOnNode*(buffer: Buffer, node: Node): bool =
            (buffer.cursory == node.ey and buffer.cursorx < node.ex)
 
 func findSelectedElement*(buffer: Buffer): Option[HtmlElement] =
-  if buffer.selectedlink != nil and buffer.selectedLink.parentNode of HtmlElement:
-    return some(HtmlElement(buffer.selectedlink.parentNode))
-  for node in buffer.nodes:
-    if node.isElemNode():
-      if node.getFmtLen() > 0:
-        if buffer.cursorOnNode(node): return some(HtmlElement(node))
-  return none(HtmlElement)
+  discard #TODO
 
 func canScroll*(buffer: Buffer): bool =
   return buffer.numLines >= buffer.height
@@ -230,31 +224,7 @@ func getElementById*(buffer: Buffer, id: string): Element =
   return nil
 
 proc findSelectedNode*(buffer: Buffer): Option[Node] =
-  for node in buffer.nodes:
-    if node.getFmtLen() > 0 and node.displayed():
-      if buffer.cursory >= node.y and buffer.cursory <= node.y + node.height and buffer.cursorx >= node.x and buffer.cursorx <= node.x + node.width:
-        return some(node)
-  return none(Node)
-
-proc writefmt*(buffer: Buffer, str: string) =
-  discard
-
-proc writefmt*(buffer: Buffer, c: char) =
-  discard
-
-proc writeraw*(buffer: Buffer, str: string) =
-  discard
-
-proc writeraw*(buffer: Buffer, c: char) =
-  discard
-
-proc write*(buffer: Buffer, str: string) =
-  buffer.writefmt(str)
-  buffer.writeraw(str)
-
-proc write*(buffer: Buffer, c: char) =
-  buffer.writefmt(c)
-  buffer.writeraw(c)
+  discard #TODO
 
 proc clearText*(buffer: Buffer) =
   buffer.lines.setLen(0)
diff --git a/src/utils/twtstr.nim b/src/utils/twtstr.nim
index 707b09a9..9cf63d68 100644
--- a/src/utils/twtstr.nim
+++ b/src/utils/twtstr.nim
@@ -464,8 +464,11 @@ const HasHanDakuten = "ぱぴぷぺぽパピプペポ".toRunes()
 #in unicode, char + 1 is dakuten and char + 2 handakuten
 #゙゚
 
-const Dakuten = "゙".toRunes()[0]
-const HanDakuten = "゚".toRunes()[0]
+const HalfDakuten = "゙".toRunes()[0]
+const HalfHanDakuten = "゚".toRunes()[0]
+
+const Dakuten = Rune(0x3099)
+const HanDakuten = Rune(0x309A)
 
 func dakuten*(r: Rune): Rune =
   if r in CanHaveDakuten:
@@ -509,15 +512,20 @@ func halfwidth*(r: Rune): Rune =
 
 func halfwidth*(s: seq[Rune]): seq[Rune] =
   for r in s:
-    #TODO implement a setting to enable this, I personally dislike it
-    #if r in HasDakuten:
-    #  result.add(halfwidth(r.nodakuten()))
-    #  result.add(Dakuten)
-    #elif r in HasHanDakuten:
-    #  result.add(halfwidth(r.nohandakuten()))
-    #  result.add(HanDakuten)
-    #else:
-    result.add(halfwidth(r))
+    #TODO combining dakuten don't always work with half width chars
+    #a proper solution would be something like:
+    #* try to detect if they work, if not fallback to halfwidth handakuten
+    #* add a config option for overriding this
+    #* also add an option to completely ignore dakuten
+    #* and one to disable half width ruby of course
+    if r in HasDakuten:
+      result.add(halfwidth(r.nodakuten()))
+      result.add(Dakuten)
+    elif r in HasHanDakuten:
+      result.add(halfwidth(r.nohandakuten()))
+      result.add(HanDakuten)
+    else:
+      result.add(halfwidth(r))
 
 func halfwidth*(s: string): string =
   return $halfwidth(s.toRunes())
@@ -542,3 +550,4 @@ proc fullwidth*(s: seq[Rune]): seq[Rune] =
 
 proc fullwidth*(s: string): string =
   return $fullwidth(s.toRunes())
+