about summary refs log tree commit diff stats
path: root/src/layout
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2022-01-30 10:56:15 +0100
committerbptato <nincsnevem662@gmail.com>2022-01-30 10:56:15 +0100
commit87a47d56cca6ded5f5cd900a9bff2e4d8292629e (patch)
tree93cdc98e998575d1cfb7637f9cec33b7533b5cb3 /src/layout
parentfb017f273dab1d63764269ca02700316919522f4 (diff)
downloadchawan-87a47d56cca6ded5f5cd900a9bff2e4d8292629e.tar.gz
Implement list-style-position
Diffstat (limited to 'src/layout')
-rw-r--r--src/layout/box.nim3
-rw-r--r--src/layout/engine.nim52
2 files changed, 52 insertions, 3 deletions
diff --git a/src/layout/box.nim b/src/layout/box.nim
index 9947cd22..f9bd2697 100644
--- a/src/layout/box.nim
+++ b/src/layout/box.nim
@@ -87,6 +87,9 @@ type
     ictx*: InlineContext
     newline*: bool
 
+  MarkerBox* = ref object of InlineBox
+    outside*: bool
+
   BlockBox* = ref object of CSSBox
     bctx*: BlockContext
 
diff --git a/src/layout/engine.nim b/src/layout/engine.nim
index 3752ce05..b9af3e6b 100644
--- a/src/layout/engine.nim
+++ b/src/layout/engine.nim
@@ -448,6 +448,30 @@ proc alignInlineBlock(bctx: BlockContext, box: InlineBlockBox) =
   box.ictx.addAtom(box.bctx, bctx.compwidth, box.specified)
   box.ictx.whitespacenum = 0
 
+# ew.
+proc alignMarkerOutside(bctx: BlockContext, box: MarkerBox) =
+  let oldwidth = box.ictx.thisrow.width
+  let oldheight = box.ictx.thisrow.height
+  assert box.text.len == 1
+  assert box.children.len == 0
+
+  box.ictx.renderText(box.text[0], bctx.compwidth, box.specified, box.node)
+  # We assume this renders one row only. But there's no guarantee it does...
+  if box.ictx.thisrow.atoms.len > 0:
+    let atom = box.ictx.thisrow.atoms[^1]
+    atom.relx -= atom.width
+
+    box.ictx.flushWhitespace(box.specified)
+    let ws = box.ictx.thisrow.atoms[^1]
+
+    # If flushWhitespace did anything
+    if ws != atom:
+      atom.relx -= ws.width
+
+    box.ictx.thisrow.width = oldwidth
+    box.ictx.height -= box.ictx.thisrow.height - oldheight
+    box.ictx.thisrow.height = oldheight
+
 proc alignInline(bctx: BlockContext, box: InlineBox) =
   assert box.ictx != nil
   if box.newline:
@@ -470,7 +494,14 @@ proc alignInline(bctx: BlockContext, box: InlineBox) =
     of DISPLAY_INLINE:
       let child = InlineBox(child)
       child.ictx = box.ictx
-      bctx.alignInline(child)
+      if child of MarkerBox:
+        let child = MarkerBox(child)
+        if child.outside:
+          bctx.alignMarkerOutside(child)
+        else:
+          bctx.alignInline(child)
+      else:
+        bctx.alignInline(child)
     of DISPLAY_INLINE_BLOCK:
       let child = InlineBlockBox(child)
       child.ictx = box.ictx
@@ -493,7 +524,14 @@ proc alignInlines(bctx: BlockContext, inlines: seq[CSSBox]) =
       of DISPLAY_INLINE:
         let child = InlineBox(child)
         child.ictx = ictx
-        bctx.alignInline(child)
+        if child of MarkerBox:
+          let child = MarkerBox(child)
+          if child.outside:
+            bctx.alignMarkerOutside(child)
+          else:
+            bctx.alignInline(child)
+        else:
+          bctx.alignInline(child)
       of DISPLAY_INLINE_BLOCK:
         let child = InlineBlockBox(child)
         child.ictx = ictx
@@ -577,6 +615,12 @@ proc getTextBox(box: CSSBox): InlineBox =
   result.inlinelayout = true
   result.specified = box.specified.inheritProperties()
 
+proc getMarkerBox(box: CSSBox): MarkerBox =
+  new(result)
+  result.t = DISPLAY_INLINE
+  result.inlinelayout = true
+  result.specified = box.specified.inheritProperties()
+
 proc getPseudoBox(bctx: BlockContext, specified: CSSSpecifiedValues): CSSBox =
   let box = getBox(specified)
 
@@ -682,9 +726,11 @@ proc generateBox(elem: Element, viewport: Viewport, bctx: BlockContext = nil): C
     var ordinalvalue = 1
     if elem.tagType == TAG_LI:
       ordinalvalue = HTMLLIElement(elem).ordinalvalue
-    let marker = box.getTextBox()
+    let marker = box.getMarkerBox()
     marker.node = elem
     marker.text.add(elem.css{"list-style-type"}.listMarker(ordinalvalue))
+    if elem.css{"list-style-position"} == LIST_STYLE_POSITION_OUTSIDE:
+      marker.outside = true
     add_box(marker)
 
   let before = elem.pseudo[PSEUDO_BEFORE]