dom.py 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. class tag:
  2. '''
  3. This class is responsible for create HTML tag, such as script, link and
  4. other. It is requied for creating tags in the app view.
  5. '''
  6. def __init__(self, name: str, twice: bool) -> None:
  7. '''
  8. This function create new tag from its name. It also require parameter
  9. named 'twice'. Twice told that tag has second closing tag. For example
  10. when twice is True, then tag look like <a></a>, but when twice is
  11. False, tag looks like <br/>.
  12. Parameters:
  13. name (str): Name of the tag
  14. twice (bool): True when tag has closing tag, false when not
  15. '''
  16. name = name.strip()
  17. if len(name) == 0:
  18. raise Exception("Can not create tag without name.")
  19. for letter in name:
  20. if letter.isspace():
  21. raise Exception("HTML Tag can not contain white space.")
  22. self.__name = name
  23. self.__twice = twice
  24. self.__content = str()
  25. self.__attributes = dict()
  26. @property
  27. def name(self) -> str:
  28. ''' This function return name of the tag. '''
  29. return self.__name
  30. @property
  31. def twice(self) -> bool:
  32. ''' This function return that tag has closing tag. '''
  33. return self.__twice
  34. @property
  35. def content(self) -> str:
  36. ''' This function return content of the tag, like innerHTML. '''
  37. return self.__content
  38. @content.setter
  39. def content(self, target: str) -> None:
  40. ''' This function set new content, like innerHTML. '''
  41. self.__content = target
  42. def set_attribute(
  43. self,
  44. name: str,
  45. content: str | int | float | bool | None
  46. ) -> None:
  47. '''
  48. This function set value for tag attribute.
  49. Parameters:
  50. name (str): Name of the attribute
  51. content (str | int | float | bool | None): Content of the attribute
  52. '''
  53. name = name.strip()
  54. for letter in name:
  55. if letter.isspace():
  56. raise Exception("Tag attribute can not contain white char.")
  57. self.__attributes[name] = content
  58. def drop_attribute(self, name: str) -> str | int | float | bool | None:
  59. '''
  60. This function remove attribute by name, when parameter exists.
  61. Parameters:
  62. name (str): Name of the attribute
  63. Returns:
  64. (str | int | float | bool | None): Content of the droped attribute
  65. '''
  66. if not name in self.__attributes:
  67. return None
  68. copy = self.__attributes[name]
  69. del self.__attributes[name]
  70. return copy
  71. def get_attribute(self, name: str) -> str | int | float | bool | None:
  72. '''
  73. This function return content of the attribute, when exists.
  74. Parameters:
  75. name (str): Name of the attribute
  76. Returns:
  77. (str | int | float | bool | None): Content of the attribute
  78. '''
  79. if not name in self.__attributes:
  80. raise Exception("Attribute " + name + " not exists.")
  81. return self.__attributes[name]
  82. def has_attribute(self, name: str) -> bool:
  83. ''' This function return that attribute exists or not. '''
  84. return name in self.__attributes
  85. @property
  86. def attributes(self) -> list:
  87. ''' This function return copy of the attributes dict. '''
  88. return self.__attributes.copy()
  89. def render(self) -> str:
  90. '''
  91. This function return tag rendered to string.
  92. '''
  93. attributes = str()
  94. for attribute in self.attributes.keys():
  95. content = self.get_attribute(attribute)
  96. if content is None:
  97. attributes = attributes + " " + attribute
  98. continue
  99. content = str(content)
  100. content = content.replace("\"", "\\\"")
  101. attributes = attributes + " " + attribute + "=\""
  102. attributes = attributes + content + "\""
  103. tag = "<" + self.name + attributes + ">\n"
  104. if not self.twice:
  105. return tag
  106. closing_tag = "</" + self.name + ">"
  107. return tag + self.content + "\n" + closing_tag + "\n"
  108. def __str__(self) -> str:
  109. ''' This function return tag rendered to string. '''
  110. return self.render()
  111. class style(tag):
  112. '''
  113. This class is responsible for style.
  114. '''
  115. def __init__(self, content: str | None = None):
  116. '''
  117. This create new style tag, with optional setuped content.
  118. Parameters:
  119. content (str | None): Stylesheet of the style tag
  120. '''
  121. super().__init__("style", True)
  122. if content is not None:
  123. self.content = content
  124. class script(tag):
  125. '''
  126. This class is responsible for script loading.
  127. '''
  128. def __init__(self, src: str | None = None):
  129. '''
  130. This create new script tag.
  131. Parameters:
  132. src (str | None) = None: Source of the script
  133. '''
  134. super().__init__("script", True)
  135. if src is not None:
  136. self.set_attribute("src", src)
  137. @property
  138. def src(self) -> str | None:
  139. ''' Return source of the script, or None when not set. '''
  140. if self.has_attribute("src"):
  141. return self.get_attribute("src")
  142. return None
  143. @src.setter
  144. def src(self, target: str | None) -> None:
  145. ''' This function set soure of the script, or drop it when None. '''
  146. if target is not None:
  147. self.set_attribute("src", target)
  148. return
  149. if self.has_attribute("src"):
  150. self.drop_attribute("src")
  151. return
  152. class link(tag):
  153. '''
  154. This class is responsible for creating link tags.
  155. '''
  156. def __init__(self):
  157. ''' This function initialize link tag. '''
  158. super().__init__("link", False)
  159. @property
  160. def rel(self) -> str | None:
  161. ''' This function return rel of the link, or None when not set. '''
  162. if not self.has_attribute("rel"):
  163. return None
  164. return self.get_attribute("rel")
  165. @property
  166. def href(self) -> str | None:
  167. ''' This function return href of the link, or None, when not set. '''
  168. if not self.has_attribute("href"):
  169. return None
  170. return self.get_attribute("href")
  171. @property
  172. def type(self) -> str | None:
  173. ''' This function return type of the link, or None when not set. '''
  174. if not self.has_attribute("type"):
  175. return None
  176. return self.get_attribute("type")
  177. @rel.setter
  178. def rel(self, target: str | None) -> None:
  179. ''' This function set rel of the link, or drop it when None. '''
  180. if target is not None:
  181. self.set_attribute("rel", target)
  182. return
  183. if self.has_attribute("rel"):
  184. self.drop_attribute("rel")
  185. @href.setter
  186. def href(self, target: str | None) -> None:
  187. ''' This function set href of the link, or drop it when None. '''
  188. if target is not None:
  189. self.set_attribute("href", target)
  190. return
  191. if self.has_attribute("href"):
  192. self.drop_attribute("href")
  193. @type.setter
  194. def type(self, target: str | None) -> None:
  195. ''' This function set type of the link, or drop it when None. '''
  196. if target is not None:
  197. self.set_attribute("type", target)
  198. return
  199. if self.has_attribute("type"):
  200. self.drop_attribute("type")