about summary refs log tree commit diff stats
path: root/src/css
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2022-12-27 23:36:13 +0100
committerbptato <nincsnevem662@gmail.com>2022-12-27 23:42:28 +0100
commitb5cffb3d805714767f2568b09fe86bb3a83d10b7 (patch)
treed9106729545b5b3915bfd3a97cf08f8da0d82619 /src/css
parent65b0b48f445b6c56016a3c842089ef117a9298bc (diff)
downloadchawan-b5cffb3d805714767f2568b09fe86bb3a83d10b7.tar.gz
layout/engine: get rid of dom dependency
Layout should only depend on cascading.
Diffstat (limited to 'src/css')
-rw-r--r--src/css/cascade.nim57
-rw-r--r--src/css/selectorparser.nim2
-rw-r--r--src/css/values.nim37
3 files changed, 73 insertions, 23 deletions
diff --git a/src/css/cascade.nim b/src/css/cascade.nim
index 1207444d..633bf0f5 100644
--- a/src/css/cascade.nim
+++ b/src/css/cascade.nim
@@ -74,49 +74,61 @@ func calcRules(styledNode: StyledNode, sheet: CSSStylesheet): DeclarationList =
           dl
 
 func calcPresentationalHints(element: Element): CSSComputedValues =
-  template set_cv(a, b, c: untyped) =
+  template set_cv(a, b: untyped) =
     if result == nil:
       new(result)
-    result[a] = CSSComputedValue(t: a, v: ValueTypes[a], b: c)
+    result{a} = b
   template map_width =
     let s = parseDimensionValues(element.attr("width"))
     if s.isSome:
-      set_cv(PROPERTY_WIDTH, length, s.get)
+      set_cv "width", s.get
   template map_height =
     let s = parseDimensionValues(element.attr("height"))
     if s.isSome:
-      set_cv(PROPERTY_HEIGHT, length, s.get)
+      set_cv "height", s.get
   template map_width_nozero =
     let s = parseDimensionValues(element.attr("width"))
     if s.isSome and s.get.num != 0:
-      set_cv(PROPERTY_WIDTH, length, s.get)
+      set_cv "width", s.get
   template map_height_nozero =
     let s = parseDimensionValues(element.attr("height"))
     if s.isSome and s.get.num != 0:
-      set_cv(PROPERTY_HEIGHT, length, s.get)
+      set_cv "height", s.get
   template map_bgcolor =
     let c = parseLegacyColor(element.attr("bgcolor"))
     if c.isSome:
-      set_cv(PROPERTY_BACKGROUND_COLOR, color, c.get)
+      set_cv "background-color", c.get
   template map_valign =
     case element.attr("valign").toLowerAscii()
-    of "top": set_cv(PROPERTY_VERTICAL_ALIGN, verticalalign, CSSVerticalAlign(keyword: VERTICAL_ALIGN_TOP))
-    of "middle": set_cv(PROPERTY_VERTICAL_ALIGN, verticalalign, CSSVerticalAlign(keyword: VERTICAL_ALIGN_MIDDLE))
-    of "bottom": set_cv(PROPERTY_VERTICAL_ALIGN, verticalalign, CSSVerticalAlign(keyword: VERTICAL_ALIGN_BOTTOM))
-    of "baseline": set_cv(PROPERTY_VERTICAL_ALIGN, verticalalign, CSSVerticalAlign(keyword: VERTICAL_ALIGN_BASELINE))
+    of "top": set_cv "vertical-align", CSSVerticalAlign(keyword: VERTICAL_ALIGN_TOP)
+    of "middle": set_cv "vertical-align", CSSVerticalAlign(keyword: VERTICAL_ALIGN_MIDDLE)
+    of "bottom": set_cv "vertical-align", CSSVerticalAlign(keyword: VERTICAL_ALIGN_BOTTOM)
+    of "baseline": set_cv "vertical-align", CSSVerticalAlign(keyword: VERTICAL_ALIGN_BASELINE)
   template map_align =
     case element.attr("align").toLowerAscii()
-    of "center", "middle": set_cv(PROPERTY_TEXT_ALIGN, textalign, TEXT_ALIGN_CHA_CENTER)
-    of "left": set_cv(PROPERTY_TEXT_ALIGN, textalign, TEXT_ALIGN_CHA_LEFT)
-    of "right": set_cv(PROPERTY_TEXT_ALIGN, textalign, TEXT_ALIGN_CHA_RIGHT)
+    of "center", "middle": set_cv "text-align", TEXT_ALIGN_CHA_CENTER
+    of "left": set_cv "text-align", TEXT_ALIGN_CHA_LEFT
+    of "right": set_cv "text-align", TEXT_ALIGN_CHA_RIGHT
   template map_text =
     let c = parseLegacyColor(element.attr("text"))
     if c.isSome:
-      set_cv(PROPERTY_COLOR, color, c.get)
+      set_cv "color", c.get
   template map_color =
     let c = parseLegacyColor(element.attr("color"))
     if c.isSome:
