diff options
author | bptato <nincsnevem662@gmail.com> | 2025-01-16 20:20:03 +0100 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2025-01-16 20:20:03 +0100 |
commit | 9c03cdd883e4fafabddfa355cdaf675d56596b0c (patch) | |
tree | df22b51e735dd5e478f8d7af804386c9dab6af36 /src | |
parent | 37bbe760b9b7c9c6aee8323c7766574a7ef55389 (diff) | |
download | chawan-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.nim | 8 | ||||
-rw-r--r-- | src/css/layout.nim | 83 | ||||
-rw-r--r-- | src/css/render.nim | 20 | ||||
-rw-r--r-- | src/css/stylednode.nim | 3 | ||||
-rw-r--r-- | src/server/buffer.nim | 17 |
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) |