Coverage for gws-app/gws/lib/style/core.py: 86%
35 statements
« prev ^ index » next coverage.py v7.16.2, created at 2026-10-05 13:35 +0200
« prev ^ index » next coverage.py v7.16.2, created at 2026-10-05 13:35 +0200
1"""Style object and constructors."""
3from typing import Optional
5import gws
7from . import parser, icon
10# parsing depends on whenever the context is `trusted` (=config) or not (=request)
12def from_dict(d: dict, opts: parser.Options = None) -> 'Object':
13 """Create a style object from a dict.
15 The dict can contain ``cssSelector``, ``text`` (CSS text) and ``values`` (a dict of style values).
16 Values from ``values`` override those parsed from ``text``.
18 Args:
19 d: A dict with style properties.
20 opts: Parser options. Defaults to untrusted and strict.
22 Returns:
23 A style object.
25 Raises:
26 ``gws.Error``: If a property or value is invalid and the parser is strict.
27 """
28 vals = {}
29 opts = opts or parser.Options(trusted=False, strict=True)
31 s = d.get('text')
32 if s:
33 vals.update(parser.parse_text(s, opts))
35 s = d.get('values')
36 if s:
37 vals.update(parser.parse_dict(gws.u.to_dict(s), opts))
39 return Object(
40 d.get('cssSelector', ''),
41 d.get('text', ''),
42 gws.StyleValues(vals),
43 )
46def from_config(cfg: gws.Config, opts: parser.Options = None) -> 'Object':
47 """Create a style object from a configuration.
49 Args:
50 cfg: Style configuration.
51 opts: Parser options. Defaults to trusted and strict.
53 Returns:
54 A style object.
56 Raises:
57 ``gws.Error``: If a property or value is invalid and the parser is strict.
58 """
59 return from_dict(
60 gws.u.to_dict(cfg),
61 opts or parser.Options(trusted=True, strict=True))
64def from_props(props: gws.Props, opts: parser.Options = None) -> 'Object':
65 """Create a style object from client properties.
67 Args:
68 props: Style properties.
69 opts: Parser options. Defaults to untrusted and non-strict.
71 Returns:
72 A style object.
73 """
74 return from_dict(
75 gws.u.to_dict(props),
76 opts or parser.Options(trusted=False, strict=False))
79##
82class Config(gws.Config):
83 """Feature style"""
85 cssSelector: Optional[str]
86 """CSS selector"""
87 text: Optional[str]
88 """raw style content"""
89 values: Optional[dict]
90 """style values"""
93class Props(gws.Props):
95 cssSelector: Optional[str]
96 """CSS selector"""
97 values: Optional[dict]
98 """Style values"""
101class Object(gws.Style):
102 """Style object."""
104 def __init__(self, selector, text, values):
105 """Create a style object.
107 Args:
108 selector: CSS selector.
109 text: Raw CSS text.
110 values: Parsed style values.
111 """
112 self.cssSelector = selector
113 self.text = text
114 self.values = values
116 def props(self, user):
117 ico = self.values.icon
118 if ico and isinstance(ico, icon.ParsedIcon):
119 ico = icon.to_data_url(ico)
120 else:
121 # NB if icon is not parsed, don't give it back
122 ico = ''
124 return Props(
125 cssSelector=self.cssSelector or '',
126 values=gws.u.merge(self.values, icon=ico),
127 )