-      set_cv(PROPERTY_COLOR, color, c.get)
+      set_cv "color", c.get
+  template map_colspan =
+    let colspan = element.attrigz("colspan")
+    if colspan.isSome:
+      let i = colspan.get
+      if i <= 1000:
+        set_cv "-cha-colspan", i
+  template map_rowspan =
+    let rowspan = element.attrigez("rowspan")
+    if rowspan.isSome:
+      let i = rowspan.get
+      if i <= 65534:
+        set_cv "-cha-rowspan", i
 
   case element.tagType
   of TAG_DIV:
@@ -131,6 +143,8 @@ func calcPresentationalHints(element: Element): CSSComputedValues =
     map_bgcolor
     map_valign
     map_align
+    map_colspan
+    map_rowspan
   of TAG_THEAD, TAG_TBODY, TAG_TFOOT, TAG_TR:
     map_height
     map_bgcolor
@@ -146,8 +160,8 @@ func calcPresentationalHints(element: Element): CSSComputedValues =
     map_text
   of TAG_TEXTAREA:
     let textarea = HTMLTextAreaElement(element)
-    set_cv(PROPERTY_WIDTH, length, CSSLength(unit: UNIT_CH, num: float64(textarea.cols)))
-    set_cv(PROPERTY_HEIGHT, length, CSSLength(unit: UNIT_EM, num: float64(textarea.rows)))
+    set_cv "width", CSSLength(unit: UNIT_CH, num: float64(textarea.cols))
+    set_cv "height", CSSLength(unit: UNIT_EM, num: float64(textarea.rows))
   of TAG_FONT:
     map_color
   else: discard
