Coverage for gws-app/gws/lib/style/core.py: 88%

34 statements  

« prev     ^ index     » next       coverage.py v7.17.0, created at 2026-10-23 20:06 +0200

1"""Style object and constructors.""" 

2 

3from typing import Optional 

4 

5import gws 

6 

7from . import parser, icon 

8 

9 

10# parsing depends on whenever the context is `trusted` (=config) or not (=request) 

11 

12 

13def from_dict(d: dict, opts: parser.Options = None) -> 'Object': 

14 """Create a style object from a dict. 

15 

16 The dict can contain ``cssSelector``, ``text`` (CSS text) and ``values`` (a dict of style values). 

17 Values from ``values`` override those parsed from ``text``. 

18 

19 Args: 

20 d: A dict with style properties. 

21 opts: Parser options. Defaults to untrusted and strict. 

22 

23 Returns: 

24 A style object. 

25 

26 Raises: 

27 ``gws.Error``: If a property or value is invalid and the parser is strict. 

28 """ 

29 vals = {} 

30 opts = opts or parser.Options(trusted=False, strict=True) 

31 

32 s = d.get('text') 

33 if s: 

34 vals.update(parser.parse_text(s, opts)) 

35 

36 s = d.get('values') 

37 if s: 

38 vals.update(parser.parse_dict(gws.u.to_dict(s), opts)) 

39 

40 return Object( 

41 d.get('cssSelector', ''), 

42 d.get('text', ''), 

43 gws.StyleValues(vals), 

44 ) 

45 

46 

47def from_config(cfg: gws.Config, opts: parser.Options = None) -> 'Object': 

48 """Create a style object from a configuration. 

49 

50 Args: 

51 cfg: Style configuration. 

52 opts: Parser options. Defaults to trusted and strict. 

53 

54 Returns: 

55 A style object. 

56 

57 Raises: 

58 ``gws.Error``: If a property or value is invalid and the parser is strict. 

59 """ 

60 return from_dict( 

61 gws.u.to_dict(cfg), 

62 opts or parser.Options(trusted=True, strict=True), 

63 ) 

64 

65 

66def from_props(props: gws.Props, opts: parser.Options = None) -> 'Object': 

67 """Create a style object from client properties. 

68 

69 Args: 

70 props: Style properties. 

71 opts: Parser options. Defaults to untrusted and non-strict. 

72 

73 Returns: 

74 A style object. 

75 """ 

76 return from_dict( 

77 gws.u.to_dict(props), 

78 opts or parser.Options(trusted=False, strict=False), 

79 ) 

80 

81 

82## 

83 

84 

85class Config(gws.Config): 

86 """Feature style""" 

87 

88 cssSelector: Optional[str] 

89 """CSS selector""" 

90 text: Optional[str] 

91 """raw style content""" 

92 values: Optional[dict] 

93 """style values""" 

94 

95 

96class Props(gws.Props): 

97 cssSelector: Optional[str] 

98 """CSS selector""" 

99 values: Optional[dict] 

100 """Style values""" 

101 

102 

103class Object(gws.Style): 

104 """Style object.""" 

105 

106 def __init__(self, selector, text, values): 

107 """Create a style object. 

108 

109 Args: 

110 selector: CSS selector. 

111 text: Raw CSS text. 

112 values: Parsed style values. 

113 """ 

114 self.cssSelector = selector 

115 self.text = text 

116 self.values = values 

117 

118 def props(self, user): 

119 values = self.values 

120 if self.values.icon: 

121 values = gws.u.merge(self.values, icon=icon.to_data_url(self.values.icon)) 

122 return Props( 

123 cssSelector=self.cssSelector or '', 

124 values=values, 

125 )