about summary refs log tree commit diff stats
path: root/src/css/layout.nim
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2025-03-27 18:27:17 +0100
committerbptato <nincsnevem662@gmail.com>2025-03-27 18:27:17 +0100
commit0611a6b84a3c45ee65d90b48a7a40fd6e05571cd (patch)
tree69aaaebebabba2b55251f8a5930c8fd820fa9095 /src/css/layout.nim
parentd0797e696475784e4f104b4ee48050c51a69f501 (diff)
downloadchawan-0611a6b84a3c45ee65d90b48a7a40fd6e05571cd.tar.gz
layout: reimplement list items with out-of-flow markers
Instead of generating a separate container box for list items, just set
the marker's display to an internal value that is treated specially.

This fixes a bug where position: relative would not register the correct
block as the positioned ancestor.
Diffstat (limited to 'src/css/layout.nim')
-rw-r--r--src/css/layout.nim39
1 files changed, 11 insertions, 28 deletions
diff --git a/src/css/layout.nim b/src/css/layout.nim
index 289c57a3..408a83f8 100644
--- a/src/css/layout.nim
+++ b/src/css/layout.nim
@@ -1735,7 +1735,7 @@ proc layoutOuterBlock(fstate: var FlowState; child: BlockBox;
         (fstate.lbstate.unpositionedFloats.len == 0 or
         not fstate.lbstate.unpositionedFloats[^1].newLine):
       # We can still cram floats into the line.
-      if child.computed{"float"} == FloatLeft:
+      if float == FloatLeft:
         fstate.lbstate.size.w += outerSize.w
         for iastate in fstate.lbstate.iastates.mitems:
           iastate.offset.x += outerSize.w
@@ -1763,6 +1763,15 @@ proc layoutInlineBlock(fstate: var FlowState; ibox: InlineBlockBox) =
       # Aligning min-content or max-content is nonsensical.
       textAlign = TextAlignLeft
     fstate.layoutOuterBlock(box, textAlign)
+  elif box.computed{"display"} == DisplayMarker:
+    # Marker box. This is a mixture of absolute and inline-block
+    # layout, where we don't care about the parent size but want to
+    # place ourselves outside the left edge of our parent box.
+    let lctx = fstate.lctx
+    var sizes = lctx.resolveFloatSizes(fstate.space, box.computed)
+    lctx.layoutRootBlock(box, sizes.margin.topLeft, sizes)
+    fstate.initLine(flag = ilfAbsolute)
+    box.state.offset.x = fstate.lbstate.size.w - box.state.size.w
   else:
     # A real inline block.
     let lctx = fstate.lctx
@@ -2111,30 +2120,6 @@ proc layoutFlow(bctx: var BlockContext; box: BlockBox; sizes: ResolvedSizes;
       size.h = max(size.h, bctx.maxFloatHeight)
     bctx.lctx.popPositioned(box, size)
 
-proc layoutListItem(bctx: var BlockContext; box: BlockBox;
-    sizes: ResolvedSizes) =
-  case box.computed{"list-style-position"}
-  of ListStylePositionOutside:
-    let marker = BlockBox(box.firstChild)
-    let content = BlockBox(marker.next)
-    content.resetState()
-    content.state.offset = box.state.offset
-    bctx.layoutFlow(content, sizes, canClear = true)
-    let markerSizes = ResolvedSizes(
-      space: availableSpace(w = fitContent(sizes.space.w), h = sizes.space.h),
-      bounds: DefaultBounds
-    )
-    bctx.lctx.layoutRootBlock(marker, offset(x = 0, y = 0), markerSizes)
-    #TODO put markers right before the first atom of the list item
-    # instead
-    marker.state.offset.x = -marker.state.size.w
-    # take inner box min width etc.
-    box.resetState()
-    box.state = content.state
-    content.state.offset = offset(x = 0, y = 0)
-  of ListStylePositionInside:
-    bctx.layoutFlow(box, sizes, canClear = true)
-
 # Table layout. We try to emulate w3m's behavior here:
 # 1. Calculate minimum and preferred width of each column
 # 2. If column width is not auto, set width to max(min_col_width, specified)
@@ -2625,10 +2610,8 @@ proc layoutTable(bctx: BlockContext; box: BlockBox; sizes: ResolvedSizes) =
 proc layout(bctx: var BlockContext; box: BlockBox; sizes: ResolvedSizes;
     canClear: bool) =
   case box.computed{"display"}
-  of DisplayBlock, DisplayFlowRoot, DisplayTableCaption, DisplayInlineBlock:
+  of DisplayInnerBlock:
     bctx.layoutFlow(box, sizes, canClear)
-  of DisplayListItem:
-    bctx.layoutListItem(box, sizes)
   of DisplayInnerTable:
     bctx.layoutTable(box, sizes)
   of DisplayInnerFlex: