about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2023-01-08 16:00:26 +0100
committerbptato <nincsnevem662@gmail.com>2023-01-08 16:19:17 +0100
commit4e40c70ebc19807a0bd121b2376ff147adae765c (patch)
treece6fcab0bc9c35d42cf69141725adcf2cd60c20f
parent7bed16fa67df23f1bd1156e709a4b959b274b2ca (diff)
downloadchawan-4e40c70ebc19807a0bd121b2376ff147adae765c.tar.gz
css/cascade, layout/engine: add table align
Also fix margin-left/right: auto, to some extent.
-rw-r--r--src/css/cascade.nim10
-rw-r--r--src/css/values.nim12
-rw-r--r--src/layout/engine.nim66
3 files changed, 49 insertions, 39 deletions
diff --git a/src/css/cascade.nim b/src/css/cascade.nim
index c7d6dfd0..0cea87b7 100644
--- a/src/css/cascade.nim
+++ b/src/css/cascade.nim
@@ -109,6 +109,15 @@ func calcPresentationalHints(element: Element): CSSComputedValues =
     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_table_align =
+    case element.attr("align").toLowerAscii()
+    of "left":
+     set_cv "margin-right", CSSLengthAuto #TODO should be float: left
+    of "right":
+      set_cv "margin-left", CSSLengthAuto #TODO should be float: right
+    of "center":
+      set_cv "margin-left", CSSLengthAuto #TODO should be inline-start
+      set_cv "margin-right", CSSLengthAuto #TODO should be inline-end
   template map_text =
     let c = parseLegacyColor(element.attr("text"))
     if c.isSome:
@@ -137,6 +146,7 @@ func calcPresentationalHints(element: Element): CSSComputedValues =
     map_height_nozero
     map_width_nozero
     map_bgcolor
+    map_table_align
   of TAG_TD, TAG_TH:
     map_height_nozero
     map_width_nozero
diff --git a/src/css/values.nim b/src/css/values.nim
index 5916bc89..82cc9419 100644
--- a/src/css/values.nim
+++ b/src/css/values.nim
@@ -446,6 +446,8 @@ func cssLength(val: float64, unit: string): CSSLength =
   else:
     raise newException(CSSValueError, "Invalid unit")
 
+const CSSLengthAuto* = CSSLength(auto: true)
+
 func parseDimensionValues*(s: string): Option[CSSLength] =
   if s == "": return
   var i = 0
