about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2025-01-16 20:20:03 +0100
committerbptato <nincsnevem662@gmail.com>2025-01-16 20:20:03 +0100
commit9c03cdd883e4fafabddfa355cdaf675d56596b0c (patch)
treedf22b51e735dd5e478f8d7af804386c9dab6af36 /src
parent37bbe760b9b7c9c6aee8323c7766574a7ef55389 (diff)
downloadchawan-9c03cdd883e4fafabddfa355cdaf675d56596b0c.tar.gz
css: reduce StyledNode use
Eventually the tree should be collapsed into the DOM, and StyledNode
should be created on the stack.
Diffstat (limited to 'src')
-rw-r--r--src/css/box.nim8
-rw-r--r--src/css/layout.nim83
-rw-r--r--src/css/render.nim20
-rw-r--r--src/css/stylednode.nim3
-rw-r--r--src/server/buffer.nim17
5 files changed, 62 insertions, 69 deletions
diff --git a/src/css/box.nim b/src/css/box.nim
index c161316a..37d9a2d3 100644
--- a/src/css/box.nim
+++ b/src/css/box.nim
@@ -1,6 +1,6 @@
 import css/cssvalues
 import css/lunit
-import css/stylednode
+import html/dom
 import types/bitmap
 
 type
@@ -58,13 +58,13 @@ type
     state*: InlineBoxState
     render*: BoxRenderState
     computed*: CSSValues
-    node*: StyledNode
+    node*: Element
     splitType*: set[SplitType]
     case t*: InlineBoxType
     of ibtParent:
       children*: seq[InlineBox]
     of ibtText:
-      text*: StyledNode # note: this has no parent.
+      text*: CharacterData # note: this has no parent.
     of ibtNewline:
       discard
     of ibtBitmap:
@@ -112,7 +112,7 @@ type
     state*: BoxLayoutState # layout output -> render input
     render*: BoxRenderState # render output
     computed*: CSSValues
-    node*: StyledNode
+    node*: Element
     inline*: InlineBox
     children*: seq[BlockBox]
 
diff --git a/src/css/layout.nim b/src/css/layout.nim
index 595f9516..de255afa 100644
--- a/src/css/layout.nim
+++ b/src/css/layout.nim
@@ -1,10 +1,11 @@
 import std/algorithm
 import std/math
 
+import css/box
 import css/cssvalues
 import css/lunit
 import css/stylednode
-import css/box
+import html/dom
 import types/bitmap
 import types/winattrs
 import utils/luwrap
@@ -47,14 +48,18 @@ type
     positioned: seq[PositionedItem]
     myRootProperties: CSSValues
     # placeholder text data
-    imgText: StyledNode
-    audioText: StyledNode
-    videoText: StyledNode
-    iframeText: StyledNode
+    imgText: CharacterData
+    audioText: CharacterData
+    videoText: CharacterData
+    iframeText: CharacterData
     luctx: LUContext
 
 const DefaultSpan = Span(start: 0, send: LUnit.high)
 
+# Defined here so it isn't accidentally used in dom.
+func newCharacterData(data: sink string): CharacterData =
+  return CharacterData(data: data)
+
 func minWidth(sizes: ResolvedSizes): LUnit =
   return sizes.bounds.a[dtHorizontal].start
 
@@ -1688,7 +1693,7 @@ proc layoutInline(ictx: var InlineContext; box: InlineBox) =
       box.computed{"clear"})
   of ibtBox: ictx.addBox(state, box.box)
   of ibtBitmap: ictx.addImage(state, box.bmp, padding.sum())
-  of ibtText: ictx.layoutText(state, box.text.textData)
+  of ibtText: ictx.layoutText(state, box.text.data)
   of ibtParent:
     for child in box.children:
       ictx.layoutInline(child)
@@ -2809,7 +2814,7 @@ proc newMarkerBox(computed: CSSValues; listItemCounter: int):
   return InlineBox(
     t: ibtText,
     computed: computed,
-    text: newStyledText(s)
+    text: newCharacterData(s)
   )
 
 type BlockBuilderContext = object
@@ -2975,7 +2980,7 @@ proc reconstructInlineParents(ctx: var BlockBuilderContext) =
     var parent = InlineBox(
       t: ibtParent,
       computed: ctx.inlineStack[0].computed,
-      node: ctx.inlineStack[0]
+      node: ctx.inlineStack[0].element
     )
     ctx.inlineStackFragments.add(parent)
     ctx.addInlineRoot(parent)
