diff options
author | bptato <nincsnevem662@gmail.com> | 2021-08-11 22:26:30 +0200 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2021-08-11 22:26:30 +0200 |
commit | 2f32d6ed51e14d6871c7be4fd1f8ccdc0455a0bb (patch) | |
tree | bcc405a077944852780551d5700d284958e49ce1 /src | |
parent | 6cea57b35e4e749de531faf6502237c1cf7ed022 (diff) | |
download | chawan-2f32d6ed51e14d6871c7be4fd1f8ccdc0455a0bb.tar.gz |
Get rid of some old code, work on css property handling
Diffstat (limited to 'src')
-rw-r--r-- | src/css/style.nim | 74 | ||||
-rw-r--r-- | src/html/dom.nim | 97 | ||||
-rw-r--r-- | src/html/parser.nim | 2 | ||||
-rw-r--r-- | src/html/renderer.nim | 4 | ||||
-rw-r--r-- | src/io/buffer.nim | 34 | ||||
-rw-r--r-- | src/utils/twtstr.nim | 31 |
6 files changed, 73 insertions, 169 deletions
diff --git a/src/css/style.nim b/src/css/style.nim index cdf774eb..3ef38bea 100644 --- a/src/css/style.nim +++ b/src/css/style.nim @@ -40,6 +40,8 @@ type position*: CSSPosition content*: seq[Rune] + CSSValues* = array[low(CSSRuleType)..high(CSSRuleType), CSSComputedValue] + CSSColor* = tuple[r: uint8, g: uint8, b: uint8, a: uint8] CSSComputedValue* = object of RootObj @@ -282,14 +284,32 @@ func getSpecifiedValue*(d: CSSDeclaration): CSSSpecifiedValue = of "content": return CSSSpecifiedValue(t: RULE_CONTENT, v: VALUE_CONTENT, content: cssString(d)) -func getComputedValue*(rule: CSSSpecifiedValue): CSSComputedValue = +func getInitialColor*(t: CSSRuleType): CSSColor = + case t + of RULE_COLOR: + return (r: 255u8, g: 255u8, b: 255u8, a: 255u8) + else: + return (r: 0u8, g: 0u8, b: 0u8, a: 255u8) + +func getComputedValue*(rule: CSSSpecifiedValue, parent: CSSValues): CSSComputedValue = let inherit = rule.hasGlobalValue and (rule.globalValue == VALUE_INHERIT) - let initial = rule.hasGlobalValue and (rule.globalValue == VALUE_INHERIT) - let unset = rule.hasGlobalValue and (rule.globalValue == VALUE_INHERIT) - let revert = rule.hasGlobalValue and (rule.globalValue == VALUE_INHERIT) + let initial = rule.hasGlobalValue and (rule.globalValue == VALUE_INITIAL) + let unset = rule.hasGlobalValue and (rule.globalValue == VALUE_UNSET) + let revert = rule.hasGlobalValue and (rule.globalValue == VALUE_REVERT) case rule.v of VALUE_COLOR: - return CSSComputedValue(t: rule.t, v: VALUE_COLOR, color: rule.color) + var val = rule.color + if inherit: #TODO and inherited(rule.t): + val = parent[rule.t].color + if initial: + val = getInitialColor(rule.t) + if unset: + val = getInitialColor(rule.t) + #TODO if inherited + if revert: + #TODO + discard + return CSSComputedValue(t: rule.t, v: VALUE_COLOR, color: val) of VALUE_LENGTH: return CSSComputedValue(t: rule.t, v: VALUE_LENGTH, length: rule.length) of VALUE_DISPLAY: @@ -300,37 +320,15 @@ func getComputedValue*(rule: CSSSpecifiedValue): CSSComputedValue = return CSSComputedValue(t: rule.t, v: VALUE_CONTENT, content: rule.content) of VALUE_NONE: return CSSComputedValue(t: rule.t, v: VALUE_NONE) -func getValue*(vals: seq[CSSComputedValue], rule: CSSRuleType): CSSComputedValue = - for val in vals: - if val.t == rule: - result = val +func getComputedValue*(d: CSSDeclaration, parent: CSSValues): CSSComputedValue = + return getComputedValue(getSpecifiedValue(d), parent) -func getComputedValue*(d: CSSDeclaration): CSSComputedValue = - return getComputedValue(getSpecifiedValue(d)) - -proc applyProperty*(props: CSS2Properties, d: CSSDeclaration) = - case $d.name - of "color": - props.color = cssColor(d) - of "margin": - let l = cssLength(d) - props.margintop = l - props.marginbottom = l - props.marginleft = l - props.marginright = l - of "margin-top": - props.margintop = cssLength(d) - of "margin-left": - props.marginleft = cssLength(d) - of "margin-right": - props.marginright = cssLength(d) - of "margin-bottom": - props.marginbottom = cssLength(d) - of "font-style": - props.fontStyle = cssFontStyle(d) - of "display": - props.display = cssDisplay(d) - of "content": - props.content = cssString(d) - else: - printc(d) #TODO +func getInitialProperties*(): array[low(CSSRuleType)..high(CSSRuleType), CSSComputedValue] = + for i in low(result)..high(result): + let t = CSSRuleType(i) + let v = getValueType(t) + case v + of VALUE_COLOR: + result[i] = CSSComputedValue(t: t, v: v, color: getInitialColor(t)) + else: + result[i] = CSSComputedValue(t: t, v: v) diff --git a/src/html/dom.nim b/src/html/dom.nim index cb2f363f..82301146 100644 --- a/src/html/dom.nim +++ b/src/html/dom.nim @@ -33,8 +33,6 @@ type parentElement*: Element ownerDocument*: Document - rawtext*: string - fmttext*: seq[string] x*: int y*: int ex*: int @@ -86,8 +84,7 @@ type id*: string classList*: seq[string] attributes*: Table[string, Attr] - style*: CSS2Properties - cssvalues*: seq[CSSComputedValue] + cssvalues*: array[low(CSSRuleType)..high(CSSRuleType), CSSComputedValue] HTMLElement* = ref HTMLElementObj HTMLElementObj = object of ElementObj @@ -155,15 +152,6 @@ func nodeAttr*(node: Node): HtmlElement = of ELEMENT_NODE: return HtmlElement(node) else: assert(false) -func getStyle*(node: Node): CSS2Properties = - case node.nodeType - of TEXT_NODE: return node.parentElement.style - of ELEMENT_NODE: return Element(node).style - else: assert(false) - -func displayed*(node: Node): bool = - return node.rawtext.len > 0 and node.getStyle().display != DISPLAY_NONE - func isTextNode*(node: Node): bool = return node.nodeType == TEXT_NODE @@ -179,12 +167,6 @@ func isCData*(node: Node): bool = func isDocument*(node: Node): bool = return node.nodeType == DOCUMENT_NODE -func getFmtLen*(htmlNode: Node): int = - return htmlNode.fmttext.join().runeLen() - -func getRawLen*(htmlNode: Node): int = - return htmlNode.rawtext.runeLen() - func firstNode*(htmlNode: Node): bool = return htmlNode.parentElement != nil and htmlNode.parentElement.childNodes[0] == htmlNode @@ -225,72 +207,12 @@ func toInputSize*(str: string): int = return 20 return str.parseInt() -func getFmtInput(inputElement: HtmlInputElement): seq[string] = - case inputElement.itype - of INPUT_TEXT, INPUT_SEARCH: - let valueFit = fitValueToSize(inputElement.value, inputElement.size) - return valueFit.ansiStyle(styleUnderscore).ansiReset().buttonFmt() - of INPUT_SUBMIT: - return inputElement.value.buttonFmt() - else: discard - -func getRawInput(inputElement: HtmlInputElement): string = - case inputElement.itype - of INPUT_TEXT, INPUT_SEARCH: - return inputElement.value.fitValueToSize(inputElement.size).buttonRaw() - of INPUT_SUBMIT: - return inputElement.value.buttonRaw() - else: discard - #TODO func ancestor*(htmlNode: Node, tagType: TagType): HtmlElement = result = HtmlElement(htmlNode.parentElement) while result != nil and result.tagType != tagType: result = HtmlElement(result.parentElement) -proc getRawText*(htmlNode: Node): string = - if htmlNode.isElemNode(): - case HtmlElement(htmlNode).tagType - of TAG_INPUT: return HtmlInputElement(htmlNode).getRawInput() - else: return "" - elif htmlNode.isTextNode(): - let chardata = CharacterData(htmlNode) - if htmlNode.parentElement != nil and htmlNode.parentElement.tagType != TAG_PRE: - result = chardata.data.remove("\n") - else: - result = unicode.strip(chardata.data) - if htmlNode.parentElement != nil and htmlNode.parentElement.tagType == TAG_OPTION: - result = result.buttonRaw() - else: - assert(false) - -func getFmtText*(node: Node): seq[string] = - if node.isElemNode(): - case HtmlElement(node).tagType - of TAG_INPUT: return HtmlInputElement(node).getFmtInput() - else: return @[] - elif node.isTextNode(): - let chardata = CharacterData(node) - result &= chardata.data - if node.parentElement != nil: - let style = node.getStyle() - if style.hasColor(): - result = result.ansiFgColor(style.termColor()) - - if node.parentElement.tagType == TAG_OPTION: - result = result.ansiFgColor(fgRed).ansiReset() - - if style.bold: - result = result.ansiStyle(styleBright).ansiReset() - if style.fontStyle == FONTSTYLE_ITALIC or style.fontStyle == FONTSTYLE_OBLIQUE: - result = result.ansiStyle(styleItalic).ansiReset() - if style.underscore: - result = result.ansiStyle(styleUnderscore).ansiReset() - else: - assert(false, node.rawtext) - else: - assert(false) - func newText*(): Text = new(result) result.nodeType = TEXT_NODE @@ -320,7 +242,7 @@ func newHtmlElement*(tagType: TagType): HTMLElement = result.nodeType = ELEMENT_NODE result.tagType = tagType - result.style = CSS2Properties() + result.cssvalues = getInitialProperties() func newDocument*(): Document = new(result) @@ -455,6 +377,15 @@ func calcRules(elem: Element, rules: CSSStylesheet): seq[CSSSimpleBlock] = tosort.sort((x, y) => cmp(x.s,y.s)) return tosort.map((x) => x.b) +proc applyProperty(elem: Element, decl: CSSDeclaration) = + var parentprops: array[low(CSSRuleType)..high(CSSRuleType), CSSComputedValue] + if elem.parentElement != nil: + parentprops = elem.parentElement.cssvalues + else: + parentprops = getInitialProperties() + let cval = getComputedValue(decl, parentprops) + elem.cssvalues[cval.t] = cval + proc applyRules*(document: Document, rules: CSSStylesheet): seq[tuple[e:Element,d:CSSDeclaration]] = var stack: seq[Element] @@ -470,8 +401,7 @@ proc applyRules*(document: Document, rules: CSSStylesheet): seq[tuple[e:Element, if decl.important: result.add((elem, decl)) else: - elem.style.applyProperty(decl) - elem.cssvalues.add(getComputedValue(decl)) + elem.applyProperty(decl) for child in elem.children: stack.add(child) @@ -480,6 +410,5 @@ proc applyRules*(document: Document, rules: CSSStylesheet): seq[tuple[e:Element, proc applyDefaultStylesheet*(document: Document) = let important = document.applyRules(stylesheet) for rule in important: - rule.e.style.applyProperty(rule.d) - rule.e.cssvalues.add(getComputedValue(rule.d)) + rule.e.applyProperty(rule.d) diff --git a/src/html/parser.nim b/src/html/parser.nim index 44b31d4a..6868ec52 100644 --- a/src/html/parser.nim +++ b/src/html/parser.nim @@ -370,7 +370,6 @@ proc processDocumentPart(state: var HTMLParseState, buf: string) = state.commentNode = comment processDocumentAddNode(state, comment) if state.textNode != nil: - state.textNode.rawtext = state.textNode.getRawText() state.textNode = nil else: #TODO for doctype @@ -381,7 +380,6 @@ proc processDocumentPart(state: var HTMLParseState, buf: string) = if not state.in_comment: if state.textNode != nil: - state.textNode.rawtext = state.textNode.getRawText() state.textNode = nil p = at var tag = parse_tag(buf, at) diff --git a/src/html/renderer.nim b/src/html/renderer.nim index 6b63cf29..1f4deadd 100644 --- a/src/html/renderer.nim +++ b/src/html/renderer.nim @@ -41,7 +41,7 @@ func boxesForText*(text: seq[Rune], width: int, height: int, lx: int, x: int, y: result[^1].innerEdge.y2 = sy + 1 proc generateBox(elem: Element, x: int, y: int, w: int, h: int, fromx: int = x): CSSBox = - let display = elem.cssvalues.getValue(RULE_DISPLAY) + let display = elem.cssvalues[RULE_DISPLAY] if display.t == RULE_DISPLAY: if display.display == DISPLAY_NONE: return nil @@ -51,7 +51,7 @@ proc generateBox(elem: Element, x: int, y: int, w: int, h: int, fromx: int = x): var anonBoxes = false for child in elem.children: - let rule = child.cssvalues.getValue(RULE_DISPLAY) + let rule = child.cssvalues[RULE_DISPLAY] if rule.t == RULE_DISPLAY and rule.display == DISPLAY_BLOCK: anonBoxes = true break diff --git a/src/io/buffer.nim b/src/io/buffer.nim index 637fc87b..65bece1f 100644 --- a/src/io/buffer.nim +++ b/src/io/buffer.nim @@ -213,13 +213,7 @@ func cursorOnNode*(buffer: Buffer, node: Node): bool = (buffer.cursory == node.ey and buffer.cursorx < node.ex) func findSelectedElement*(buffer: Buffer): Option[HtmlElement] = - if buffer.selectedlink != nil and buffer.selectedLink.parentNode of HtmlElement: - return some(HtmlElement(buffer.selectedlink.parentNode)) - for node in buffer.nodes: - if node.isElemNode(): - if node.getFmtLen() > 0: - if buffer.cursorOnNode(node): return some(HtmlElement(node)) - return none(HtmlElement) + discard #TODO func canScroll*(buffer: Buffer): bool = return buffer.numLines >= buffer.height @@ -230,31 +224,7 @@ func getElementById*(buffer: Buffer, id: string): Element = return nil proc findSelectedNode*(buffer: Buffer): Option[Node] = - for node in buffer.nodes: - if node.getFmtLen() > 0 and node.displayed(): - if buffer.cursory >= node.y and buffer.cursory <= node.y + node.height and buffer.cursorx >= node.x and buffer.cursorx <= node.x + node.width: - return some(node) - return none(Node) - -proc writefmt*(buffer: Buffer, str: string) = - discard - -proc writefmt*(buffer: Buffer, c: char) = - discard - -proc writeraw*(buffer: Buffer, str: string) = - discard - -proc writeraw*(buffer: Buffer, c: char) = - discard - -proc write*(buffer: Buffer, str: string) = - buffer.writefmt(str) - buffer.writeraw(str) - -proc write*(buffer: Buffer, c: char) = - buffer.writefmt(c) - buffer.writeraw(c) + discard #TODO proc clearText*(buffer: Buffer) = buffer.lines.setLen(0) diff --git a/src/utils/twtstr.nim b/src/utils/twtstr.nim index 707b09a9..9cf63d68 100644 --- a/src/utils/twtstr.nim +++ b/src/utils/twtstr.nim @@ -464,8 +464,11 @@ const HasHanDakuten = "ぱぴぷぺぽパピプペポ".toRunes() #in unicode, char + 1 is dakuten and char + 2 handakuten #゙゚ -const Dakuten = "゙".toRunes()[0] -const HanDakuten = "゚".toRunes()[0] +const HalfDakuten = "゙".toRunes()[0] +const HalfHanDakuten = "゚".toRunes()[0] + +const Dakuten = Rune(0x3099) +const HanDakuten = Rune(0x309A) func dakuten*(r: Rune): Rune = if r in CanHaveDakuten: @@ -509,15 +512,20 @@ func halfwidth*(r: Rune): Rune = func halfwidth*(s: seq[Rune]): seq[Rune] = for r in s: - #TODO implement a setting to enable this, I personally dislike it - #if r in HasDakuten: - # result.add(halfwidth(r.nodakuten())) - # result.add(Dakuten) - #elif r in HasHanDakuten: - # result.add(halfwidth(r.nohandakuten())) - # result.add(HanDakuten) - #else: - result.add(halfwidth(r)) + #TODO combining dakuten don't always work with half width chars + #a proper solution would be something like: + #* try to detect if they work, if not fallback to halfwidth handakuten + #* add a config option for overriding this + #* also add an option to completely ignore dakuten + #* and one to disable half width ruby of course + if r in HasDakuten: + result.add(halfwidth(r.nodakuten())) + result.add(Dakuten) + elif r in HasHanDakuten: + result.add(halfwidth(r.nohandakuten())) + result.add(HanDakuten) + else: + result.add(halfwidth(r)) func halfwidth*(s: string): string = return $halfwidth(s.toRunes()) @@ -542,3 +550,4 @@ proc fullwidth*(s: seq[Rune]): seq[Rune] = proc fullwidth*(s: string): string = return $fullwidth(s.toRunes()) + |