@@ -286,6 +300,11 @@ proc applyRules(document: Document, ua, user: CSSStylesheet, cachedTree: StyledN
           let styledText = styledParent.newStyledReplacement(content)
           styledText.pseudo = pseudo
           styledParent.children.add(styledText)
+        of PSEUDO_NEWLINE:
+          let content = CSSContent(t: CONTENT_NEWLINE)
+          let styledText = styledParent.newStyledReplacement(content)
+          styledText.pseudo = pseudo
+          styledParent.children.add(styledText)
         of PSEUDO_NONE: discard
       else:
         assert child != nil
@@ -364,6 +383,8 @@ proc applyRules(document: Document, ua, user: CSSStylesheet, cachedTree: StyledN
         stack_append styledChild, PSEUDO_TEXTAREA_TEXT
       elif elem.tagType == TAG_IMG or elem.tagType == TAG_IMAGE:
         stack_append styledChild, PSEUDO_IMAGE
+      elif elem.tagType == TAG_BR:
+        stack_append styledChild, PSEUDO_NEWLINE
       else:
         for i in countdown(elem.childList.high, 0):
           if elem.childList[i].nodeType in {ELEMENT_NODE, TEXT_NODE}:
diff --git a/src/css/selectorparser.nim b/src/css/selectorparser.nim
index 8a38292b..2c6ab659 100644
--- a/src/css/selectorparser.nim
+++ b/src/css/selectorparser.nim
@@ -19,7 +19,7 @@ type
   PseudoElem* = enum
     PSEUDO_NONE, PSEUDO_BEFORE, PSEUDO_AFTER,
     # internal
-    PSEUDO_INPUT_TEXT, PSEUDO_TEXTAREA_TEXT, PSEUDO_IMAGE
+    PSEUDO_INPUT_TEXT, PSEUDO_TEXTAREA_TEXT, PSEUDO_IMAGE, PSEUDO_NEWLINE
 
   PseudoClass* = enum
     PSEUDO_FIRST_CHILD, PSEUDO_LAST_CHILD, PSEUDO_ONLY_CHILD, PSEUDO_HOVER,
diff --git a/src/css/values.nim b/src/css/values.nim
index 874d82a0..f847b72b 100644
--- a/src/css/values.nim
+++ b/src/css/values.nim
@@ -35,7 +35,8 @@ type
     PROPERTY_RIGHT, PROPERTY_TOP, PROPERTY_BOTTOM, PROPERTY_CAPTION_SIDE,
     PROPERTY_BORDER_SPACING, PROPERTY_BORDER_COLLAPSE, PROPERTY_QUOTES,
     PROPERTY_COUNTER_RESET, PROPERTY_MAX_WIDTH, PROPERTY_MAX_HEIGHT,
-    PROPERTY_MIN_WIDTH, PROPERTY_MIN_HEIGHT, PROPERTY_BACKGROUND_IMAGE
+    PROPERTY_MIN_WIDTH, PROPERTY_MIN_HEIGHT, PROPERTY_BACKGROUND_IMAGE,
+    PROPERTY_CHA_COLSPAN, PROPERTY_CHA_ROWSPAN
 
   CSSValueType* = enum
     VALUE_NONE, VALUE_LENGTH, VALUE_COLOR, VALUE_CONTENT, VALUE_DISPLAY,
@@ -102,7 +103,8 @@ type
 
   CSSContentType* = enum
     CONTENT_STRING, CONTENT_OPEN_QUOTE, CONTENT_CLOSE_QUOTE,
-    CONTENT_NO_OPEN_QUOTE, CONTENT_NO_CLOSE_QUOTE, CONTENT_IMAGE
+    CONTENT_NO_OPEN_QUOTE, CONTENT_NO_CLOSE_QUOTE, CONTENT_IMAGE,
+    CONTENT_NEWLINE
 
 const RowGroupBox* = {DISPLAY_TABLE_ROW_GROUP, DISPLAY_TABLE_HEADER_GROUP,
                       DISPLAY_TABLE_FOOTER_GROUP}
@@ -250,7 +252,9 @@ const PropertyNames = {
   "max-height": PROPERTY_MAX_HEIGHT,
   "min-width": PROPERTY_MIN_WIDTH,
   "min-height": PROPERTY_MIN_HEIGHT,
-  "background-image": PROPERTY_BACKGROUND_IMAGE
+  "background-image": PROPERTY_BACKGROUND_IMAGE,
+  "-cha-colspan": PROPERTY_CHA_COLSPAN,
+  "-cha-rowspan": PROPERTY_CHA_ROWSPAN
 }.toTable()
 
 const ValueTypes* = [
@@ -294,7 +298,9 @@ const ValueTypes* = [
   PROPERTY_MAX_HEIGHT: VALUE_LENGTH,
   PROPERTY_MIN_WIDTH: VALUE_LENGTH,
   PROPERTY_MIN_HEIGHT: VALUE_LENGTH,
-  PROPERTY_BACKGROUND_IMAGE: VALUE_IMAGE
+  PROPERTY_BACKGROUND_IMAGE: VALUE_IMAGE,
+  PROPERTY_CHA_COLSPAN: VALUE_INTEGER,
+  PROPERTY_CHA_ROWSPAN: VALUE_INTEGER
 ]
 
 const InheritedProperties = {
@@ -856,6 +862,15 @@ func cssImage(cval: CSSComponentValue): Option[CSSContent] =
     if tok.tokenType == CSS_URL_TOKEN or tok.tokenType == CSS_BAD_URL_TOKEN:
       return some(CSSContent(t: CONTENT_IMAGE, s: "[img]"))
 
+func cssInteger(cval: CSSComponentValue, range: Slice[int]): int =
+  if isToken(cval):
+    let tok = getToken(cval)
+    if tok.tokenType == CSS_NUMBER_TOKEN:
+      let i = int(tok.nvalue)
+      if float64(i) == tok.nvalue and i in range:
+        return i
+  raise newException(CSSValueError, "Invalid integer")
+
 proc getValueFromDecl(val: CSSComputedValue, d: CSSDeclaration, vtype: CSSValueType, ptype: CSSPropertyType) =
   var i = 0
   d.value.skipWhitespace(i)
@@ -891,6 +906,10 @@ proc getValueFromDecl(val: CSSComputedValue, d: CSSDeclaration, vtype: CSSValueT
   of VALUE_INTEGER:
     if ptype == PROPERTY_FONT_WEIGHT:
       val.integer = cssFontWeight(cval)
+    elif ptype == PROPERTY_CHA_COLSPAN:
+      val.integer = cssInteger(cval, 1 .. 1000)
+    elif ptype == PROPERTY_CHA_ROWSPAN:
+      val.integer = cssInteger(cval, 0 .. 65534)
   of VALUE_TEXT_DECORATION: val.textdecoration = cssTextDecoration(d)
   of VALUE_WORD_BREAK: val.wordbreak = cssWordBreak(cval)
   of VALUE_LIST_STYLE_TYPE: val.liststyletype = cssListStyleType(cval)
@@ -947,6 +966,14 @@ func getInitialLength(t: CSSPropertyType): CSSLength =
   else:
     return CSSLength(auto: false, unit: UNIT_PX, num: 0)
 
+func getInitialInteger(t: CSSPropertyType): int =
+  case t
+  of PROPERTY_CHA_COLSPAN, PROPERTY_CHA_ROWSPAN:
+    return 1
+  of PROPERTY_FONT_WEIGHT:
+    return 400 # normal
+  else: discard
+
 func calcInitial(t: CSSPropertyType): CSSComputedValue =
   let v = valueType(t)
   var nv: CSSComputedValue
@@ -959,6 +986,8 @@ func calcInitial(t: CSSPropertyType): CSSComputedValue =
     nv = CSSComputedValue(t: t, v: v, wordbreak: WORD_BREAK_NORMAL)
   of VALUE_LENGTH:
     nv = CSSComputedValue(t: t, v: v, length: getInitialLength(t))
+  of VALUE_INTEGER:
+    nv = CSSComputedValue(t: t, v: v, integer: getInitialInteger(t))
   of VALUE_QUOTES:
     nv = CSSComputedValue(t: t, v: v, quotes: CSSQuotes(auto: true))
   else: