diff options
author | bptato <nincsnevem662@gmail.com> | 2022-12-27 23:36:13 +0100 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2022-12-27 23:42:28 +0100 |
commit | b5cffb3d805714767f2568b09fe86bb3a83d10b7 (patch) | |
tree | d9106729545b5b3915bfd3a97cf08f8da0d82619 /src/css | |
parent | 65b0b48f445b6c56016a3c842089ef117a9298bc (diff) | |
download | chawan-b5cffb3d805714767f2568b09fe86bb3a83d10b7.tar.gz |
layout/engine: get rid of dom dependency
Layout should only depend on cascading.
Diffstat (limited to 'src/css')
-rw-r--r-- | src/css/cascade.nim | 57 | ||||
-rw-r--r-- | src/css/selectorparser.nim | 2 | ||||
-rw-r--r-- | src/css/values.nim | 37 |
3 files changed, 73 insertions, 23 deletions
diff --git a/src/css/cascade.nim b/src/css/cascade.nim index 1207444d..633bf0f5 100644 --- a/src/css/cascade.nim +++ b/src/css/cascade.nim @@ -74,49 +74,61 @@ func calcRules(styledNode: StyledNode, sheet: CSSStylesheet): DeclarationList = dl func calcPresentationalHints(element: Element): CSSComputedValues = - template set_cv(a, b, c: untyped) = + template set_cv(a, b: untyped) = if result == nil: new(result) - result[a] = CSSComputedValue(t: a, v: ValueTypes[a], b: c) + result{a} = b template map_width = let s = parseDimensionValues(element.attr("width")) if s.isSome: - set_cv(PROPERTY_WIDTH, length, s.get) + set_cv "width", s.get template map_height = let s = parseDimensionValues(element.attr("height")) if s.isSome: - set_cv(PROPERTY_HEIGHT, length, s.get) + set_cv "height", s.get template map_width_nozero = let s = parseDimensionValues(element.attr("width")) if s.isSome and s.get.num != 0: - set_cv(PROPERTY_WIDTH, length, s.get) + set_cv "width", s.get template map_height_nozero = let s = parseDimensionValues(element.attr("height")) if s.isSome and s.get.num != 0: - set_cv(PROPERTY_HEIGHT, length, s.get) + set_cv "height", s.get template map_bgcolor = let c = parseLegacyColor(element.attr("bgcolor")) if c.isSome: - set_cv(PROPERTY_BACKGROUND_COLOR, color, c.get) + set_cv "background-color", c.get template map_valign = case element.attr("valign").toLowerAscii() - of "top": set_cv(PROPERTY_VERTICAL_ALIGN, verticalalign, CSSVerticalAlign(keyword: VERTICAL_ALIGN_TOP)) - of "middle": set_cv(PROPERTY_VERTICAL_ALIGN, verticalalign, CSSVerticalAlign(keyword: VERTICAL_ALIGN_MIDDLE)) - of "bottom": set_cv(PROPERTY_VERTICAL_ALIGN, verticalalign, CSSVerticalAlign(keyword: VERTICAL_ALIGN_BOTTOM)) - of "baseline": set_cv(PROPERTY_VERTICAL_ALIGN, verticalalign, CSSVerticalAlign(keyword: VERTICAL_ALIGN_BASELINE)) + of "top": set_cv "vertical-align", CSSVerticalAlign(keyword: VERTICAL_ALIGN_TOP) + of "middle": set_cv "vertical-align", CSSVerticalAlign(keyword: VERTICAL_ALIGN_MIDDLE) + of "bottom": set_cv "vertical-align", CSSVerticalAlign(keyword: VERTICAL_ALIGN_BOTTOM) + of "baseline": set_cv "vertical-align", CSSVerticalAlign(keyword: VERTICAL_ALIGN_BASELINE) template map_align = case element.attr("align").toLowerAscii() - of "center", "middle": set_cv(PROPERTY_TEXT_ALIGN, textalign, TEXT_ALIGN_CHA_CENTER) - of "left": set_cv(PROPERTY_TEXT_ALIGN, textalign, TEXT_ALIGN_CHA_LEFT) - of "right": set_cv(PROPERTY_TEXT_ALIGN, textalign, TEXT_ALIGN_CHA_RIGHT) + of "center", "middle": set_cv "text-align", TEXT_ALIGN_CHA_CENTER + of "left": set_cv "text-align", TEXT_ALIGN_CHA_LEFT + of "right": set_cv "text-align", TEXT_ALIGN_CHA_RIGHT template map_text = let c = parseLegacyColor(element.attr("text")) if c.isSome: - set_cv(PROPERTY_COLOR, color, c.get) + set_cv "color", c.get template map_color = let c = parseLegacyColor(element.attr("color")) if c.isSome: - set_cv(PROPERTY_COLOR, color, c.get) + set_cv "color", c.get + template map_colspan = + let colspan = element.attrigz("colspan") + if colspan.isSome: + let i = colspan.get + if i <= 1000: + set_cv "-cha-colspan", i + template map_rowspan = + let rowspan = element.attrigez("rowspan") + if rowspan.isSome: + let i = rowspan.get + if i <= 65534: + set_cv "-cha-rowspan", i case element.tagType of TAG_DIV: @@ -131,6 +143,8 @@ func calcPresentationalHints(element: Element): CSSComputedValues = map_bgcolor map_valign map_align + map_colspan + map_rowspan of TAG_THEAD, TAG_TBODY, TAG_TFOOT, TAG_TR: map_height map_bgcolor @@ -146,8 +160,8 @@ func calcPresentationalHints(element: Element): CSSComputedValues = map_text of TAG_TEXTAREA: let textarea = HTMLTextAreaElement(element) - set_cv(PROPERTY_WIDTH, length, CSSLength(unit: UNIT_CH, num: float64(textarea.cols))) - set_cv(PROPERTY_HEIGHT, length, CSSLength(unit: UNIT_EM, num: float64(textarea.rows))) + set_cv "width", CSSLength(unit: UNIT_CH, num: float64(textarea.cols)) + set_cv "height", CSSLength(unit: UNIT_EM, num: float64(textarea.rows)) of TAG_FONT: map_color else: discard @@ -286,6 +300,11 @@ proc applyRules(document: Document, ua, user: CSSStylesheet, cachedTree: StyledN let styledText = styledParent.newStyledReplacement(content) styledText.pseudo = pseudo styledParent.children.add(styledText) + of PSEUDO_NEWLINE: + let content = CSSContent(t: CONTENT_NEWLINE) + let styledText = styledParent.newStyledReplacement(content) + styledText.pseudo = pseudo + styledParent.children.add(styledText) of PSEUDO_NONE: discard else: assert child != nil @@ -364,6 +383,8 @@ proc applyRules(document: Document, ua, user: CSSStylesheet, cachedTree: StyledN stack_append styledChild, PSEUDO_TEXTAREA_TEXT elif elem.tagType == TAG_IMG or elem.tagType == TAG_IMAGE: stack_append styledChild, PSEUDO_IMAGE + elif elem.tagType == TAG_BR: + stack_append styledChild, PSEUDO_NEWLINE else: for i in countdown(elem.childList.high, 0): if elem.childList[i].nodeType in {ELEMENT_NODE, TEXT_NODE}: diff --git a/src/css/selectorparser.nim b/src/css/selectorparser.nim index 8a38292b..2c6ab659 100644 --- a/src/css/selectorparser.nim +++ b/src/css/selectorparser.nim @@ -19,7 +19,7 @@ type PseudoElem* = enum PSEUDO_NONE, PSEUDO_BEFORE, PSEUDO_AFTER, # internal - PSEUDO_INPUT_TEXT, PSEUDO_TEXTAREA_TEXT, PSEUDO_IMAGE + PSEUDO_INPUT_TEXT, PSEUDO_TEXTAREA_TEXT, PSEUDO_IMAGE, PSEUDO_NEWLINE PseudoClass* = enum PSEUDO_FIRST_CHILD, PSEUDO_LAST_CHILD, PSEUDO_ONLY_CHILD, PSEUDO_HOVER, diff --git a/src/css/values.nim b/src/css/values.nim index 874d82a0..f847b72b 100644 --- a/src/css/values.nim +++ b/src/css/values.nim @@ -35,7 +35,8 @@ type PROPERTY_RIGHT, PROPERTY_TOP, PROPERTY_BOTTOM, PROPERTY_CAPTION_SIDE, 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_MIN_WIDTH, PROPERTY_MIN_HEIGHT, PROPERTY_BACKGROUND_IMAGE, + PROPERTY_CHA_COLSPAN, PROPERTY_CHA_ROWSPAN CSSValueType* = enum VALUE_NONE, VALUE_LENGTH, VALUE_COLOR, VALUE_CONTENT, VALUE_DISPLAY, @@ -102,7 +103,8 @@ type CSSContentType* = enum CONTENT_STRING, CONTENT_OPEN_QUOTE, CONTENT_CLOSE_QUOTE, - CONTENT_NO_OPEN_QUOTE, CONTENT_NO_CLOSE_QUOTE, CONTENT_IMAGE + CONTENT_NO_OPEN_QUOTE, CONTENT_NO_CLOSE_QUOTE, CONTENT_IMAGE, + CONTENT_NEWLINE const RowGroupBox* = {DISPLAY_TABLE_ROW_GROUP, DISPLAY_TABLE_HEADER_GROUP, DISPLAY_TABLE_FOOTER_GROUP} @@ -250,7 +252,9 @@ const PropertyNames = { "max-height": PROPERTY_MAX_HEIGHT, "min-width": PROPERTY_MIN_WIDTH, "min-height": PROPERTY_MIN_HEIGHT, - "background-image": PROPERTY_BACKGROUND_IMAGE + "background-image": PROPERTY_BACKGROUND_IMAGE, + "-cha-colspan": PROPERTY_CHA_COLSPAN, + "-cha-rowspan": PROPERTY_CHA_ROWSPAN }.toTable() const ValueTypes* = [ @@ -294,7 +298,9 @@ const ValueTypes* = [ PROPERTY_MAX_HEIGHT: VALUE_LENGTH, PROPERTY_MIN_WIDTH: VALUE_LENGTH, PROPERTY_MIN_HEIGHT: VALUE_LENGTH, - PROPERTY_BACKGROUND_IMAGE: VALUE_IMAGE + PROPERTY_BACKGROUND_IMAGE: VALUE_IMAGE, + PROPERTY_CHA_COLSPAN: VALUE_INTEGER, + PROPERTY_CHA_ROWSPAN: VALUE_INTEGER ] const InheritedProperties = { @@ -856,6 +862,15 @@ func cssImage(cval: CSSComponentValue): Option[CSSContent] = if tok.tokenType == CSS_URL_TOKEN or tok.tokenType == CSS_BAD_URL_TOKEN: return some(CSSContent(t: CONTENT_IMAGE, s: "[img]")) +func cssInteger(cval: CSSComponentValue, range: Slice[int]): int = + if isToken(cval): + let tok = getToken(cval) + if tok.tokenType == CSS_NUMBER_TOKEN: + let i = int(tok.nvalue) + if float64(i) == tok.nvalue and i in range: + return i + raise newException(CSSValueError, "Invalid integer") + proc getValueFromDecl(val: CSSComputedValue, d: CSSDeclaration, vtype: CSSValueType, ptype: CSSPropertyType) = var i = 0 d.value.skipWhitespace(i) @@ -891,6 +906,10 @@ proc getValueFromDecl(val: CSSComputedValue, d: CSSDeclaration, vtype: CSSValueT of VALUE_INTEGER: if ptype == PROPERTY_FONT_WEIGHT: val.integer = cssFontWeight(cval) + elif ptype == PROPERTY_CHA_COLSPAN: + val.integer = cssInteger(cval, 1 .. 1000) + elif ptype == PROPERTY_CHA_ROWSPAN: + val.integer = cssInteger(cval, 0 .. 65534) of VALUE_TEXT_DECORATION: val.textdecoration = cssTextDecoration(d) of VALUE_WORD_BREAK: val.wordbreak = cssWordBreak(cval) of VALUE_LIST_STYLE_TYPE: val.liststyletype = cssListStyleType(cval) @@ -947,6 +966,14 @@ func getInitialLength(t: CSSPropertyType): CSSLength = else: return CSSLength(auto: false, unit: UNIT_PX, num: 0) +func getInitialInteger(t: CSSPropertyType): int = + case t + of PROPERTY_CHA_COLSPAN, PROPERTY_CHA_ROWSPAN: + return 1 + of PROPERTY_FONT_WEIGHT: + return 400 # normal + else: discard + func calcInitial(t: CSSPropertyType): CSSComputedValue = let v = valueType(t) var nv: CSSComputedValue @@ -959,6 +986,8 @@ func calcInitial(t: CSSPropertyType): CSSComputedValue = nv = CSSComputedValue(t: t, v: v, wordbreak: WORD_BREAK_NORMAL) of VALUE_LENGTH: nv = CSSComputedValue(t: t, v: v, length: getInitialLength(t)) + of VALUE_INTEGER: + nv = CSSComputedValue(t: t, v: v, integer: getInitialInteger(t)) of VALUE_QUOTES: nv = CSSComputedValue(t: t, v: v, quotes: CSSQuotes(auto: true)) else: |