1+ from hashlib import sha256
2+ from . import Page
3+ from typing import Dict , List
4+ from flask import current_app
5+
6+ class Style :
7+ """Inline CSS style
8+ Keyword arguments:
9+ keyword -- value
10+ Example:
11+ Style(color="red", padding_top="blue")
12+ """
13+ def __init__ (self , ** kwargs ):
14+ """Inline CSS style
15+ Keyword arguments:
16+ keyword -- value
17+ Example:
18+ Style(color="red", padding_top="blue")
19+ """
20+ self .style = ""
21+ for key , value in kwargs .items ():
22+ if "_" in key :
23+ key = key .replace ("_" , "-" )
24+ self .style += "{}:{};\n " .format (key , value )
25+
26+ def __str__ (self ):
27+ return self .render ()
28+
29+ def __repr__ (self ):
30+ return self .render ()
31+
32+ def render (self ):
33+ return self .style
34+
35+ class Item :
36+
37+ item = "<{tag} {classes} {id} {props}>{content}</{tag}>"
38+ __tag = None
39+ __classes = None
40+ __id = None
41+ __props = None
42+ page = None
43+ elements = []
44+ styles = ""
45+ js = ""
46+ def register_style (self ):
47+ if self .styles :
48+ self .page .register_style (self .styles )
49+ for item in self .elements :
50+ if isinstance (item , Item ):
51+ item .page = self .page
52+ item .register_style ()
53+
54+ def register_js (self ):
55+ if self .js :
56+ self .page .register_js (self .js )
57+ for item in self .elements :
58+ if isinstance (item , Item ):
59+ item .page = self .page
60+ item .register_js ()
61+
62+ def __init__ (self , page : Page = None , classes : List [str ] = [], id : str = None , style : Style = None , tag : str = "div" , content : List [object ] = [], props : Dict [str , str ] = {}):
63+ """Base template for all HTML elements
64+
65+ Args:
66+ page (Page, optional): Page element, uses for Body tag. Defaults to None.
67+ classes (List[str], optional): List of class names for tag. Defaults to [].
68+ id (str, optional): Unique ID for tag. Defaults to None.
69+ style (Style, optional): Custom inline styles for tag. Defaults to None.
70+ tag (str, optional): Tag name. Defaults to "div".
71+ content (List[object], optional): List of Elements. Defaults to [].
72+ props (Dict[str, str], optional): Tag rpoperties. Defaults to {}.
73+ """
74+ if page :
75+ self .page = page
76+ self .elements = content
77+ _cl = None
78+ if style :
79+ _cl = self .__generate_style (style )
80+ classes .append (_cl )
81+ if len (classes ) > 0 :
82+ self .__append_classes (classes )
83+ else :
84+ self .__classes = ""
85+ if id :
86+ self .__id = "id='{}'" .format (id )
87+ else :
88+ self .__id = ""
89+ self .__tag = tag
90+ if len (props ) > 0 :
91+ _props = ""
92+ for key , value in props .items ():
93+ _props += "{}='{}' " .format (key , value )
94+ self .__props = _props .rstrip (" " )
95+ else :
96+ self .__props = ""
97+
98+ def __str__ (self ):
99+ return self .render ()
100+
101+ def __repr__ (self ):
102+ return self .render ()
103+
104+ def render (self ):
105+ """Render HTML element
106+
107+ Returns:
108+ str: String HTML element
109+ """
110+ _cnt = ""
111+ for item in self .elements :
112+ _cnt += str (item )
113+ return self .item .format (tag = self .__tag , classes = self .__classes , id = self .__id , content = _cnt , props = self .__props )
114+
115+ def __append_classes (self ,classes : List [str ] = None ):
116+ print (classes )
117+ _res = ""
118+ if classes :
119+ _res = "class='"
120+ for _class in classes :
121+ _res += _class + " "
122+ _res = _res .rstrip (" " )
123+ _res = _res + "'"
124+ self .__classes = _res
125+
126+ def __generate_style (self , style : Style ):
127+ styles = style .render ()
128+ self .hash_code = "o" + sha256 ("{secret}{styles}" .format (secret = current_app .config .get ("SECRET_KEY" , "123123" ), styles = styles ).encode ()).hexdigest ()[:5 ]
129+ return self .__register_style (self .hash_code , styles )
130+
131+ def __register_style (self , hash_code : str , styles : str ):
132+ _st = """
133+ .{hash_code} {{
134+ {styles}
135+ }}
136+ """ .format (hash_code = hash_code , styles = styles )
137+ self .styles = _st
138+ return hash_code
0 commit comments