diff options
author | bptato <nincsnevem662@gmail.com> | 2023-06-07 19:46:19 +0200 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2023-06-07 19:58:42 +0200 |
commit | 75310d68b875964c757c73ab1df791cda6fba756 (patch) | |
tree | d435fcdd9511bbf6f9f02cf380d7d0c45daaf97b /src | |
parent | 578df008d0e2e6ac2d8ee2ad84ccf640f8d07c55 (diff) | |
download | chawan-75310d68b875964c757c73ab1df791cda6fba756.tar.gz |
Add support for visibility
Diffstat (limited to 'src')
-rw-r--r-- | src/buffer/buffer.nim | 33 | ||||
-rw-r--r-- | src/css/values.nim | 30 | ||||
-rw-r--r-- | src/layout/engine.nim | 2 | ||||
-rw-r--r-- | src/render/renderdocument.nim | 44 |
4 files changed, 65 insertions, 44 deletions
diff --git a/src/buffer/buffer.nim b/src/buffer/buffer.nim index 8775e0e6..acfbad19 100644 --- a/src/buffer/buffer.nim +++ b/src/buffer/buffer.nim @@ -17,6 +17,7 @@ import css/cssparser import css/mediaquery import css/sheet import css/stylednode +import css/values import config/config import data/charset import html/dom @@ -264,26 +265,22 @@ const ClickableElements = { TAG_A, TAG_INPUT, TAG_OPTION, TAG_BUTTON, TAG_TEXTAREA, TAG_LABEL } +func isClickable(styledNode: StyledNode): bool = + if styledNode.t != STYLED_ELEMENT or styledNode.node == nil: + return false + if styledNode.computed{"visibility"} != VISIBILITY_VISIBLE: + return false + let element = Element(styledNode.node) + if element.tagType == TAG_A: + return HTMLAnchorElement(element).href != "" + return element.tagType in ClickableElements + func getClickable(styledNode: StyledNode): Element = - if styledNode == nil: - return nil var styledNode = styledNode - while styledNode.node == nil: - styledNode = styledNode.parent - if styledNode == nil: - return nil - if styledNode.t == STYLED_ELEMENT: - let element = Element(styledNode.node) - if element.tagType in ClickableElements and (element.tagType != TAG_A or HTMLAnchorElement(element).href != ""): - return element - var node = styledNode.node - while true: - result = node.findAncestor(ClickableElements) - if result == nil: - break - if result.tagType != TAG_A or HTMLAnchorElement(result).href != "": - break - node = result + while styledNode != nil: + if styledNode.isClickable(): + return Element(styledNode.node) + styledNode = stylednode.parent func submitForm(form: HTMLFormElement, submitter: Element): Option[Request] diff --git a/src/css/values.nim b/src/css/values.nim index 2204e6ab..99d1bc76 100644 --- a/src/css/values.nim +++ b/src/css/values.nim @@ -36,7 +36,8 @@ type PROPERTY_BORDER_SPACING, PROPERTY_BORDER_COLLAPSE, PROPERTY_QUOTES, PROPERTY_COUNTER_RESET, PROPERTY_MAX_WIDTH, PROPERTY_MAX_HEIGHT, PROPERTY_MIN_WIDTH, PROPERTY_MIN_HEIGHT, PROPERTY_BACKGROUND_IMAGE, - PROPERTY_CHA_COLSPAN, PROPERTY_CHA_ROWSPAN, PROPERTY_FLOAT + PROPERTY_CHA_COLSPAN, PROPERTY_CHA_ROWSPAN, PROPERTY_FLOAT, + PROPERTY_VISIBILITY CSSValueType* = enum VALUE_NONE, VALUE_LENGTH, VALUE_COLOR, VALUE_CONTENT, VALUE_DISPLAY, @@ -44,7 +45,7 @@ type VALUE_WORD_BREAK, VALUE_LIST_STYLE_TYPE, VALUE_VERTICAL_ALIGN, VALUE_TEXT_ALIGN, VALUE_LIST_STYLE_POSITION, VALUE_POSITION, VALUE_CAPTION_SIDE, VALUE_LENGTH2, VALUE_BORDER_COLLAPSE, VALUE_QUOTES, - VALUE_COUNTER_RESET, VALUE_IMAGE, VALUE_FLOAT + VALUE_COUNTER_RESET, VALUE_IMAGE, VALUE_FLOAT, VALUE_VISIBILITY CSSGlobalValueType* = enum VALUE_NOGLOBAL, VALUE_INITIAL, VALUE_INHERIT, VALUE_REVERT, VALUE_UNSET @@ -109,6 +110,9 @@ type CSSFloat* = enum FLOAT_NONE, FLOAT_LEFT, FLOAT_RIGHT + CSSVisibility* = enum + VISIBILITY_VISIBLE, VISIBILITY_HIDDEN, VISIBILITY_COLLAPSE + const RowGroupBox* = {DISPLAY_TABLE_ROW_GROUP, DISPLAY_TABLE_HEADER_GROUP, DISPLAY_TABLE_FOOTER_GROUP} const ProperTableChild* = {DISPLAY_TABLE_ROW, DISPLAY_TABLE_COLUMN, @@ -187,6 +191,8 @@ type image*: CSSContent of VALUE_FLOAT: float*: CSSFloat + of VALUE_VISIBILITY: + visibility*: CSSVisibility of VALUE_NONE: discard CSSComputedValues* = ref array[CSSPropertyType, CSSComputedValue] @@ -261,7 +267,8 @@ const PropertyNames = { "background-image": PROPERTY_BACKGROUND_IMAGE, "-cha-colspan": PROPERTY_CHA_COLSPAN, "-cha-rowspan": PROPERTY_CHA_ROWSPAN, - "float": PROPERTY_FLOAT + "float": PROPERTY_FLOAT, + "visibility": PROPERTY_VISIBILITY }.toTable() const ValueTypes* = [ @@ -308,7 +315,8 @@ const ValueTypes* = [ PROPERTY_BACKGROUND_IMAGE: VALUE_IMAGE, PROPERTY_CHA_COLSPAN: VALUE_INTEGER, PROPERTY_CHA_ROWSPAN: VALUE_INTEGER, - PROPERTY_FLOAT: VALUE_FLOAT + PROPERTY_FLOAT: VALUE_FLOAT, + PROPERTY_VISIBILITY: VALUE_VISIBILITY ] const InheritedProperties = { @@ -316,7 +324,8 @@ const InheritedProperties = { PROPERTY_FONT_WEIGHT, PROPERTY_TEXT_DECORATION, PROPERTY_WORD_BREAK, PROPERTY_LIST_STYLE_TYPE, PROPERTY_WORD_SPACING, PROPERTY_LINE_HEIGHT, PROPERTY_TEXT_ALIGN, PROPERTY_LIST_STYLE_POSITION, PROPERTY_CAPTION_SIDE, - PROPERTY_BORDER_SPACING, PROPERTY_BORDER_COLLAPSE, PROPERTY_QUOTES + PROPERTY_BORDER_SPACING, PROPERTY_BORDER_COLLAPSE, PROPERTY_QUOTES, + PROPERTY_VISIBILITY } func getPropInheritedArray(): array[CSSPropertyType, bool] = @@ -938,6 +947,16 @@ func cssFloat(cval: CSSComponentValue): CSSFloat = of "right": return FLOAT_RIGHT raise newException(CSSValueError, "Invalid float") +func cssVisibility(cval: CSSComponentValue): CSSVisibility = + if isToken(cval): + let tok = getToken(cval) + if tok.tokenType == CSS_IDENT_TOKEN: + case tok.value + of "visible": return VISIBILITY_VISIBLE + of "hidden": return VISIBILITY_HIDDEN + of "collapse": return VISIBILITY_COLLAPSE + raise newException(CSSValueError, "Invalid visibility") + proc getValueFromDecl(val: CSSComputedValue, d: CSSDeclaration, vtype: CSSValueType, ptype: CSSPropertyType) = var i = 0 d.value.skipWhitespace(i) @@ -994,6 +1013,7 @@ proc getValueFromDecl(val: CSSComputedValue, d: CSSDeclaration, vtype: CSSValueT of VALUE_COUNTER_RESET: val.counterreset = cssCounterReset(d) of VALUE_IMAGE: val.image = cssImage(cval) of VALUE_FLOAT: val.float = cssFloat(cval) + of VALUE_VISIBILITY: val.visibility = cssVisibility(cval) of VALUE_NONE: discard func getInitialColor(t: CSSPropertyType): RGBAColor = diff --git a/src/layout/engine.nim b/src/layout/engine.nim index 92eeabbc..edc6c2b2 100644 --- a/src/layout/engine.nim +++ b/src/layout/engine.nim @@ -1148,6 +1148,8 @@ proc buildTableLayout(table: BlockBox, builder: TableBoxBuilder) = dec n var y = 0 for roww in ctx.rows: + if roww.builder.computed{"visibility"} == VISIBILITY_COLLAPSE: + continue y += ctx.blockspacing let row = ctx.buildTableRow(roww, table, roww.builder) row.offset.y += y diff --git a/src/render/renderdocument.nim b/src/render/renderdocument.nim index 301eefc8..0cdd8075 100644 --- a/src/render/renderdocument.nim +++ b/src/render/renderdocument.nim @@ -332,30 +332,32 @@ proc renderBlockBox(grid: var FlexibleGrid, box: BlockBox, x, y: int, window: Wi posx = x posy = y - if box.computed{"background-color"}.a != 0: #TODO color blending - grid.paintBackground(box.computed{"background-color"}, x, y, x + box.width, y + box.height, box.node, window) - if box.computed{"background-image"}.t == CONTENT_IMAGE and box.computed{"background-image"}.s != "": - # ugly hack for background-image display... TODO actually display images - let s = "[img]" - let w = s.len * window.ppc - var ix = x - if box.width < w: - # text is larger than image; center it to minimize error - ix -= w div 2 - ix += box.width div 2 - let x = ix div window.ppc - let y = y div window.ppl - if y >= 0 and x + w >= 0: - grid.setText(s, ComputedFormat(node: box.node), x, y) - - if box of ListItemBox: - let box = ListItemBox(box) - if box.marker != nil: - grid.renderInlineContext(box.marker, x - box.marker.width, y, window) + if box.computed{"visibility"} == VISIBILITY_VISIBLE: + if box.computed{"background-color"}.a != 0: #TODO color blending + grid.paintBackground(box.computed{"background-color"}, x, y, x + box.width, y + box.height, box.node, window) + if box.computed{"background-image"}.t == CONTENT_IMAGE and box.computed{"background-image"}.s != "": + # ugly hack for background-image display... TODO actually display images + let s = "[img]" + let w = s.len * window.ppc + var ix = x + if box.width < w: + # text is larger than image; center it to minimize error + ix -= w div 2 + ix += box.width div 2 + let x = ix div window.ppc + let y = y div window.ppl + if y >= 0 and x + w >= 0: + grid.setText(s, ComputedFormat(node: box.node), x, y) + + if box of ListItemBox: + let box = ListItemBox(box) + if box.marker != nil: + grid.renderInlineContext(box.marker, x - box.marker.width, y, window) if box.inline != nil: assert box.nested.len == 0 - grid.renderInlineContext(box.inline, x, y, window) + if box.computed{"visibility"} == VISIBILITY_VISIBLE: + grid.renderInlineContext(box.inline, x, y, window) else: for i in countdown(box.nested.high, 0): stack.add((box.nested[i], x, y, posx, posy)) |