@@ -2984,7 +2989,7 @@ proc reconstructInlineParents(ctx: var BlockBuilderContext) =
       let child = InlineBox(
         t: ibtParent,
         computed: node.computed,
-        node: node
+        node: node.element
       )
       parent.children.add(child)
       ctx.inlineStackFragments.add(child)
@@ -2992,7 +2997,7 @@ proc reconstructInlineParents(ctx: var BlockBuilderContext) =
 
 proc buildSomeBlock(ctx: var BlockBuilderContext; styledNode: StyledNode;
     computed: CSSValues): BlockBox =
-  let box = BlockBox(computed: computed, node: styledNode)
+  let box = BlockBox(computed: computed, node: styledNode.element)
   var childCtx = initBlockBuilderContext(styledNode, box, ctx.lctx, addr ctx)
   case computed{"display"}
   of DisplayBlock, DisplayFlowRoot, DisplayInlineBlock: childCtx.buildBlock()
@@ -3022,12 +3027,12 @@ proc pushInline(ctx: var BlockBuilderContext; box: InlineBox) =
     ctx.inlineStackFragments[^1].children.add(box)
 
 proc pushInlineText(ctx: var BlockBuilderContext; computed: CSSValues;
-    parent, node: StyledNode) =
+    parent: Element; text: CharacterData) =
   ctx.pushInline(InlineBox(
     t: ibtText,
     computed: computed,
     node: parent,
-    text: node
+    text: text
   ))
 
 proc pushInlineBlock(ctx: var BlockBuilderContext; styledNode: StyledNode;
@@ -3035,7 +3040,7 @@ proc pushInlineBlock(ctx: var BlockBuilderContext; styledNode: StyledNode;
   ctx.pushInline(InlineBox(
     t: ibtBox,
     computed: computed.inheritProperties(),
-    node: styledNode,
+    node: styledNode.element,
     box: ctx.buildSomeBlock(styledNode, computed)
   ))
 
@@ -3046,7 +3051,7 @@ proc pushListItem(ctx: var BlockBuilderContext; styledNode: StyledNode;
   inc ctx.listItemCounter
   let marker = newMarkerBox(computed, ctx.listItemCounter)
   let position = computed{"list-style-position"}
-  let content = BlockBox(computed: computed, node: styledNode)
+  let content = BlockBox(computed: computed, node: styledNode.element)
   var contentCtx = initBlockBuilderContext(styledNode, content, ctx.lctx,
     addr ctx)
   case position
@@ -3150,8 +3155,8 @@ proc buildFromElem(ctx: var BlockBuilderContext; styledNode: StyledNode;
   of DisplayNone: discard
   of DisplayTableWrapper, DisplayInlineTableWrapper: assert false
 
-proc buildReplacement(ctx: var BlockBuilderContext; child, parent: StyledNode;
-    computed: CSSValues) =
+proc buildReplacement(ctx: var BlockBuilderContext; child: StyledNode;
+    parent: Element; computed: CSSValues) =
   case child.content.t
   of ContentNone: assert false # unreachable for `content'
   of ContentOpenQuote:
@@ -3162,7 +3167,7 @@ proc buildReplacement(ctx: var BlockBuilderContext; child, parent: StyledNode;
       quotes.qs[min(ctx.quoteLevel, quotes.qs.high)].s
     else:
       return
-    let node = newStyledText(s)
+    let node = newCharacterData(s)
     ctx.pushInlineText(computed, parent, node)
     inc ctx.quoteLevel
   of ContentCloseQuote:
@@ -3175,14 +3180,14 @@ proc buildReplacement(ctx: var BlockBuilderContext; child, parent: StyledNode;
       quotes.qs[min(ctx.quoteLevel, quotes.qs.high)].e
     else:
       return
-    let text = newStyledText(s)
+    let text = newCharacterData(s)
     ctx.pushInlineText(computed, parent, text)
   of ContentNoOpenQuote:
     inc ctx.quoteLevel
   of ContentNoCloseQuote:
     if ctx.quoteLevel > 0: dec ctx.quoteLevel
   of ContentString:
-    let text = newStyledText(child.content.s)
+    let text = newCharacterData(child.content.s)
     ctx.pushInlineText(computed, parent, text)
   of ContentImage:
     if child.content.bmp != nil:
@@ -3204,7 +3209,7 @@ proc buildReplacement(ctx: var BlockBuilderContext; child, parent: StyledNode;
     ctx.pushInline(InlineBox(
       t: ibtNewline,
       computed: computed,
-      node: child
+      node: child.element
     ))
 
 proc buildInlineBoxes(ctx: var BlockBuilderContext; styledNode: StyledNode;
@@ -3213,7 +3218,7 @@ proc buildInlineBoxes(ctx: var BlockBuilderContext; styledNode: StyledNode;
     t: ibtParent,
     computed: computed,
     splitType: {stSplitStart},
-    node: styledNode
+    node: styledNode.element
   )
   if ctx.inlineStack.len == 0:
     ctx.addInlineRoot(parent)
@@ -3228,10 +3233,10 @@ proc buildInlineBoxes(ctx: var BlockBuilderContext; styledNode: StyledNode;
       ctx.buildFromElem(child, child.computed)
     of stText:
       ctx.flushInlineTable()
-      ctx.pushInlineText(computed, styledNode, child)
+      ctx.pushInlineText(computed, styledNode.element, child.text)
     of stReplacement:
       ctx.flushInlineTable()
-      ctx.buildReplacement(child, styledNode, computed)
+      ctx.buildReplacement(child, styledNode.element, computed)
   ctx.reconstructInlineParents()
   ctx.flushInlineTable()
   let box = ctx.inlineStackFragments.pop()
@@ -3262,10 +3267,11 @@ proc buildInnerBlock(ctx: var BlockBuilderContext) =
     of stElement:
       ctx.buildFromElem(child, child.computed)
     of stText:
-      if ctx.canBuildAnonInline(ctx.outer.computed, child.textData):
-        ctx.pushInlineText(inlineComputed, ctx.styledNode, child)
+      let text = child.text
+      if ctx.canBuildAnonInline(ctx.outer.computed, text.data):
+        ctx.pushInlineText(inlineComputed, ctx.styledNode.element, text)
     of stReplacement:
-      ctx.buildReplacement(child, ctx.styledNode, inlineComputed)
+      ctx.buildReplacement(child, ctx.styledNode.element, inlineComputed)
   ctx.iflush()
 
 proc buildBlock(ctx: var BlockBuilderContext) =
@@ -3297,10 +3303,11 @@ proc buildInnerFlex(ctx: var BlockBuilderContext) =
         child.computed
       ctx.buildFromElem(child, computed)
     of stText:
-      if ctx.canBuildAnonInline(ctx.outer.computed, child.textData):
-        ctx.pushInlineText(inlineComputed, ctx.styledNode, child)
+      let text = child.text
+      if ctx.canBuildAnonInline(ctx.outer.computed, text.data):
+        ctx.pushInlineText(inlineComputed, ctx.styledNode.element, text)
     of stReplacement:
-      ctx.buildReplacement(child, ctx.styledNode, inlineComputed)
+      ctx.buildReplacement(child, ctx.styledNode.element, inlineComputed)
   ctx.iflush()
 
 proc buildFlex(ctx: var BlockBuilderContext) =
@@ -3314,7 +3321,7 @@ proc buildFlex(ctx: var BlockBuilderContext) =
 
 proc buildTableCell(parent: var BlockBuilderContext; styledNode: StyledNode;
     computed: CSSValues): BlockBox =
-  let box = BlockBox(node: styledNode, computed: computed)
+  let box = BlockBox(node: styledNode.element, computed: computed)
   var ctx = initBlockBuilderContext(styledNode, box, parent.lctx, addr parent)
   ctx.buildInnerBlock()
   ctx.flush()
@@ -3344,7 +3351,7 @@ proc buildTableRowChildWrappers(box: BlockBox) =
 
 proc buildTableRow(parent: var BlockBuilderContext; styledNode: StyledNode;
     computed: CSSValues): BlockBox =
-  let box = BlockBox(node: styledNode, computed: computed)
+  let box = BlockBox(node: styledNode.element, computed: computed)
   var ctx = initBlockBuilderContext(styledNode, box, parent.lctx, addr parent)
   ctx.buildInnerBlock()
   ctx.flush()
@@ -3379,7 +3386,7 @@ proc buildTableRowGroupChildWrappers(box: BlockBox) =
 
 proc buildTableRowGroup(parent: var BlockBuilderContext; styledNode: StyledNode;
     computed: CSSValues): BlockBox =
-  let box = BlockBox(node: styledNode, computed: computed)
+  let box = BlockBox(node: styledNode.element, computed: computed)
   var ctx = initBlockBuilderContext(styledNode, box, parent.lctx, addr parent)
   ctx.buildInnerBlock()
   ctx.flush()
@@ -3388,7 +3395,7 @@ proc buildTableRowGroup(parent: var BlockBuilderContext; styledNode: StyledNode;
 
 proc buildTableCaption(parent: var BlockBuilderContext; styledNode: StyledNode;
     computed: CSSValues): BlockBox =
-  let box = BlockBox(node: styledNode, computed: computed)
+  let box = BlockBox(node: styledNode.element, computed: computed)
   var ctx = initBlockBuilderContext(styledNode, box, parent.lctx, addr parent)
   ctx.buildInnerBlock()
   ctx.flush()
@@ -3438,13 +3445,13 @@ proc layout*(root: StyledNode; attrsp: ptr WindowAttributes): BlockBox =
     cellSize: size(w = attrsp.ppc, h = attrsp.ppl),
     positioned: @[PositionedItem(), PositionedItem()],
     myRootProperties: rootProperties(),
-    imgText: newStyledText("[img]"),
-    videoText: newStyledText("[video]"),
-    audioText: newStyledText("[audio]"),
-    iframeText: newStyledText("[iframe]"),
+    imgText: newCharacterData("[img]"),
+    videoText: newCharacterData("[video]"),
+    audioText: newCharacterData("[audio]"),
+    iframeText: newCharacterData("[iframe]"),
     luctx: LUContext()
   )
-  let box = BlockBox(computed: root.computed, node: root)
+  let box = BlockBox(computed: root.computed, node: root.element)
   var ctx = initBlockBuilderContext(root, box, lctx, nil)
   ctx.buildBlock()
   let sizes = lctx.resolveBlockSizes(space, box.computed)
diff --git a/src/css/render.nim b/src/css/render.nim
index ebe0b1cc..2949dc26 100644
--- a/src/css/render.nim
+++ b/src/css/render.nim
@@ -3,7 +3,7 @@ import std/algorithm
 import css/box
 import css/cssvalues
 import css/lunit
-import css/stylednode
+import html/dom
 import types/bitmap
 import types/cell
 import types/color
@@ -17,7 +17,7 @@ type
   FormatCell* = object
     format*: Format
     pos*: int
-    node*: StyledNode
+    node*: Element
 
   # Following properties should hold for `formats':
   # * Position should be >= 0, <= str.width().
@@ -80,11 +80,11 @@ proc insertFormat(line: var FlexibleLine; i: int; cell: FormatCell) =
   line.formats.insert(cell, i)
 
 proc insertFormat(line: var FlexibleLine; pos, i: int; format: Format;
-    node: StyledNode = nil) =
+    node: Element = nil) =
   line.insertFormat(i, FormatCell(format: format, node: node, pos: pos))
 
 proc addFormat(line: var FlexibleLine; pos: int; format: Format;
-    node: StyledNode = nil) =
+    node: Element = nil) =
   line.formats.add(FormatCell(format: format, node: node, pos: pos))
 
 func toFormat(computed: CSSValues): Format =
@@ -148,7 +148,7 @@ proc setTextStr(line: var FlexibleLine; s, ostr: openArray[char];
     copyMem(addr line.str[i], unsafeAddr ostr[0], ostr.len)
 
 proc setTextFormat(line: var FlexibleLine; x, cx, nx: int; ostr: string;
-    format: Format; node: StyledNode) =
+    format: Format; node: Element) =
   var fi = line.findFormatN(cx) - 1 # Skip unchanged formats before new string
   if x > cx:
     # Replace formats for padding
@@ -185,7 +185,7 @@ proc setTextFormat(line: var FlexibleLine; x, cx, nx: int; ostr: string;
   # Now for the text's formats:
   var format = format
   var lformat: Format
-  var lnode: StyledNode
+  var lnode: Element = nil
   if fi == -1:
     # No formats => just insert a new format at 0
     inc fi
@@ -232,7 +232,7 @@ proc setTextFormat(line: var FlexibleLine; x, cx, nx: int; ostr: string;
   # That's it!
 
 proc setText0(line: var FlexibleLine; s: openArray[char]; x, targetX: int;
-    format: Format; node: StyledNode) =
+    format: Format; node: Element) =
   assert x >= 0 and s.len != 0
   var i = 0
   let cx = line.findFirstX(x, i) # first x of new string (before padding)
@@ -245,7 +245,7 @@ proc setText0(line: var FlexibleLine; s: openArray[char]; x, targetX: int;
   line.setTextFormat(x, cx, nx, ostr, format, node)
 
 proc setText(grid: var FlexibleGrid; state: var RenderState; s: string;
-    offset: Offset; format: Format; node: StyledNode) =
+    offset: Offset; format: Format; node: Element) =
   if offset.y notin state.clipBox.start.y ..< state.clipBox.send.y:
     return
   if offset.x > state.clipBox.send.x:
@@ -272,7 +272,7 @@ proc setText(grid: var FlexibleGrid; state: var RenderState; s: string;
     grid[y].setText0(s.toOpenArray(i, j - 1), x, targetX, format, node)
 
 proc paintBackground(grid: var FlexibleGrid; state: var RenderState;
-    color: CellColor; startx, starty, endx, endy: int; node: StyledNode;
+    color: CellColor; startx, starty, endx, endy: int; node: Element;
     noPaint = false) =
   let clipBox = addr state.clipBox
   var startx = startx
@@ -388,7 +388,7 @@ proc renderInlineBox(grid: var FlexibleGrid; state: var RenderState;
             let y1 = offset.y.toInt
             let x2 = x2p.toInt
             let y2 = y2p.toInt
-            # add StyledNode to background (but don't actually color it)
+            # add Element to background (but don't actually color it)
             grid.paintBackground(state, defaultColor, x1, y1, x2, y2,
               box.node, noPaint = true)
             let x = (offset.x div state.attrs.ppc).toInt
diff --git a/src/css/stylednode.nim b/src/css/stylednode.nim
index 5572b949..933439d2 100644
--- a/src/css/stylednode.nim
+++ b/src/css/stylednode.nim
@@ -112,9 +112,6 @@ func newStyledElement*(parent: StyledNode; pseudo: PseudoElement): StyledNode =
 func newStyledText*(parent: StyledNode; text: Text): StyledNode =
   return StyledNode(t: stText, text: text, element: parent.element)
 
-func newStyledText*(text: sink string): StyledNode =
-  return StyledNode(t: stText, text: CharacterData(data: text))
-
 func newStyledReplacement*(parent: StyledNode; content: sink CSSContent;
     pseudo: PseudoElement): StyledNode =
   return StyledNode(
diff --git a/src/server/buffer.nim b/src/server/buffer.nim
index b5fc6629..c80f1b07 100644
--- a/src/server/buffer.nim
+++ b/src/server/buffer.nim
@@ -345,11 +345,6 @@ proc getClickable(element: Element): Element =
       return element
   return nil
 
-proc getClickable(styledNode: StyledNode): Element =
-  if styledNode == nil:
-    return nil
-  return styledNode.element.getClickable()
-
 func canSubmitOnClick(fae: FormAssociatedElement): bool =
   if fae.form == nil:
     return false
@@ -414,18 +409,12 @@ proc getCachedImageHover(buffer: Buffer; element: Element): string =
       return $image.bitmap.cacheId & ' ' & image.bitmap.contentType
   ""
 
-func getCursorStyledNode(buffer: Buffer; cursorx, cursory: int): StyledNode =
+func getCursorElement(buffer: Buffer; cursorx, cursory: int): Element =
   let i = buffer.lines[cursory].findFormatN(cursorx) - 1
   if i >= 0:
     return buffer.lines[cursory].formats[i].node
   return nil
 
-func getCursorElement(buffer: Buffer; cursorx, cursory: int): Element =
-  let styledNode = buffer.getCursorStyledNode(cursorx, cursory)
-  if styledNode == nil:
-    return nil
-  return styledNode.element
-
 proc getCursorClickable(buffer: Buffer; cursorx, cursory: int): Element =
   let element = buffer.getCursorElement(cursorx, cursory)
   if element != nil:
@@ -690,7 +679,7 @@ proc findAnchor(box: InlineBox; anchor: Element): Offset =
       let off = child.findAnchor(anchor)
       if off.y >= 0:
         return off
-  if box.node != nil and box.node.element == anchor:
+  if box.node == anchor:
     return box.render.offset
   return offset(-1, -1)
 
@@ -703,7 +692,7 @@ proc findAnchor(box: BlockBox; anchor: Element): Offset =
     let off = child.findAnchor(anchor)
     if off.y >= 0:
       return off
-  if box.node != nil and box.node.element == anchor:
+  if box.node == anchor:
     return box.render.offset
   return offset(-1, -1)