@@ -560,7 +562,7 @@ func cssLength(val: CSSComponentValue, has_auto: static bool = true, allow_negat
       of CSS_IDENT_TOKEN:
         when has_auto:
           if tok.value == "auto":
-            return CSSLength(auto: true)
+            return CSSLengthAuto
       else: discard
   raise newException(CSSValueError, "Invalid length")
 
@@ -585,7 +587,7 @@ func cssWordSpacing(cval: CSSComponentValue): CSSLength =
       return cssLength(tok.nvalue, tok.unit)
     of CSS_IDENT_TOKEN:
       if tok.value == "normal":
-        return CSSLength(auto: true)
+        return CSSLengthAuto
     else: discard
   raise newException(CSSValueError, "Invalid word spacing")
 
@@ -772,7 +774,7 @@ func cssLineHeight(cval: CSSComponentValue): CSSLength =
       return cssLength(tok.nvalue * 100, "%")
     of CSS_IDENT_TOKEN:
       if tok.value == "normal":
-        return CSSLength(auto: true)
+        return CSSLengthAuto
     else:
       return cssLength(tok, has_auto = false)
   raise newException(CSSValueError, "Invalid line height")
@@ -867,7 +869,7 @@ func cssMaxMinSize(cval: CSSComponentValue): CSSLength =
     case tok.tokenType
     of CSS_IDENT_TOKEN:
       if tok.value == "none":
-        return CSSLength(auto: true)
+        return CSSLengthAuto
     of CSS_NUMBER_TOKEN, CSS_DIMENSION_TOKEN:
       return cssLength(tok, allow_negative = false)
     else: discard
@@ -986,7 +988,7 @@ func getInitialLength(t: CSSPropertyType): CSSLength =
      PROPERTY_LINE_HEIGHT, PROPERTY_LEFT, PROPERTY_RIGHT, PROPERTY_TOP,
      PROPERTY_BOTTOM, PROPERTY_MAX_WIDTH, PROPERTY_MAX_HEIGHT,
      PROPERTY_MIN_WIDTH, PROPERTY_MIN_HEIGHT:
-    return CSSLength(auto: true)
+    return CSSLengthAuto
   else:
     return CSSLength(auto: false, unit: UNIT_PX, num: 0)
 
diff --git a/src/layout/engine.nim b/src/layout/engine.nim
index f116e440..47c293b6 100644
--- a/src/layout/engine.nim
+++ b/src/layout/engine.nim
@@ -8,7 +8,6 @@ import css/stylednode
 import css/values
 import io/window
 import layout/box
-import types/color
 import utils/twtstr
 
 # Build phase
@@ -810,28 +809,10 @@ proc positionBlocks(box: BlockBox) =
   box.height += box.padding_top
 
   x += box.padding_left
-  let needsMove = box.computed{"text-align"} in {TEXT_ALIGN_CHA_LEFT, TEXT_ALIGN_CHA_CENTER, TEXT_ALIGN_CHA_RIGHT}
 
   template apply_child(child: BlockBox) =
     child.offset.y = y
     child.offset.x = x
-    if not needsMove and spec and child.contentWidth < box.contentWidth:
-      let margin_left = child.computed{"margin-left"}
-      let margin_right = child.computed{"margin-right"}
-      if margin_left.auto and margin_right.auto:
-        child.margin_left += box.contentWidth div 2
-        child.margin_left -= child.contentWidth div 2
-        child.margin_right += box.contentWidth div 2
-        child.margin_right -= child.contentWidth div 2
-      elif margin_left.auto:
-        child.margin_left += box.contentWidth
-        child.margin_left -= child.contentWidth
-      elif margin_right.auto:
-        child.margin_right += box.contentWidth
-        child.margin_right -= child.contentWidth
-    child.offset.x += child.margin_left
-    if box.computed{"position"} == POSITION_RELATIVE:
-      box.positionRelative(child)
     y += child.height
     box.height += child.height
     if not spec:
@@ -887,25 +868,42 @@ proc positionBlocks(box: BlockBox) =
   margin_todo.append(box.margin_bottom)
   box.margin_bottom = margin_todo.sum()
 
-  if needsMove:
-    # Re-position the children.
-    # The x offset for values in shrink mode depends on the parent box's
-    # width, so we can not just do this in the first pass.
-    let width = if box.shrink:
-      min(box.width, box.contentWidth)
-    else:
-      max(box.width, box.contentWidth)
+  # Re-position the children.
+  # The x offset for values in shrink mode depends on the parent box's
+  # width, so we can not just do this in the first pass.
+  let width = if box.shrink:
+    min(box.width, box.contentWidth)
+  else:
+    max(box.width, box.contentWidth)
+  for child in box.nested:
     case box.computed{"text-align"}
     of TEXT_ALIGN_CHA_CENTER:
-      for child in box.nested:
-        child.offset.x += width div 2
-        child.offset.x -= child.width div 2
+      child.offset.x += width div 2
+      child.offset.x -= child.width div 2
     of TEXT_ALIGN_CHA_LEFT: discard
     of TEXT_ALIGN_CHA_RIGHT:
-      for child in box.nested:
-        child.offset.x += width
-        child.offset.x -= child.width
-    else: discard
+      child.offset.x += width
+      child.offset.x -= child.width
+    elif child.contentWidth < box.contentWidth:
+      let margin_left = child.computed{"margin-left"}
+      let margin_right = child.computed{"margin-right"}
+      if margin_left.auto and margin_right.auto:
+        child.margin_left += width div 2
+        child.margin_left -= child.width div 2
+        child.margin_right += width div 2
+        child.margin_right -= child.width div 2
+      elif margin_left.auto:
+        child.margin_left += width
+        child.margin_left -= child.width
+      elif margin_right.auto:
+        child.margin_right += width
+        child.margin_right -= child.width
+      if not spec:
+        let marginWidth = child.width + child.margin_left + child.margin_right
+        box.width = min(box.maxContentWidth, max(marginWidth, box.width))
+    child.offset.x += child.margin_left
+    if box.computed{"position"} == POSITION_RELATIVE:
+      box.positionRelative(child)
 
   box.height += box.padding_bottom