diff options
author | bptato <nincsnevem662@gmail.com> | 2024-12-30 19:28:33 +0100 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2024-12-30 19:28:33 +0100 |
commit | bc3b11ebd3c2554f4f30e9afb4d46328c748e9be (patch) | |
tree | 619bb135cce1e9af3fa058c9fc6c7bd4ee017773 | |
parent | de759debe31d67776a7a70d3d4dc41a89591cdfc (diff) | |
download | chawan-bc3b11ebd3c2554f4f30e9afb4d46328c748e9be.tar.gz |
dom, cssvalues: add getComputedStyle
Only available in "app" mode.
-rw-r--r-- | src/css/cascade.nim | 5 | ||||
-rw-r--r-- | src/css/cssvalues.nim | 107 | ||||
-rw-r--r-- | src/html/dom.nim | 28 | ||||
-rw-r--r-- | src/html/env.nim | 8 | ||||
-rw-r--r-- | src/types/color.nim | 9 |
5 files changed, 113 insertions, 44 deletions
diff --git a/src/css/cascade.nim b/src/css/cascade.nim index 3a983a63..60d59a04 100644 --- a/src/css/cascade.nim +++ b/src/css/cascade.nim @@ -294,8 +294,9 @@ proc applyDeclarations(styledNode: StyledNode; parent: CSSValues; rules[coUser].add(map.user[peNone]) for rule in map.author: rules[coAuthor].add(rule[peNone]) + var element: Element = nil if styledNode.node != nil: - let element = Element(styledNode.node) + element = Element(styledNode.node) let style = element.cachedStyle if window.styling and style != nil: for decl in style.decls: @@ -306,6 +307,8 @@ proc applyDeclarations(styledNode: StyledNode; parent: CSSValues; rules[coAuthor].normal.add(vals) presHints = element.calcPresHints(window.attrsp[]) styledNode.computed = rules.buildComputedValues(presHints, parent) + if element != nil and window.settings.scripting == smApp: + element.computed = styledNode.computed func hasValues(rules: CSSValueEntryMap): bool = for origin in CSSOrigin: diff --git a/src/css/cssvalues.nim b/src/css/cssvalues.nim index 35487dfd..a88ae814 100644 --- a/src/css/cssvalues.nim +++ b/src/css/cssvalues.nim @@ -499,44 +499,79 @@ func valueType*(prop: CSSPropertyType): CSSValueType = func isSupportedProperty*(s: string): bool = return propertyType(s) != cptNone -when defined(debug): - func `$`*(length: CSSLength): string = - if length.u == clAuto: - return "auto" - return $length.num & $length.u - - func `$`*(content: CSSContent): string = - if content.s != "": - return "url(" & content.s & ")" - return "none" - - func `$`(quotes: CSSQuotes): string = - if quotes.auto: - return "auto" - return "auto" #TODO - - func `$`(counterreset: seq[CSSCounterReset]): string = - result = "" - for it in counterreset: - result &= $it.name - result &= ' ' - result &= $it.num +func `$`*(length: CSSLength): string = + if length.u == clAuto: + return "auto" + return $length.num & $length.u + +func `$`*(content: CSSContent): string = + if content.t == ContentImage: + #TODO + return "" + if content.s != "": + return "url(" & content.s & ")" + return "none" + +func `$`(quotes: CSSQuotes): string = + if quotes.auto: + return "auto" + return "auto" #TODO + +func `$`(counterreset: seq[CSSCounterReset]): string = + result = "" + for it in counterreset: + result &= $it.name + result &= ' ' + result &= $it.num + +func serialize*(val: CSSValue): string = + case val.v + of cvtNone: return "none" + of cvtColor: return $val.color + of cvtImage: return $val.image + of cvtLength: return $val.length + of cvtInteger: return $val.integer + of cvtTextDecoration: return $val.textDecoration + of cvtVerticalAlign: return $val.verticalAlign + of cvtLength2: return $val.length2.a & " " & $val.length2.b + of cvtContent: + var s = "" + for x in val.content: + if s.len > 0: + s &= ' ' + s &= $x + return s + of cvtQuotes: return $val.quotes + of cvtCounterReset: return $val.counterReset + of cvtNumber: return $val.number + else: assert false + +func serialize*(val: CSSValueBit; t: CSSValueType): string = + case t + of cvtDisplay: return $val.display + of cvtFontStyle: return $val.fontStyle + of cvtWhiteSpace: return $val.whiteSpace + of cvtWordBreak: return $val.wordBreak + of cvtListStyleType: return $val.listStyleType + of cvtTextAlign: return $val.textAlign + of cvtListStylePosition: return $val.listStylePosition + of cvtPosition: return $val.position + of cvtCaptionSide: return $val.captionSide + of cvtBorderCollapse: return $val.borderCollapse + of cvtFloat: return $val.float + of cvtVisibility: return $val.visibility + of cvtBoxSizing: return $val.boxSizing + of cvtClear: return $val.clear + of cvtTextTransform: return $val.textTransform + of cvtBgcolorIsCanvas: return $val.bgcolorIsCanvas + of cvtFlexDirection: return $val.flexDirection + of cvtFlexWrap: return $val.flexWrap + of cvtOverflow: return $val.overflow + else: assert false +when defined(debug): func `$`*(val: CSSValue): string = - case val.v - of cvtNone: return "none" - of cvtColor: return $val.color - of cvtImage: return $val.image - of cvtLength: return $val.length - of cvtInteger: return $val.integer - of cvtTextDecoration: return $val.textDecoration - of cvtVerticalAlign: return $val.verticalAlign - of cvtLength2: return $val.length2.a & " " & $val.length2.b - of cvtContent: return $val.content - of cvtQuotes: return $val.quotes - of cvtCounterReset: return $val.counterReset - of cvtNumber: return $val.number - else: assert false + return val.serialize() macro `{}`*(vals: CSSValues; s: static string): untyped = let t = propertyType(s) diff --git a/src/html/dom.nim b/src/html/dom.nim index 759191a8..61b406b4 100644 --- a/src/html/dom.nim +++ b/src/html/dom.nim @@ -260,10 +260,13 @@ type attrs*: seq[AttrData] # sorted by int(qualifiedName) cachedAttributes: NamedNodeMap cachedStyle*: CSSStyleDeclaration + cachedComputedStyle*: CSSStyleDeclaration + computed*: CSSValues AttrDummyElement = ref object of Element CSSStyleDeclaration* = ref object + computed: bool decls*: seq[CSSDeclaration] element: Element @@ -3300,7 +3303,10 @@ func find(this: CSSStyleDeclaration; s: string): int = proc getPropertyValue(this: CSSStyleDeclaration; s: string): string {.jsfunc.} = if (let i = this.find(s); i != -1): - return $this.decls[i].value + var s = "" + for it in this.decls[i].value: + s &= $it + return move(s) return "" # https://drafts.csswg.org/cssom/#idl-attribute-to-css-property @@ -3347,7 +3353,10 @@ proc setValue(this: CSSStyleDeclaration; i: int; cvals: seq[CSSComponentValue]): return ok() proc setter(ctx: JSContext; this: CSSStyleDeclaration; atom: JSAtom; - value: string): Opt[void] {.jssetprop.} = + value: string): DOMResult[void] {.jssetprop.} = + if this.computed: + return errDOMException("Cannot modify computed value", + "NoModificationAllowedError") let cvals = parseComponentValues(value) var u: uint32 if ctx.fromJS(atom, u).isSome: @@ -3374,6 +3383,21 @@ proc style*(element: Element): CSSStyleDeclaration {.jsfget.} = element.cachedStyle = CSSStyleDeclaration(element: element) return element.cachedStyle +proc getComputedStyle*(element: Element): CSSStyleDeclaration = + if element.cachedComputedStyle == nil: + var s = "" + for p in CSSPropertyType: + if p != cptNone: + s &= $p & ':' + if p.isBit: + s &= element.computed.bits[p].serialize(valueType(p)) + else: + s &= element.computed.objs[p].serialize() + s &= ';' + element.cachedComputedStyle = newCSSStyleDeclaration(element, move(s)) + element.cachedComputedStyle.computed = true + return element.cachedComputedStyle + proc corsFetch(window: Window; input: Request): FetchPromise = if not window.images and input.url.scheme.startsWith("img-codec+"): return newResolvedPromise(JSResult[Response].err(newFetchTypeError())) diff --git a/src/html/env.nim b/src/html/env.nim index 588aa897..91e82f30 100644 --- a/src/html/env.nim +++ b/src/html/env.nim @@ -283,9 +283,11 @@ callback(new Event("").timeStamp); return ctx.toJS(window.setTimeout(handler, 0, callback)) proc getComputedStyle(window: Window; element: Element; - pseudoElt = none(string)): JSResult[CSSStyleDeclaration] {.jsfunc.} = - #TODO implement this properly - return ok(element.style) + pseudoElt = none(string)): CSSStyleDeclaration {.jsfunc.} = + if window.settings.scripting == smApp: + return element.getComputedStyle() + # Maybe it works. + return element.style proc postMessage(window: Window) {.jsfunc.} = window.console.log("postMessage: Stub") diff --git a/src/types/color.nim b/src/types/color.nim index f78b3e28..7f49aa74 100644 --- a/src/types/color.nim +++ b/src/types/color.nim @@ -287,8 +287,13 @@ func serialize*(color: ARGBColor): string = return "rgba(" & $color.r & ", " & $color.g & ", " & $color.b & ", " & $a & ")" -func `$`*(argbcolor: ARGBColor): string = - return argbcolor.serialize() +func `$`*(c: ARGBColor): string = + return c.serialize() + +func `$`*(c: CSSColor): string = + if c.isCell: + return "-cha-ansi(" & $c.n & ")" + return c.argb().serialize() # Divide each component by 255, multiply them by n, and discard the fractions. # See https://arxiv.org/pdf/2202.02864.pdf for details. |